From 4cde2fe8e67608026360883db0ffda2835e25849 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 9 Feb 2023 14:25:58 -0500 Subject: [PATCH] Refactoring of RelaySetupInfo away from ModelView --- .../amethyst/LocalPreferences.kt | 12 ++---- .../vitorpamplona/amethyst/model/Account.kt | 7 +--- .../amethyst/model/RelaySetupInfo.kt | 13 ++++++ .../amethyst/service/relays/Constants.kt | 40 +++++++++---------- .../amethyst/ui/actions/NewRelayListView.kt | 35 +++++----------- .../ui/actions/NewRelayListViewModel.kt | 36 ++++++----------- 6 files changed, 61 insertions(+), 82 deletions(-) create mode 100644 app/src/main/java/com/vitorpamplona/amethyst/model/RelaySetupInfo.kt diff --git a/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt b/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt index 84194c3ec..f679de2eb 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt @@ -4,16 +4,10 @@ import android.content.Context import com.google.gson.GsonBuilder import com.google.gson.reflect.TypeToken import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.model.Channel -import com.vitorpamplona.amethyst.model.DefaultChannels -import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.toByteArray -import com.vitorpamplona.amethyst.ui.actions.NewRelayListViewModel -import com.vitorpamplona.amethyst.ui.navigation.Route +import com.vitorpamplona.amethyst.model.RelaySetupInfo import java.util.Locale import nostr.postr.Persona -import nostr.postr.events.ContactListEvent -import nostr.postr.events.Event import nostr.postr.toHex class LocalPreferences(context: Context) { @@ -52,8 +46,8 @@ class LocalPreferences(context: Context) { val hiddenUsers = getStringSet("hidden_users", emptySet()) ?: setOf() val localRelays = gson.fromJson( getString("relays", "[]"), - object : TypeToken>() {}.type - ) ?: setOf() + object : TypeToken>() {}.type + ) ?: setOf() val dontTranslateFrom = getStringSet("dontTranslateFrom", null) ?: setOf() val translateTo = getString("translateTo", null) ?: Locale.getDefault().language diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 067d73c41..3d36d081a 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -1,8 +1,6 @@ package com.vitorpamplona.amethyst.model import android.content.res.Resources -import androidx.compose.material.DropdownMenuItem -import androidx.compose.material.Text import androidx.core.os.ConfigurationCompat import androidx.lifecycle.LiveData import com.vitorpamplona.amethyst.service.relays.Constants @@ -16,7 +14,6 @@ import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.service.relays.FeedType import com.vitorpamplona.amethyst.service.relays.Relay import com.vitorpamplona.amethyst.service.relays.RelayPool -import com.vitorpamplona.amethyst.ui.actions.NewRelayListViewModel import java.util.Date import java.util.Locale import java.util.concurrent.atomic.AtomicBoolean @@ -53,7 +50,7 @@ class Account( val loggedIn: Persona, var followingChannels: Set = DefaultChannels, var hiddenUsers: Set = setOf(), - var localRelays: Set = Constants.defaultRelays.toSet(), + var localRelays: Set = Constants.defaultRelays.toSet(), var dontTranslateFrom: Set = getLanguagesSpokenByUser(), var translateTo: String = Locale.getDefault().language ) { @@ -435,7 +432,7 @@ class Account( innerReports).toSet() } - fun saveRelayList(value: List) { + fun saveRelayList(value: List) { localRelays = value.toSet() sendNewRelayList(value.associate { it.url to ContactListEvent.ReadWrite(it.read, it.write) } ) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/RelaySetupInfo.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/RelaySetupInfo.kt new file mode 100644 index 000000000..3374fb08f --- /dev/null +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/RelaySetupInfo.kt @@ -0,0 +1,13 @@ +package com.vitorpamplona.amethyst.model + +import com.vitorpamplona.amethyst.service.relays.FeedType + +data class RelaySetupInfo( + val url: String, + val read: Boolean, + val write: Boolean, + val errorCount: Int = 0, + val downloadCount: Int = 0, + val uploadCount: Int = 0, + val feedTypes: Set +) \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Constants.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Constants.kt index 400af884a..593076ac1 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Constants.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Constants.kt @@ -1,6 +1,6 @@ package com.vitorpamplona.amethyst.service.relays -import com.vitorpamplona.amethyst.ui.actions.NewRelayListViewModel +import com.vitorpamplona.amethyst.model.RelaySetupInfo object Constants { val activeTypes = setOf(FeedType.FOLLOWS, FeedType.PRIVATE_DMS) @@ -14,15 +14,15 @@ object Constants { val defaultRelays = arrayOf( // Free relays - NewRelayListViewModel.Relay("wss://offchain.pub", read = true, write = true, feedTypes = activeTypes), - NewRelayListViewModel.Relay("wss://relay.nostr.bg", read = true, write = true, feedTypes = activeTypes), - NewRelayListViewModel.Relay("wss://relay.snort.social", read = true, write = true, feedTypes = activeTypes), - NewRelayListViewModel.Relay("wss://relay.damus.io", read = true, write = true, feedTypes = activeTypes), - NewRelayListViewModel.Relay("wss://nostr.oxtr.dev", read = true, write = true, feedTypes = activeTypes), - NewRelayListViewModel.Relay("wss://nostr-pub.wellorder.net", read = true, write = true, feedTypes = activeTypes), - NewRelayListViewModel.Relay("wss://nostr.mom", read = true, write = true, feedTypes = activeTypes), - NewRelayListViewModel.Relay("wss://no.str.cr", read = true, write = true, feedTypes = activeTypes), - NewRelayListViewModel.Relay("wss://nos.lol", read = true, write = true, feedTypes = activeTypes), + RelaySetupInfo("wss://nostr.bitcoiner.social", read = true, write = true, feedTypes = activeTypes), + RelaySetupInfo("wss://relay.nostr.bg", read = true, write = true, feedTypes = activeTypes), + RelaySetupInfo("wss://relay.snort.social", read = true, write = true, feedTypes = activeTypes), + RelaySetupInfo("wss://relay.damus.io", read = true, write = true, feedTypes = activeTypes), + RelaySetupInfo("wss://nostr.oxtr.dev", read = true, write = true, feedTypes = activeTypes), + RelaySetupInfo("wss://nostr-pub.wellorder.net", read = true, write = true, feedTypes = activeTypes), + RelaySetupInfo("wss://nostr.mom", read = true, write = true, feedTypes = activeTypes), + RelaySetupInfo("wss://no.str.cr", read = true, write = true, feedTypes = activeTypes), + RelaySetupInfo("wss://nos.lol", read = true, write = true, feedTypes = activeTypes), // Less Reliable //NewRelayListViewModel.Relay("wss://nostr.orangepill.dev", read = true, write = true, feedTypes = activeTypes), @@ -35,14 +35,14 @@ object Constants { //NewRelayListViewModel.Relay("wss://brb.io", read = true, write = true, feedTypes = activeTypes), // Paid relays - NewRelayListViewModel.Relay("wss://relay.nostr.com.au", read = true, write = false, feedTypes = activeTypesGlobalChats), - NewRelayListViewModel.Relay("wss://eden.nostr.land", read = true, write = false, feedTypes = activeTypesGlobalChats), - NewRelayListViewModel.Relay("wss://nostr.milou.lol", read = true, write = false, feedTypes = activeTypesGlobalChats), - NewRelayListViewModel.Relay("wss://puravida.nostr.land", read = true, write = false, feedTypes = activeTypesGlobalChats), - NewRelayListViewModel.Relay("wss://nostr.wine", read = true, write = false, feedTypes = activeTypesGlobalChats), - NewRelayListViewModel.Relay("wss://nostr.inosta.cc", read = true, write = false, feedTypes = activeTypesGlobalChats), - NewRelayListViewModel.Relay("wss://atlas.nostr.land", read = true, write = false, feedTypes = activeTypesGlobalChats), - NewRelayListViewModel.Relay("wss://relay.orangepill.dev", read = true, write = false, feedTypes = activeTypesGlobalChats), - NewRelayListViewModel.Relay("wss://relay.nostrati.com", read = true, write = false, feedTypes = activeTypesGlobalChats), + RelaySetupInfo("wss://relay.nostr.com.au", read = true, write = false, feedTypes = activeTypesGlobalChats), + RelaySetupInfo("wss://eden.nostr.land", read = true, write = false, feedTypes = activeTypesGlobalChats), + RelaySetupInfo("wss://nostr.milou.lol", read = true, write = false, feedTypes = activeTypesGlobalChats), + RelaySetupInfo("wss://puravida.nostr.land", read = true, write = false, feedTypes = activeTypesGlobalChats), + RelaySetupInfo("wss://nostr.wine", read = true, write = false, feedTypes = activeTypesGlobalChats), + RelaySetupInfo("wss://nostr.inosta.cc", read = true, write = false, feedTypes = activeTypesGlobalChats), + RelaySetupInfo("wss://atlas.nostr.land", read = true, write = false, feedTypes = activeTypesGlobalChats), + RelaySetupInfo("wss://relay.orangepill.dev", read = true, write = false, feedTypes = activeTypesGlobalChats), + RelaySetupInfo("wss://relay.nostrati.com", read = true, write = false, feedTypes = activeTypesGlobalChats), ) -} +} \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListView.kt index 0e59dbfff..5dba88ac5 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListView.kt @@ -1,25 +1,19 @@ package com.vitorpamplona.amethyst.ui.actions -import androidx.compose.foundation.border import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.Button import androidx.compose.material.ButtonDefaults -import androidx.compose.material.Checkbox -import androidx.compose.material.Colors import androidx.compose.material.Divider import androidx.compose.material.Icon import androidx.compose.material.IconButton @@ -28,18 +22,12 @@ import androidx.compose.material.OutlinedTextField import androidx.compose.material.Surface import androidx.compose.material.Text import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Cancel -import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Download -import androidx.compose.material.icons.filled.DownloadDone import androidx.compose.material.icons.filled.Groups import androidx.compose.material.icons.filled.Public -import androidx.compose.material.icons.filled.Share import androidx.compose.material.icons.filled.SyncProblem import androidx.compose.material.icons.filled.Upload -import androidx.compose.material.icons.outlined.BarChart -import androidx.compose.material.icons.outlined.Delete import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -48,12 +36,10 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment -import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -62,6 +48,7 @@ import androidx.compose.ui.window.DialogProperties import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Account +import com.vitorpamplona.amethyst.model.RelaySetupInfo import com.vitorpamplona.amethyst.service.relays.FeedType import java.lang.Math.round @@ -206,16 +193,16 @@ fun ServerConfigHeader() { @Composable fun ServerConfig( - item: NewRelayListViewModel.Relay, - onToggleDownload: (NewRelayListViewModel.Relay) -> Unit, - onToggleUpload: (NewRelayListViewModel.Relay) -> Unit, + item: RelaySetupInfo, + onToggleDownload: (RelaySetupInfo) -> Unit, + onToggleUpload: (RelaySetupInfo) -> Unit, - onToggleFollows: (NewRelayListViewModel.Relay) -> Unit, - onTogglePrivateDMs: (NewRelayListViewModel.Relay) -> Unit, - onTogglePublicChats: (NewRelayListViewModel.Relay) -> Unit, - onToggleGlobal: (NewRelayListViewModel.Relay) -> Unit, + onToggleFollows: (RelaySetupInfo) -> Unit, + onTogglePrivateDMs: (RelaySetupInfo) -> Unit, + onTogglePublicChats: (RelaySetupInfo) -> Unit, + onToggleGlobal: (RelaySetupInfo) -> Unit, - onDelete: (NewRelayListViewModel.Relay) -> Unit) { + onDelete: (RelaySetupInfo) -> Unit) { Column(Modifier.fillMaxWidth()) { Row( verticalAlignment = Alignment.CenterVertically, @@ -376,7 +363,7 @@ fun ServerConfig( } @Composable -fun EditableServerConfig(relayToAdd: String, onNewRelay: (NewRelayListViewModel.Relay) -> Unit) { +fun EditableServerConfig(relayToAdd: String, onNewRelay: (RelaySetupInfo) -> Unit) { var url by remember { mutableStateOf(relayToAdd) } var read by remember { mutableStateOf(true) } var write by remember { mutableStateOf(true) } @@ -424,7 +411,7 @@ fun EditableServerConfig(relayToAdd: String, onNewRelay: (NewRelayListViewModel. if (url.isNotBlank() && url != "/") { var addedWSS = if (!url.startsWith("wss://")) "wss://$url" else url if (url.endsWith("/")) addedWSS = addedWSS.dropLast(1) - onNewRelay(NewRelayListViewModel.Relay(addedWSS, read, write, feedTypes = FeedType.values().toSet())) + onNewRelay(RelaySetupInfo(addedWSS, read, write, feedTypes = FeedType.values().toSet())) url = "" write = true read = true diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListViewModel.kt index 251cd045e..23dfe2ed4 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewRelayListViewModel.kt @@ -1,32 +1,20 @@ package com.vitorpamplona.amethyst.ui.actions import android.content.Context -import androidx.compose.ui.platform.LocalContext import androidx.lifecycle.ViewModel import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.service.relays.Constants +import com.vitorpamplona.amethyst.model.RelaySetupInfo import com.vitorpamplona.amethyst.service.relays.FeedType import com.vitorpamplona.amethyst.service.relays.RelayPool import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update -import nostr.postr.events.ContactListEvent class NewRelayListViewModel: ViewModel() { private lateinit var account: Account - data class Relay( - val url: String, - val read: Boolean, - val write: Boolean, - val errorCount: Int = 0, - val downloadCount: Int = 0, - val uploadCount: Int = 0, - val feedTypes: Set - ) - - private val _relays = MutableStateFlow>(emptyList()) + private val _relays = MutableStateFlow>(emptyList()) val relays = _relays.asStateFlow() fun load(account: Account, ctx: Context) { @@ -56,7 +44,7 @@ class NewRelayListViewModel: ViewModel() { val eventDownloadCounter = liveRelay?.eventDownloadCounter ?: 0 val eventUploadCounter = liveRelay?.eventUploadCounter ?: 0 - Relay(it.key, it.value.read, it.value.write, errorCounter, eventDownloadCounter, eventUploadCounter, localInfoFeedTypes) + RelaySetupInfo(it.key, it.value.read, it.value.write, errorCounter, eventDownloadCounter, eventUploadCounter, localInfoFeedTypes) }.sortedBy { it.downloadCount }.reversed() else account.localRelays.map { @@ -66,12 +54,12 @@ class NewRelayListViewModel: ViewModel() { val eventDownloadCounter = liveRelay?.eventDownloadCounter ?: 0 val eventUploadCounter = liveRelay?.eventUploadCounter ?: 0 - Relay(it.url, it.read, it.write, errorCounter, eventDownloadCounter, eventUploadCounter, it.feedTypes) + RelaySetupInfo(it.url, it.read, it.write, errorCounter, eventDownloadCounter, eventUploadCounter, it.feedTypes) }.sortedBy { it.downloadCount }.reversed() } } - fun addRelay(relay: Relay) { + fun addRelay(relay: RelaySetupInfo) { if (relays.value.any { it.url == relay.url }) return _relays.update { @@ -79,46 +67,46 @@ class NewRelayListViewModel: ViewModel() { } } - fun deleteRelay(relay: Relay) { + fun deleteRelay(relay: RelaySetupInfo) { _relays.update { it.minus(relay) } } - fun toggleDownload(relay: Relay) { + fun toggleDownload(relay: RelaySetupInfo) { _relays.update { it.updated(relay, relay.copy(read = !relay.read)) } } - fun toggleUpload(relay: Relay) { + fun toggleUpload(relay: RelaySetupInfo) { _relays.update { it.updated(relay, relay.copy(write = !relay.write)) } } - fun toggleFollows(relay: Relay) { + fun toggleFollows(relay: RelaySetupInfo) { val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.FOLLOWS) _relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) } } - fun toggleMessages(relay: Relay) { + fun toggleMessages(relay: RelaySetupInfo) { val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.PRIVATE_DMS) _relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) } } - fun togglePublicChats(relay: Relay) { + fun togglePublicChats(relay: RelaySetupInfo) { val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.PUBLIC_CHATS) _relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) } } - fun toggleGlobal(relay: Relay) { + fun toggleGlobal(relay: RelaySetupInfo) { val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.GLOBAL) _relays.update { it.updated(relay, relay.copy( feedTypes = newTypes ))