Displays all available and connected relays in the relay screen

This commit is contained in:
Vitor Pamplona
2025-07-02 14:52:03 -04:00
parent d0e66504e4
commit 67dc396588
4 changed files with 126 additions and 0 deletions
@@ -55,6 +55,8 @@ import com.vitorpamplona.amethyst.ui.note.buttons.CloseButton
import com.vitorpamplona.amethyst.ui.note.buttons.SaveButton
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.connected.ConnectedRelayListViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.connected.renderConnectedItems
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.dm.DMRelayListViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.dm.renderDMItems
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.local.LocalRelayListViewModel
@@ -107,12 +109,16 @@ fun MappedAllRelayListView(
val localViewModel: LocalRelayListViewModel = viewModel()
val localFeedState by localViewModel.relays.collectAsStateWithLifecycle()
val connectedViewModel: ConnectedRelayListViewModel = viewModel()
val connectedRelays by connectedViewModel.relays.collectAsStateWithLifecycle()
LaunchedEffect(Unit) {
dmViewModel.load(accountViewModel.account)
nip65ViewModel.load(accountViewModel.account)
searchViewModel.load(accountViewModel.account)
localViewModel.load(accountViewModel.account)
privateOutboxViewModel.load(accountViewModel.account)
connectedViewModel.load(accountViewModel.account)
}
Scaffold(
@@ -241,6 +247,15 @@ fun MappedAllRelayListView(
)
}
renderLocalItems(localFeedState, localViewModel, accountViewModel, newNav)
item {
SettingsCategory(
stringRes(R.string.connected_section),
stringRes(R.string.connected_section_description),
SettingsCategorySpacingModifier,
)
}
renderConnectedItems(connectedRelays, connectedViewModel, accountViewModel, newNav)
}
}
}
@@ -0,0 +1,71 @@
/**
* Copyright (c) 2025 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.connected
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.vitorpamplona.amethyst.ui.navigation.INav
import com.vitorpamplona.amethyst.ui.navigation.rememberExtendedNav
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoDialog
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
@Composable
fun ConnectedRelayList(
postViewModel: ConnectedRelayListViewModel,
accountViewModel: AccountViewModel,
onClose: () -> Unit,
nav: INav,
) {
val newNav = rememberExtendedNav(nav, onClose)
val feedState by postViewModel.relays.collectAsStateWithLifecycle()
Row(verticalAlignment = Alignment.CenterVertically) {
LazyColumn(
contentPadding = FeedPadding,
) {
renderConnectedItems(feedState, postViewModel, accountViewModel, newNav)
}
}
}
fun LazyListScope.renderConnectedItems(
feedState: List<BasicRelaySetupInfo>,
postViewModel: ConnectedRelayListViewModel,
accountViewModel: AccountViewModel,
nav: INav,
) {
itemsIndexed(feedState, key = { _, item -> "Connected" + item.relay }) { index, item ->
BasicRelaySetupInfoDialog(
item,
onDelete = { },
accountViewModel = accountViewModel,
nav,
)
}
}
@@ -0,0 +1,35 @@
/**
* Copyright (c) 2025 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.connected
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoModel
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
class ConnectedRelayListViewModel : BasicRelaySetupInfoModel() {
override fun getRelayList(): List<NormalizedRelayUrl> =
account.client
.relayStatusFlow()
.value.available
.sorted()
override fun saveRelayList(urlList: List<NormalizedRelayUrl>) {
}
}
+5
View File
@@ -1061,6 +1061,11 @@
<string name="private_outbox_section_explainer">Insert between 13 relays to store events no one else can see, like your Drafts and/or app settings. Ideally, these relays are either local or require authentication before downloading each user\'s content.</string>
<string name="kind_3_section">General Relays</string>
<string name="kind_3_section_description">Amethyst uses these relays to download posts for you.</string>
<string name="connected_section">Connected Relays</string>
<string name="connected_section_description">Current list of relays being used</string>
<string name="kind_3_recommended_section">Recommended Relays</string>
<string name="kind_3_recommended_section_description">Add the following relays to your General Relays list in order to receive posts from the listed users.</string>
<string name="search_section">Search Relays</string>