mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-09-21 23:51:24 +02:00
Adds a user list to each connected relay to know where this is coming from
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.stats.RelayStat
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.stats.RelayStats
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
@@ -31,6 +32,7 @@ data class BasicRelaySetupInfo(
|
||||
val relayStat: RelayStat,
|
||||
val paidRelay: Boolean = false,
|
||||
val forcesTor: Boolean = false,
|
||||
val users: List<User> = emptyList(),
|
||||
)
|
||||
|
||||
fun relaySetupInfoBuilder(
|
||||
|
@@ -22,26 +22,37 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.LocalCache.users
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.EmptyNav.nav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.note.RenderRelayIcon
|
||||
import com.vitorpamplona.amethyst.ui.note.UserPicture
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.ephemChat.header.loadRelayInfo
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||
import com.vitorpamplona.amethyst.ui.theme.HalfHorzPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.HalfStartPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.HalfVertPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.Height25Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.LargeRelayIconModifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.ReactionRowHeightChatMaxWidth
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size25dp
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.displayUrl
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@@ -53,6 +64,7 @@ fun BasicRelaySetupInfoClickableRow(
|
||||
onDelete: ((BasicRelaySetupInfo) -> Unit)?,
|
||||
onClick: () -> Unit,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val clipboardManager = LocalClipboardManager.current
|
||||
Column(
|
||||
@@ -90,6 +102,8 @@ fun BasicRelaySetupInfoClickableRow(
|
||||
ReactionRowHeightChatMaxWidth,
|
||||
)
|
||||
|
||||
UsedBy(item, accountViewModel, nav)
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = ReactionRowHeightChatMaxWidth,
|
||||
@@ -106,3 +120,56 @@ fun BasicRelaySetupInfoClickableRow(
|
||||
HorizontalDivider(thickness = DividerThickness)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
fun UsedBy(
|
||||
item: BasicRelaySetupInfo,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
if (item.users.isNotEmpty()) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
item.users.getOrNull(0)?.let {
|
||||
UserPicture(
|
||||
user = it,
|
||||
size = Size25dp,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
item.users.getOrNull(1)?.let {
|
||||
UserPicture(
|
||||
user = it,
|
||||
size = Size25dp,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
item.users.getOrNull(2)?.let {
|
||||
UserPicture(
|
||||
user = it,
|
||||
size = Size25dp,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
item.users.getOrNull(3)?.let {
|
||||
UserPicture(
|
||||
user = it,
|
||||
size = Size25dp,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
if (item.users.size > 4) {
|
||||
Box(contentAlignment = Alignment.Center, modifier = Height25Modifier) {
|
||||
Text(
|
||||
text = stringRes(R.string.and_more, item.users.size - 4),
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -44,5 +44,6 @@ fun BasicRelaySetupInfoDialog(
|
||||
onDelete = onDelete,
|
||||
accountViewModel = accountViewModel,
|
||||
onClick = { nav.nav(Route.RelayInfo(item.relay.url)) },
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
@@ -83,22 +83,24 @@ abstract class BasicRelaySetupInfoModel : ViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
_relays.update {
|
||||
val relayList = getRelayList() ?: emptyList()
|
||||
open fun relayListBuilder(): List<BasicRelaySetupInfo> {
|
||||
val relayList = getRelayList() ?: emptyList()
|
||||
|
||||
relayList
|
||||
.map {
|
||||
relaySetupInfoBuilder(
|
||||
normalized = it,
|
||||
forcesTor =
|
||||
account.torRelayState.flow.value
|
||||
.useTor(it),
|
||||
)
|
||||
}.distinctBy { it.relay }
|
||||
.sortedBy { it.relayStat.receivedBytes }
|
||||
.reversed()
|
||||
}
|
||||
return relayList
|
||||
.map {
|
||||
relaySetupInfoBuilder(
|
||||
normalized = it,
|
||||
forcesTor =
|
||||
account.torRelayState.flow.value
|
||||
.useTor(it),
|
||||
)
|
||||
}.distinctBy { it.relay }
|
||||
.sortedBy { it.relayStat.receivedBytes }
|
||||
.reversed()
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
_relays.update { relayListBuilder() }
|
||||
}
|
||||
|
||||
fun addRelay(relay: BasicRelaySetupInfo) {
|
||||
|
@@ -20,10 +20,34 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.connected
|
||||
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoModel
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.stats.RelayStats
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
|
||||
class ConnectedRelayListViewModel : BasicRelaySetupInfoModel() {
|
||||
override fun relayListBuilder(): List<BasicRelaySetupInfo> {
|
||||
val relayList = getRelayList()
|
||||
|
||||
return relayList
|
||||
.map {
|
||||
BasicRelaySetupInfo(
|
||||
relay = it,
|
||||
relayStat = RelayStats.get(it),
|
||||
forcesTor =
|
||||
account.torRelayState.flow.value
|
||||
.useTor(it),
|
||||
users =
|
||||
account.followsPerRelay.value[it]?.mapNotNull { hex ->
|
||||
LocalCache.checkGetOrCreateUser(hex)
|
||||
} ?: emptyList(),
|
||||
)
|
||||
}.distinctBy { it.relay }
|
||||
.sortedBy { it.relayStat.receivedBytes }
|
||||
.reversed()
|
||||
}
|
||||
|
||||
override fun getRelayList(): List<NormalizedRelayUrl> =
|
||||
account.client
|
||||
.relayStatusFlow()
|
||||
|
@@ -189,6 +189,7 @@ val UserNameMaxRowHeight = Modifier.fillMaxWidth()
|
||||
|
||||
val Height24dpModifier = Modifier.height(24.dp)
|
||||
val Height4dpModifier = Modifier.height(4.dp)
|
||||
val Height25Modifier = Modifier.height(Size25dp)
|
||||
|
||||
val Height24dpFilledModifier = Modifier.fillMaxWidth().height(24.dp)
|
||||
val Height4dpFilledModifier = Modifier.fillMaxWidth().height(4.dp)
|
||||
|
Reference in New Issue
Block a user