Moves relay screens to it's own master package on the UI and reorganizes subpackages
This commit is contained in:
@@ -29,8 +29,8 @@ import com.vitorpamplona.amethyst.launchAndWaitAll
|
|||||||
import com.vitorpamplona.amethyst.service.NostrSingleEventDataSource
|
import com.vitorpamplona.amethyst.service.NostrSingleEventDataSource
|
||||||
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||||
import com.vitorpamplona.amethyst.service.firstFullCharOrEmoji
|
import com.vitorpamplona.amethyst.service.firstFullCharOrEmoji
|
||||||
|
import com.vitorpamplona.amethyst.service.replace
|
||||||
import com.vitorpamplona.amethyst.tryAndWait
|
import com.vitorpamplona.amethyst.tryAndWait
|
||||||
import com.vitorpamplona.amethyst.ui.actions.relays.updated
|
|
||||||
import com.vitorpamplona.amethyst.ui.note.combineWith
|
import com.vitorpamplona.amethyst.ui.note.combineWith
|
||||||
import com.vitorpamplona.amethyst.ui.note.toShortenHex
|
import com.vitorpamplona.amethyst.ui.note.toShortenHex
|
||||||
import com.vitorpamplona.ammolite.relays.BundledUpdate
|
import com.vitorpamplona.ammolite.relays.BundledUpdate
|
||||||
@@ -791,28 +791,28 @@ open class Note(
|
|||||||
// migrates these comments to a new version
|
// migrates these comments to a new version
|
||||||
replies.forEach {
|
replies.forEach {
|
||||||
note.addReply(it)
|
note.addReply(it)
|
||||||
it.replyTo = it.replyTo?.updated(this, note)
|
it.replyTo = it.replyTo?.replace(this, note)
|
||||||
}
|
}
|
||||||
reactions.forEach {
|
reactions.forEach {
|
||||||
it.value.forEach {
|
it.value.forEach {
|
||||||
note.addReaction(it)
|
note.addReaction(it)
|
||||||
it.replyTo = it.replyTo?.updated(this, note)
|
it.replyTo = it.replyTo?.replace(this, note)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
boosts.forEach {
|
boosts.forEach {
|
||||||
note.addBoost(it)
|
note.addBoost(it)
|
||||||
it.replyTo = it.replyTo?.updated(this, note)
|
it.replyTo = it.replyTo?.replace(this, note)
|
||||||
}
|
}
|
||||||
reports.forEach {
|
reports.forEach {
|
||||||
it.value.forEach {
|
it.value.forEach {
|
||||||
note.addReport(it)
|
note.addReport(it)
|
||||||
it.replyTo = it.replyTo?.updated(this, note)
|
it.replyTo = it.replyTo?.replace(this, note)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zaps.forEach {
|
zaps.forEach {
|
||||||
note.addZap(it.key, it.value)
|
note.addZap(it.key, it.value)
|
||||||
it.key.replyTo = it.key.replyTo?.updated(this, note)
|
it.key.replyTo = it.key.replyTo?.replace(this, note)
|
||||||
it.value?.replyTo = it.value?.replyTo?.updated(this, note)
|
it.value?.replyTo = it.value?.replyTo?.replace(this, note)
|
||||||
}
|
}
|
||||||
|
|
||||||
replyTo = null
|
replyTo = null
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 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.service
|
||||||
|
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
fun countToHumanReadableBytes(counter: Int) =
|
||||||
|
when {
|
||||||
|
counter >= 1000000000 -> "${(counter / 1000000000f).roundToInt()} GB"
|
||||||
|
counter >= 1000000 -> "${(counter / 1000000f).roundToInt()} MB"
|
||||||
|
counter >= 1000 -> "${(counter / 1000f).roundToInt()} KB"
|
||||||
|
else -> "$counter"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun countToHumanReadableBytes(counter: Long) =
|
||||||
|
when {
|
||||||
|
counter >= 1000000000 -> "${(counter / 1000000000f).roundToInt()} GB"
|
||||||
|
counter >= 1000000 -> "${(counter / 1000000f).roundToInt()} MB"
|
||||||
|
counter >= 1000 -> "${(counter / 1000f).roundToInt()} KB"
|
||||||
|
else -> "$counter"
|
||||||
|
}
|
||||||
+8
-22
@@ -18,31 +18,17 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.service
|
||||||
|
|
||||||
fun countToHumanReadableBytes(counter: Int) =
|
import kotlin.math.roundToInt
|
||||||
when {
|
|
||||||
counter >= 1000000000 -> "${Math.round(counter / 1000000000f)} GB"
|
|
||||||
counter >= 1000000 -> "${Math.round(counter / 1000000f)} MB"
|
|
||||||
counter >= 1000 -> "${Math.round(counter / 1000f)} KB"
|
|
||||||
else -> "$counter"
|
|
||||||
}
|
|
||||||
|
|
||||||
fun countToHumanReadableBytes(counter: Long) =
|
|
||||||
when {
|
|
||||||
counter >= 1000000000 -> "${Math.round(counter / 1000000000f)} GB"
|
|
||||||
counter >= 1000000 -> "${Math.round(counter / 1000000f)} MB"
|
|
||||||
counter >= 1000 -> "${Math.round(counter / 1000f)} KB"
|
|
||||||
else -> "$counter"
|
|
||||||
}
|
|
||||||
|
|
||||||
fun countToHumanReadable(
|
fun countToHumanReadable(
|
||||||
counter: Int,
|
counter: Int,
|
||||||
str: String,
|
str: String,
|
||||||
) = when {
|
) = when {
|
||||||
counter >= 1000000000 -> "${Math.round(counter / 1000000000f)}G $str"
|
counter >= 1000000000 -> "${(counter / 1000000000f).roundToInt()}G $str"
|
||||||
counter >= 1000000 -> "${Math.round(counter / 1000000f)}M $str"
|
counter >= 1000000 -> "${(counter / 1000000f).roundToInt()}M $str"
|
||||||
counter >= 1000 -> "${Math.round(counter / 1000f)}K $str"
|
counter >= 1000 -> "${(counter / 1000f).roundToInt()}K $str"
|
||||||
else -> "$counter $str"
|
else -> "$counter $str"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,8 +36,8 @@ fun countToHumanReadable(
|
|||||||
counter: Long,
|
counter: Long,
|
||||||
str: String,
|
str: String,
|
||||||
) = when {
|
) = when {
|
||||||
counter >= 1000000000 -> "${Math.round(counter / 1000000000f)}G $str"
|
counter >= 1000000000 -> "${(counter / 1000000000f).roundToInt()}G $str"
|
||||||
counter >= 1000000 -> "${Math.round(counter / 1000000f)}M $str"
|
counter >= 1000000 -> "${(counter / 1000000f).roundToInt()}M $str"
|
||||||
counter >= 1000 -> "${Math.round(counter / 1000f)}K $str"
|
counter >= 1000 -> "${(counter / 1000f).roundToInt()}K $str"
|
||||||
else -> "$counter $str"
|
else -> "$counter $str"
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 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.service
|
||||||
|
|
||||||
|
fun <T> Iterable<T>.replace(
|
||||||
|
old: T,
|
||||||
|
new: T,
|
||||||
|
): List<T> = map { if (it == old) new else it }
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 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.service
|
||||||
|
|
||||||
|
fun <T> Set<T>.togglePresenceInSet(item: T): Set<T> = if (contains(item)) minus(item) else plus(item)
|
||||||
+1
-1
@@ -47,11 +47,11 @@ import androidx.compose.ui.window.Dialog
|
|||||||
import androidx.compose.ui.window.DialogProperties
|
import androidx.compose.ui.window.DialogProperties
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.service.Nip11Retriever
|
import com.vitorpamplona.amethyst.service.Nip11Retriever
|
||||||
import com.vitorpamplona.amethyst.ui.actions.relays.RelayInformationDialog
|
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.RelayInformationDialog
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||||
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
||||||
|
|||||||
+2
-2
@@ -56,13 +56,13 @@ import androidx.compose.ui.window.DialogProperties
|
|||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.ui.actions.relays.SettingsCategory
|
|
||||||
import com.vitorpamplona.amethyst.ui.actions.relays.SettingsCategoryWithButton
|
|
||||||
import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge
|
import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategory
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategoryWithButton
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DoubleVertPadding
|
import com.vitorpamplona.amethyst.ui.theme.DoubleVertPadding
|
||||||
|
|||||||
+3
-3
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.ui.dal
|
|||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.ui.actions.relays.updated
|
import com.vitorpamplona.amethyst.service.replace
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEventIds
|
import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEventIds
|
||||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
||||||
@@ -90,7 +90,7 @@ class ChatroomListKnownFeedFilter(
|
|||||||
if (newNotePair.key == oldNote.channelHex()) {
|
if (newNotePair.key == oldNote.channelHex()) {
|
||||||
hasUpdated = true
|
hasUpdated = true
|
||||||
if ((newNotePair.value.createdAt() ?: 0) > (oldNote.createdAt() ?: 0)) {
|
if ((newNotePair.value.createdAt() ?: 0) > (oldNote.createdAt() ?: 0)) {
|
||||||
myNewList = myNewList.updated(oldNote, newNotePair.value)
|
myNewList = myNewList.replace(oldNote, newNotePair.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ class ChatroomListKnownFeedFilter(
|
|||||||
if (newNotePair.key == oldRoom) {
|
if (newNotePair.key == oldRoom) {
|
||||||
hasUpdated = true
|
hasUpdated = true
|
||||||
if ((newNotePair.value.createdAt() ?: 0) > (oldNote.createdAt() ?: 0)) {
|
if ((newNotePair.value.createdAt() ?: 0) > (oldNote.createdAt() ?: 0)) {
|
||||||
myNewList = myNewList.updated(oldNote, newNotePair.value)
|
myNewList = myNewList.replace(oldNote, newNotePair.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.ui.dal
|
|||||||
|
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.ui.actions.relays.updated
|
import com.vitorpamplona.amethyst.service.replace
|
||||||
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent
|
||||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
||||||
@@ -77,7 +77,7 @@ class ChatroomListNewFeedFilter(
|
|||||||
if (newNotePair.key == oldRoom) {
|
if (newNotePair.key == oldRoom) {
|
||||||
hasUpdated = true
|
hasUpdated = true
|
||||||
if ((newNotePair.value.createdAt() ?: 0) > (oldNote.createdAt() ?: 0)) {
|
if ((newNotePair.value.createdAt() ?: 0) > (oldNote.createdAt() ?: 0)) {
|
||||||
myNewList = myNewList.updated(oldNote, newNotePair.value)
|
myNewList = myNewList.replace(oldNote, newNotePair.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ import androidx.navigation.compose.NavHost
|
|||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.ui.actions.NewUserMetadataScreen
|
import com.vitorpamplona.amethyst.ui.actions.NewUserMetadataScreen
|
||||||
import com.vitorpamplona.amethyst.ui.actions.relays.AllRelayListScreen
|
|
||||||
import com.vitorpamplona.amethyst.ui.components.DisplayNotifyMessages
|
import com.vitorpamplona.amethyst.ui.components.DisplayNotifyMessages
|
||||||
import com.vitorpamplona.amethyst.ui.components.getActivity
|
import com.vitorpamplona.amethyst.ui.components.getActivity
|
||||||
import com.vitorpamplona.amethyst.ui.components.toasts.DisplayErrorMessages
|
import com.vitorpamplona.amethyst.ui.components.toasts.DisplayErrorMessages
|
||||||
@@ -72,6 +71,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.hashtag.HashtagScreen
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.HomeScreen
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.HomeScreen
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.NotificationScreen
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.NotificationScreen
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.ProfileScreen
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.ProfileScreen
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.AllRelayListScreen
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.search.SearchScreen
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.search.SearchScreen
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.NIP47SetupScreen
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.NIP47SetupScreen
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SecurityFiltersScreen
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SecurityFiltersScreen
|
||||||
|
|||||||
@@ -54,11 +54,11 @@ import com.vitorpamplona.amethyst.model.FeatureSetType
|
|||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
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.ui.actions.relays.RelayInformationDialog
|
|
||||||
import com.vitorpamplona.amethyst.ui.components.ClickableBox
|
import com.vitorpamplona.amethyst.ui.components.ClickableBox
|
||||||
import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage
|
import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.RelayInformationDialog
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.RelayIconFilter
|
import com.vitorpamplona.amethyst.ui.theme.RelayIconFilter
|
||||||
import com.vitorpamplona.amethyst.ui.theme.Size15Modifier
|
import com.vitorpamplona.amethyst.ui.theme.Size15Modifier
|
||||||
|
|||||||
+1
-1
@@ -39,12 +39,12 @@ import androidx.compose.ui.text.font.FontWeight
|
|||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
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.ui.actions.relays.AddDMRelayListDialog
|
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.EmptyNav
|
import com.vitorpamplona.amethyst.ui.navigation.EmptyNav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
|
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.dm.AddDMRelayListDialog
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.BigPadding
|
import com.vitorpamplona.amethyst.ui.theme.BigPadding
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdPadding
|
import com.vitorpamplona.amethyst.ui.theme.StdPadding
|
||||||
|
|||||||
+1
-1
@@ -39,12 +39,12 @@ import androidx.compose.ui.text.font.FontWeight
|
|||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
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.ui.actions.relays.AddSearchRelayListDialog
|
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.EmptyNav
|
import com.vitorpamplona.amethyst.ui.navigation.EmptyNav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
|
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.search.AddSearchRelayListDialog
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.BigPadding
|
import com.vitorpamplona.amethyst.ui.theme.BigPadding
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdPadding
|
import com.vitorpamplona.amethyst.ui.theme.StdPadding
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ import androidx.core.content.ContextCompat
|
|||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.ui.actions.relays.countToHumanReadableBytes
|
import com.vitorpamplona.amethyst.service.countToHumanReadableBytes
|
||||||
import com.vitorpamplona.amethyst.ui.components.ShowMoreButton
|
import com.vitorpamplona.amethyst.ui.components.ShowMoreButton
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.EmptyNav
|
import com.vitorpamplona.amethyst.ui.navigation.EmptyNav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.ui.actions.relays.countToHumanReadableBytes
|
import com.vitorpamplona.amethyst.service.countToHumanReadableBytes
|
||||||
import com.vitorpamplona.amethyst.ui.components.GenericLoadable
|
import com.vitorpamplona.amethyst.ui.components.GenericLoadable
|
||||||
import com.vitorpamplona.amethyst.ui.components.LoadNote
|
import com.vitorpamplona.amethyst.ui.components.LoadNote
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.EmptyNav
|
import com.vitorpamplona.amethyst.ui.navigation.EmptyNav
|
||||||
|
|||||||
+5
-4
@@ -54,9 +54,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.PublicChatChannel
|
import com.vitorpamplona.amethyst.model.PublicChatChannel
|
||||||
import com.vitorpamplona.amethyst.ui.actions.relays.BasicRelaySetupInfoDialog
|
|
||||||
import com.vitorpamplona.amethyst.ui.actions.relays.RelayUrlEditField
|
|
||||||
import com.vitorpamplona.amethyst.ui.actions.relays.SettingsCategory
|
|
||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectSingleFromGallery
|
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectSingleFromGallery
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.EmptyNav
|
import com.vitorpamplona.amethyst.ui.navigation.EmptyNav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
@@ -67,6 +64,10 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CreateButton
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CreateButton
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategory
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoDialog
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayUrlEditField
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.MinHorzSpacer
|
import com.vitorpamplona.amethyst.ui.theme.MinHorzSpacer
|
||||||
@@ -236,7 +237,7 @@ private fun ChannelMetadataScaffold(
|
|||||||
}
|
}
|
||||||
|
|
||||||
item {
|
item {
|
||||||
RelayUrlEditField { postViewModel.addHomeRelay(it) }
|
RelayUrlEditField { postViewModel.addHomeRelay(relaySetupInfoBuilder(it)) }
|
||||||
|
|
||||||
Spacer(modifier = DoubleVertSpacer)
|
Spacer(modifier = DoubleVertSpacer)
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-9
@@ -37,20 +37,21 @@ import com.vitorpamplona.amethyst.service.uploads.MediaCompressor
|
|||||||
import com.vitorpamplona.amethyst.service.uploads.blossom.BlossomUploader
|
import com.vitorpamplona.amethyst.service.uploads.blossom.BlossomUploader
|
||||||
import com.vitorpamplona.amethyst.service.uploads.nip96.Nip96Uploader
|
import com.vitorpamplona.amethyst.service.uploads.nip96.Nip96Uploader
|
||||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType
|
import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType
|
||||||
import com.vitorpamplona.amethyst.ui.actions.relays.BasicRelaySetupInfo
|
|
||||||
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.ammolite.relays.RelayStats
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||||
import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlin.collections.isNotEmpty
|
||||||
|
import kotlin.collections.map
|
||||||
import kotlin.collections.plus
|
import kotlin.collections.plus
|
||||||
import kotlin.coroutines.cancellation.CancellationException
|
import kotlin.coroutines.cancellation.CancellationException
|
||||||
|
|
||||||
@@ -84,12 +85,8 @@ class ChannelMetadataViewModel : ViewModel() {
|
|||||||
|
|
||||||
val relays =
|
val relays =
|
||||||
channel.info.relays
|
channel.info.relays
|
||||||
?.map {
|
?.map { relaySetupInfoBuilder(it) }
|
||||||
BasicRelaySetupInfo(
|
?.distinctBy { it.url }
|
||||||
RelayUrlFormatter.normalize(it),
|
|
||||||
RelayStats.get(it),
|
|
||||||
)
|
|
||||||
}?.distinctBy { it.url }
|
|
||||||
|
|
||||||
_channelRelays.update { relays ?: emptyList() }
|
_channelRelays.update { relays ?: emptyList() }
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-4
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -54,6 +54,21 @@ import com.vitorpamplona.amethyst.ui.navigation.INav
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||||
|
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.kind3.Kind3RelayListViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.kind3.renderKind3Items
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.kind3.renderKind3ProposalItems
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.local.LocalRelayListViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.local.renderLocalItems
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.nip37.PrivateOutboxRelayListViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.nip37.renderPrivateOutboxItems
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.nip65.Nip65RelayListViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.nip65.renderNip65HomeItems
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.nip65.renderNip65NotifItems
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.search.SearchRelayListViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.search.renderSearchItems
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||||
import com.vitorpamplona.amethyst.ui.theme.MinHorzSpacer
|
import com.vitorpamplona.amethyst.ui.theme.MinHorzSpacer
|
||||||
@@ -61,7 +76,6 @@ import com.vitorpamplona.amethyst.ui.theme.RowColSpacing
|
|||||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.grayText
|
import com.vitorpamplona.amethyst.ui.theme.grayText
|
||||||
import com.vitorpamplona.ammolite.relays.Constants
|
import com.vitorpamplona.ammolite.relays.Constants
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AllRelayListScreen(
|
fun AllRelayListScreen(
|
||||||
@@ -275,7 +289,11 @@ fun ResetSearchRelays(postViewModel: SearchRelayListViewModel) {
|
|||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
postViewModel.deleteAll()
|
postViewModel.deleteAll()
|
||||||
DefaultSearchRelayList.forEach { postViewModel.addRelay(BasicRelaySetupInfo(it, RelayStat())) }
|
DefaultSearchRelayList.forEach {
|
||||||
|
postViewModel.addRelay(
|
||||||
|
relaySetupInfoBuilder(it),
|
||||||
|
)
|
||||||
|
}
|
||||||
postViewModel.loadRelayDocuments()
|
postViewModel.loadRelayDocuments()
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
@@ -288,7 +306,9 @@ fun ResetDMRelays(postViewModel: DMRelayListViewModel) {
|
|||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
postViewModel.deleteAll()
|
postViewModel.deleteAll()
|
||||||
DefaultDMRelayList.forEach { postViewModel.addRelay(BasicRelaySetupInfo(it, RelayStat())) }
|
DefaultDMRelayList.forEach {
|
||||||
|
postViewModel.addRelay(relaySetupInfoBuilder(it))
|
||||||
|
}
|
||||||
postViewModel.loadRelayDocuments()
|
postViewModel.loadRelayDocuments()
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
+1
-1
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 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.common
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
||||||
|
import com.vitorpamplona.ammolite.relays.RelayStats
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
||||||
|
import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class BasicRelaySetupInfo(
|
||||||
|
val url: String,
|
||||||
|
val relayStat: RelayStat,
|
||||||
|
val paidRelay: Boolean = false,
|
||||||
|
) {
|
||||||
|
val briefInfo: RelayBriefInfoCache.RelayBriefInfo = RelayBriefInfoCache.RelayBriefInfo(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun relaySetupInfoBuilder(url: String): BasicRelaySetupInfo {
|
||||||
|
val normalized = RelayUrlFormatter.normalize(url)
|
||||||
|
return BasicRelaySetupInfo(
|
||||||
|
normalized,
|
||||||
|
RelayStats.get(normalized),
|
||||||
|
)
|
||||||
|
}
|
||||||
+1
-1
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common
|
||||||
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
+2
-1
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
@@ -32,6 +32,7 @@ import com.vitorpamplona.amethyst.service.Nip11Retriever
|
|||||||
import com.vitorpamplona.amethyst.ui.actions.RelayInfoDialog
|
import com.vitorpamplona.amethyst.ui.actions.RelayInfoDialog
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.RelayInformationDialog
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
||||||
|
|
||||||
+5
-10
@@ -18,14 +18,13 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.service.Nip11CachedRetriever
|
import com.vitorpamplona.amethyst.service.Nip11CachedRetriever
|
||||||
import com.vitorpamplona.ammolite.relays.RelayStats
|
import com.vitorpamplona.amethyst.service.replace
|
||||||
import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
@@ -80,12 +79,8 @@ abstract class BasicRelaySetupInfoModel : ViewModel() {
|
|||||||
val relayList = getRelayList() ?: emptyList()
|
val relayList = getRelayList() ?: emptyList()
|
||||||
|
|
||||||
relayList
|
relayList
|
||||||
.map { relayUrl ->
|
.map { relaySetupInfoBuilder(it) }
|
||||||
BasicRelaySetupInfo(
|
.distinctBy { it.url }
|
||||||
RelayUrlFormatter.normalize(relayUrl),
|
|
||||||
RelayStats.get(relayUrl),
|
|
||||||
)
|
|
||||||
}.distinctBy { it.url }
|
|
||||||
.sortedBy { it.relayStat.receivedBytes }
|
.sortedBy { it.relayStat.receivedBytes }
|
||||||
.reversed()
|
.reversed()
|
||||||
}
|
}
|
||||||
@@ -112,6 +107,6 @@ abstract class BasicRelaySetupInfoModel : ViewModel() {
|
|||||||
relay: BasicRelaySetupInfo,
|
relay: BasicRelaySetupInfo,
|
||||||
paid: Boolean,
|
paid: Boolean,
|
||||||
) {
|
) {
|
||||||
_relays.update { it.updated(relay, relay.copy(paidRelay = paid)) }
|
_relays.update { it.replace(relay, relay.copy(paidRelay = paid)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common
|
||||||
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
+3
-1
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.gestures.detectTapGestures
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
@@ -39,6 +39,8 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
import androidx.compose.ui.unit.dp
|
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.service.countToHumanReadable
|
||||||
|
import com.vitorpamplona.amethyst.service.countToHumanReadableBytes
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.allGoodColor
|
import com.vitorpamplona.amethyst.ui.theme.allGoodColor
|
||||||
+4
-6
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
@@ -47,8 +47,6 @@ import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
|||||||
import com.vitorpamplona.amethyst.ui.theme.Size10dp
|
import com.vitorpamplona.amethyst.ui.theme.Size10dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
|
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
|
||||||
import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter
|
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
@@ -59,7 +57,7 @@ fun RelayUrlEditFieldPreview() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RelayUrlEditField(onNewRelay: (BasicRelaySetupInfo) -> Unit) {
|
fun RelayUrlEditField(onNewRelay: (String) -> Unit) {
|
||||||
var url by remember { mutableStateOf("") }
|
var url by remember { mutableStateOf("") }
|
||||||
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(Size10dp)) {
|
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(Size10dp)) {
|
||||||
@@ -87,7 +85,7 @@ fun RelayUrlEditField(onNewRelay: (BasicRelaySetupInfo) -> Unit) {
|
|||||||
KeyboardActions(
|
KeyboardActions(
|
||||||
onGo = {
|
onGo = {
|
||||||
if (url.isNotBlank() && url != "/") {
|
if (url.isNotBlank() && url != "/") {
|
||||||
onNewRelay(BasicRelaySetupInfo(RelayUrlFormatter.normalize(url), RelayStat()))
|
onNewRelay(url)
|
||||||
url = ""
|
url = ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -97,7 +95,7 @@ fun RelayUrlEditField(onNewRelay: (BasicRelaySetupInfo) -> Unit) {
|
|||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
if (url.isNotBlank() && url != "/") {
|
if (url.isNotBlank() && url != "/") {
|
||||||
onNewRelay(BasicRelaySetupInfo(RelayUrlFormatter.normalize(url), RelayStat()))
|
onNewRelay(url)
|
||||||
url = ""
|
url = ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
+5
-3
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.dm
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -49,11 +49,11 @@ import com.vitorpamplona.amethyst.ui.navigation.INav
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.imageModifier
|
import com.vitorpamplona.amethyst.ui.theme.imageModifier
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@@ -153,7 +153,9 @@ fun ResetDMRelaysLonger(postViewModel: DMRelayListViewModel) {
|
|||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
postViewModel.deleteAll()
|
postViewModel.deleteAll()
|
||||||
DefaultDMRelayList.forEach { postViewModel.addRelay(BasicRelaySetupInfo(it, RelayStat())) }
|
DefaultDMRelayList.forEach {
|
||||||
|
postViewModel.addRelay(relaySetupInfoBuilder(it))
|
||||||
|
}
|
||||||
postViewModel.loadRelayDocuments()
|
postViewModel.loadRelayDocuments()
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
+6
-2
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.dm
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@@ -32,6 +32,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.rememberExtendedNav
|
import com.vitorpamplona.amethyst.ui.navigation.rememberExtendedNav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
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.screen.loggedIn.relays.common.RelayUrlEditField
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||||
|
|
||||||
@@ -71,6 +75,6 @@ fun LazyListScope.renderDMItems(
|
|||||||
|
|
||||||
item {
|
item {
|
||||||
Spacer(modifier = StdVertSpacer)
|
Spacer(modifier = StdVertSpacer)
|
||||||
RelayUrlEditField { postViewModel.addRelay(it) }
|
RelayUrlEditField { postViewModel.addRelay(relaySetupInfoBuilder(it)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-1
@@ -18,7 +18,9 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.dm
|
||||||
|
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoModel
|
||||||
|
|
||||||
class DMRelayListViewModel : BasicRelaySetupInfoModel() {
|
class DMRelayListViewModel : BasicRelaySetupInfoModel() {
|
||||||
override fun getRelayList(): List<String>? = account.getDMRelayList()?.relays()
|
override fun getRelayList(): List<String>? = account.getDMRelayList()?.relays()
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 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.kind3
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import com.vitorpamplona.ammolite.relays.FeedType
|
||||||
|
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
||||||
|
|
||||||
|
@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)
|
||||||
|
}
|
||||||
+11
-5
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.kind3
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
@@ -70,11 +70,16 @@ import com.vitorpamplona.amethyst.R
|
|||||||
import com.vitorpamplona.amethyst.model.FeatureSetType
|
import com.vitorpamplona.amethyst.model.FeatureSetType
|
||||||
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.countToHumanReadable
|
||||||
|
import com.vitorpamplona.amethyst.service.countToHumanReadableBytes
|
||||||
import com.vitorpamplona.amethyst.ui.actions.RelayInfoDialog
|
import com.vitorpamplona.amethyst.ui.actions.RelayInfoDialog
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.rememberExtendedNav
|
import com.vitorpamplona.amethyst.ui.navigation.rememberExtendedNav
|
||||||
import com.vitorpamplona.amethyst.ui.note.RenderRelayIcon
|
import com.vitorpamplona.amethyst.ui.note.RenderRelayIcon
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.RelayInformationDialog
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.recommendations.Kind3RelayProposalSetupInfo
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.recommendations.Kind3RelaySetupInfoProposalDialog
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||||
@@ -90,10 +95,10 @@ import com.vitorpamplona.amethyst.ui.theme.allGoodColor
|
|||||||
import com.vitorpamplona.amethyst.ui.theme.largeRelayIconModifier
|
import com.vitorpamplona.amethyst.ui.theme.largeRelayIconModifier
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
import com.vitorpamplona.amethyst.ui.theme.warningColor
|
import com.vitorpamplona.amethyst.ui.theme.warningColor
|
||||||
import com.vitorpamplona.ammolite.relays.Constants
|
|
||||||
import com.vitorpamplona.ammolite.relays.Constants.activeTypesGlobalChats
|
import com.vitorpamplona.ammolite.relays.Constants.activeTypesGlobalChats
|
||||||
import com.vitorpamplona.ammolite.relays.FeedType
|
import com.vitorpamplona.ammolite.relays.FeedType
|
||||||
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
||||||
|
import com.vitorpamplona.ammolite.relays.RelayStats
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
||||||
import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter
|
import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -184,7 +189,7 @@ fun ServerConfigPreview() {
|
|||||||
sentBytes = 10000000,
|
sentBytes = 10000000,
|
||||||
spamCounter = 10,
|
spamCounter = 10,
|
||||||
),
|
),
|
||||||
feedTypes = Constants.activeTypesGlobalChats,
|
feedTypes = activeTypesGlobalChats,
|
||||||
paidRelay = true,
|
paidRelay = true,
|
||||||
),
|
),
|
||||||
onDelete = {},
|
onDelete = {},
|
||||||
@@ -790,13 +795,14 @@ fun Kind3RelayEditBox(
|
|||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
if (url.isNotBlank() && url != "/") {
|
if (url.isNotBlank() && url != "/") {
|
||||||
|
val normalized = RelayUrlFormatter.normalize(url)
|
||||||
onNewRelay(
|
onNewRelay(
|
||||||
Kind3BasicRelaySetupInfo(
|
Kind3BasicRelaySetupInfo(
|
||||||
url = RelayUrlFormatter.normalize(url),
|
url = normalized,
|
||||||
read = read,
|
read = read,
|
||||||
write = write,
|
write = write,
|
||||||
feedTypes = activeTypesGlobalChats,
|
feedTypes = activeTypesGlobalChats,
|
||||||
relayStat = RelayStat(),
|
relayStat = RelayStats.get(normalized),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
url = ""
|
url = ""
|
||||||
+30
-25
@@ -18,13 +18,16 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.kind3
|
||||||
|
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.service.Nip11CachedRetriever
|
import com.vitorpamplona.amethyst.service.Nip11CachedRetriever
|
||||||
|
import com.vitorpamplona.amethyst.service.replace
|
||||||
|
import com.vitorpamplona.amethyst.service.togglePresenceInSet
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.recommendations.Kind3RelayProposalSetupInfo
|
||||||
import com.vitorpamplona.ammolite.relays.Constants
|
import com.vitorpamplona.ammolite.relays.Constants
|
||||||
import com.vitorpamplona.ammolite.relays.Constants.activeTypesGlobalChats
|
import com.vitorpamplona.ammolite.relays.Constants.activeTypesGlobalChats
|
||||||
import com.vitorpamplona.ammolite.relays.FeedType
|
import com.vitorpamplona.ammolite.relays.FeedType
|
||||||
@@ -38,6 +41,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlin.collections.plus
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
class Kind3RelayListViewModel : ViewModel() {
|
class Kind3RelayListViewModel : ViewModel() {
|
||||||
@@ -206,7 +210,18 @@ class Kind3RelayListViewModel : ViewModel() {
|
|||||||
fun addRelay(relay: Kind3RelayProposalSetupInfo) {
|
fun addRelay(relay: Kind3RelayProposalSetupInfo) {
|
||||||
if (relays.value.any { it.url == relay.url }) return
|
if (relays.value.any { it.url == relay.url }) return
|
||||||
|
|
||||||
_relays.update { it.plus(Kind3BasicRelaySetupInfo(relay.url, relay.read, relay.write, relay.feedTypes, relay.relayStat, relay.paidRelay)) }
|
_relays.update {
|
||||||
|
it.plus(
|
||||||
|
Kind3BasicRelaySetupInfo(
|
||||||
|
relay.url,
|
||||||
|
relay.read,
|
||||||
|
relay.write,
|
||||||
|
relay.feedTypes,
|
||||||
|
relay.relayStat,
|
||||||
|
relay.paidRelay,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
refreshProposals()
|
refreshProposals()
|
||||||
|
|
||||||
@@ -230,42 +245,42 @@ class Kind3RelayListViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun toggleDownload(relay: Kind3BasicRelaySetupInfo) {
|
fun toggleDownload(relay: Kind3BasicRelaySetupInfo) {
|
||||||
_relays.update { it.updated(relay, relay.copy(read = !relay.read)) }
|
_relays.update { it.replace(relay, relay.copy(read = !relay.read)) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleUpload(relay: Kind3BasicRelaySetupInfo) {
|
fun toggleUpload(relay: Kind3BasicRelaySetupInfo) {
|
||||||
_relays.update { it.updated(relay, relay.copy(write = !relay.write)) }
|
_relays.update { it.replace(relay, relay.copy(write = !relay.write)) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleFollows(relay: Kind3BasicRelaySetupInfo) {
|
fun toggleFollows(relay: Kind3BasicRelaySetupInfo) {
|
||||||
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.FOLLOWS)
|
val newTypes = relay.feedTypes.togglePresenceInSet(FeedType.FOLLOWS)
|
||||||
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
_relays.update { it.replace(relay, relay.copy(feedTypes = newTypes)) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleMessages(relay: Kind3BasicRelaySetupInfo) {
|
fun toggleMessages(relay: Kind3BasicRelaySetupInfo) {
|
||||||
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.PRIVATE_DMS)
|
val newTypes = relay.feedTypes.togglePresenceInSet(FeedType.PRIVATE_DMS)
|
||||||
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
_relays.update { it.replace(relay, relay.copy(feedTypes = newTypes)) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun togglePublicChats(relay: Kind3BasicRelaySetupInfo) {
|
fun togglePublicChats(relay: Kind3BasicRelaySetupInfo) {
|
||||||
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.PUBLIC_CHATS)
|
val newTypes = relay.feedTypes.togglePresenceInSet(FeedType.PUBLIC_CHATS)
|
||||||
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
_relays.update { it.replace(relay, relay.copy(feedTypes = newTypes)) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleGlobal(relay: Kind3BasicRelaySetupInfo) {
|
fun toggleGlobal(relay: Kind3BasicRelaySetupInfo) {
|
||||||
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.GLOBAL)
|
val newTypes = relay.feedTypes.togglePresenceInSet(FeedType.GLOBAL)
|
||||||
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
_relays.update { it.replace(relay, relay.copy(feedTypes = newTypes)) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleSearch(relay: Kind3BasicRelaySetupInfo) {
|
fun toggleSearch(relay: Kind3BasicRelaySetupInfo) {
|
||||||
val newTypes = togglePresenceInSet(relay.feedTypes, FeedType.SEARCH)
|
val newTypes = relay.feedTypes.togglePresenceInSet(FeedType.SEARCH)
|
||||||
_relays.update { it.updated(relay, relay.copy(feedTypes = newTypes)) }
|
_relays.update { it.replace(relay, relay.copy(feedTypes = newTypes)) }
|
||||||
hasModified = true
|
hasModified = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,16 +288,6 @@ class Kind3RelayListViewModel : ViewModel() {
|
|||||||
relay: Kind3BasicRelaySetupInfo,
|
relay: Kind3BasicRelaySetupInfo,
|
||||||
paid: Boolean,
|
paid: Boolean,
|
||||||
) {
|
) {
|
||||||
_relays.update { it.updated(relay, relay.copy(paidRelay = paid)) }
|
_relays.update { it.replace(relay, relay.copy(paidRelay = paid)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> Iterable<T>.updated(
|
|
||||||
old: T,
|
|
||||||
new: T,
|
|
||||||
): List<T> = map { if (it == old) new else it }
|
|
||||||
|
|
||||||
fun <T> togglePresenceInSet(
|
|
||||||
set: Set<T>,
|
|
||||||
item: T,
|
|
||||||
): Set<T> = if (set.contains(item)) set.minus(item) else set.plus(item)
|
|
||||||
+6
-2
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.local
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@@ -32,6 +32,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.rememberExtendedNav
|
import com.vitorpamplona.amethyst.ui.navigation.rememberExtendedNav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
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.screen.loggedIn.relays.common.RelayUrlEditField
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||||
|
|
||||||
@@ -71,6 +75,6 @@ fun LazyListScope.renderLocalItems(
|
|||||||
|
|
||||||
item {
|
item {
|
||||||
Spacer(modifier = StdVertSpacer)
|
Spacer(modifier = StdVertSpacer)
|
||||||
RelayUrlEditField { postViewModel.addRelay(it) }
|
RelayUrlEditField { postViewModel.addRelay(relaySetupInfoBuilder(it)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-1
@@ -18,7 +18,9 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.local
|
||||||
|
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoModel
|
||||||
|
|
||||||
class LocalRelayListViewModel : BasicRelaySetupInfoModel() {
|
class LocalRelayListViewModel : BasicRelaySetupInfoModel() {
|
||||||
override fun getRelayList(): List<String> = account.settings.localRelayServers.toList()
|
override fun getRelayList(): List<String> = account.settings.localRelayServers.toList()
|
||||||
+6
-2
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.nip37
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@@ -32,6 +32,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.rememberExtendedNav
|
import com.vitorpamplona.amethyst.ui.navigation.rememberExtendedNav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
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.screen.loggedIn.relays.common.RelayUrlEditField
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||||
|
|
||||||
@@ -71,6 +75,6 @@ fun LazyListScope.renderPrivateOutboxItems(
|
|||||||
|
|
||||||
item {
|
item {
|
||||||
Spacer(modifier = StdVertSpacer)
|
Spacer(modifier = StdVertSpacer)
|
||||||
RelayUrlEditField { postViewModel.addRelay(it) }
|
RelayUrlEditField { postViewModel.addRelay(relaySetupInfoBuilder(it)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-1
@@ -18,7 +18,9 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.nip37
|
||||||
|
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoModel
|
||||||
|
|
||||||
class PrivateOutboxRelayListViewModel : BasicRelaySetupInfoModel() {
|
class PrivateOutboxRelayListViewModel : BasicRelaySetupInfoModel() {
|
||||||
override fun getRelayList(): List<String>? = account.getPrivateOutboxRelayList()?.relays()
|
override fun getRelayList(): List<String>? = account.getPrivateOutboxRelayList()?.relays()
|
||||||
+7
-3
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.nip65
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@@ -32,6 +32,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.rememberExtendedNav
|
import com.vitorpamplona.amethyst.ui.navigation.rememberExtendedNav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
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.screen.loggedIn.relays.common.RelayUrlEditField
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||||
|
|
||||||
@@ -74,7 +78,7 @@ fun LazyListScope.renderNip65HomeItems(
|
|||||||
|
|
||||||
item {
|
item {
|
||||||
Spacer(modifier = StdVertSpacer)
|
Spacer(modifier = StdVertSpacer)
|
||||||
RelayUrlEditField { postViewModel.addHomeRelay(it) }
|
RelayUrlEditField { postViewModel.addHomeRelay(relaySetupInfoBuilder(it)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +99,6 @@ fun LazyListScope.renderNip65NotifItems(
|
|||||||
|
|
||||||
item {
|
item {
|
||||||
Spacer(modifier = StdVertSpacer)
|
Spacer(modifier = StdVertSpacer)
|
||||||
RelayUrlEditField { postViewModel.addNotifRelay(it) }
|
RelayUrlEditField { postViewModel.addNotifRelay(relaySetupInfoBuilder(it)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+10
-17
@@ -18,16 +18,17 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.nip65
|
||||||
|
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.service.Nip11CachedRetriever
|
import com.vitorpamplona.amethyst.service.Nip11CachedRetriever
|
||||||
import com.vitorpamplona.ammolite.relays.RelayStats
|
import com.vitorpamplona.amethyst.service.replace
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||||
import com.vitorpamplona.quartz.nip65RelayList.RelayUrlFormatter
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
@@ -110,12 +111,8 @@ class Nip65RelayListViewModel : ViewModel() {
|
|||||||
val relayList = account.getNIP65RelayList()?.writeRelays() ?: emptyList()
|
val relayList = account.getNIP65RelayList()?.writeRelays() ?: emptyList()
|
||||||
|
|
||||||
relayList
|
relayList
|
||||||
.map { relayUrl ->
|
.map { relaySetupInfoBuilder(it) }
|
||||||
BasicRelaySetupInfo(
|
.distinctBy { it.url }
|
||||||
RelayUrlFormatter.normalize(relayUrl),
|
|
||||||
RelayStats.get(relayUrl),
|
|
||||||
)
|
|
||||||
}.distinctBy { it.url }
|
|
||||||
.sortedBy { it.relayStat.receivedBytes }
|
.sortedBy { it.relayStat.receivedBytes }
|
||||||
.reversed()
|
.reversed()
|
||||||
}
|
}
|
||||||
@@ -124,12 +121,8 @@ class Nip65RelayListViewModel : ViewModel() {
|
|||||||
val relayList = account.getNIP65RelayList()?.readRelays() ?: emptyList()
|
val relayList = account.getNIP65RelayList()?.readRelays() ?: emptyList()
|
||||||
|
|
||||||
relayList
|
relayList
|
||||||
.map { relayUrl ->
|
.map { relaySetupInfoBuilder(it) }
|
||||||
BasicRelaySetupInfo(
|
.distinctBy { it.url }
|
||||||
RelayUrlFormatter.normalize(relayUrl),
|
|
||||||
RelayStats.get(relayUrl),
|
|
||||||
)
|
|
||||||
}.distinctBy { it.url }
|
|
||||||
.sortedBy { it.relayStat.receivedBytes }
|
.sortedBy { it.relayStat.receivedBytes }
|
||||||
.reversed()
|
.reversed()
|
||||||
}
|
}
|
||||||
@@ -156,7 +149,7 @@ class Nip65RelayListViewModel : ViewModel() {
|
|||||||
relay: BasicRelaySetupInfo,
|
relay: BasicRelaySetupInfo,
|
||||||
paid: Boolean,
|
paid: Boolean,
|
||||||
) {
|
) {
|
||||||
_homeRelays.update { it.updated(relay, relay.copy(paidRelay = paid)) }
|
_homeRelays.update { it.replace(relay, relay.copy(paidRelay = paid)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addNotifRelay(relay: BasicRelaySetupInfo) {
|
fun addNotifRelay(relay: BasicRelaySetupInfo) {
|
||||||
@@ -180,6 +173,6 @@ class Nip65RelayListViewModel : ViewModel() {
|
|||||||
relay: BasicRelaySetupInfo,
|
relay: BasicRelaySetupInfo,
|
||||||
paid: Boolean,
|
paid: Boolean,
|
||||||
) {
|
) {
|
||||||
_notificationRelays.update { it.updated(relay, relay.copy(paidRelay = paid)) }
|
_notificationRelays.update { it.replace(relay, relay.copy(paidRelay = paid)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-22
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.recommendations
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.ammolite.relays.FeedType
|
import com.vitorpamplona.ammolite.relays.FeedType
|
||||||
@@ -26,27 +26,6 @@ import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
|||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
||||||
|
|
||||||
@Immutable
|
|
||||||
data class BasicRelaySetupInfo(
|
|
||||||
val url: String,
|
|
||||||
val relayStat: RelayStat,
|
|
||||||
val paidRelay: Boolean = false,
|
|
||||||
) {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class Kind3RelayProposalSetupInfo(
|
data class Kind3RelayProposalSetupInfo(
|
||||||
val url: String,
|
val url: String,
|
||||||
+2
-1
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.recommendations
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
@@ -32,6 +32,7 @@ import com.vitorpamplona.amethyst.service.Nip11Retriever
|
|||||||
import com.vitorpamplona.amethyst.ui.actions.RelayInfoDialog
|
import com.vitorpamplona.amethyst.ui.actions.RelayInfoDialog
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.RelayInformationDialog
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
||||||
|
|
||||||
+1
-1
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.recommendations
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
+5
-3
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.search
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -49,11 +49,11 @@ import com.vitorpamplona.amethyst.ui.navigation.INav
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.CloseButton
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.SaveButton
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.imageModifier
|
import com.vitorpamplona.amethyst.ui.theme.imageModifier
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.RelayStat
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@@ -153,7 +153,9 @@ fun ResetSearchRelaysLonger(postViewModel: SearchRelayListViewModel) {
|
|||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
postViewModel.deleteAll()
|
postViewModel.deleteAll()
|
||||||
DefaultSearchRelayList.forEach { postViewModel.addRelay(BasicRelaySetupInfo(it, RelayStat())) }
|
DefaultSearchRelayList.forEach {
|
||||||
|
postViewModel.addRelay(relaySetupInfoBuilder(it))
|
||||||
|
}
|
||||||
postViewModel.loadRelayDocuments()
|
postViewModel.loadRelayDocuments()
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
+6
-2
@@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.search
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@@ -32,6 +32,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.rememberExtendedNav
|
import com.vitorpamplona.amethyst.ui.navigation.rememberExtendedNav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
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.screen.loggedIn.relays.common.RelayUrlEditField
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||||
|
|
||||||
@@ -72,6 +76,6 @@ fun LazyListScope.renderSearchItems(
|
|||||||
|
|
||||||
item {
|
item {
|
||||||
Spacer(modifier = StdVertSpacer)
|
Spacer(modifier = StdVertSpacer)
|
||||||
RelayUrlEditField { postViewModel.addRelay(it) }
|
RelayUrlEditField { postViewModel.addRelay(relaySetupInfoBuilder(it)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-1
@@ -18,7 +18,9 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.actions.relays
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.search
|
||||||
|
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoModel
|
||||||
|
|
||||||
class SearchRelayListViewModel : BasicRelaySetupInfoModel() {
|
class SearchRelayListViewModel : BasicRelaySetupInfoModel() {
|
||||||
override fun getRelayList(): List<String>? = account.getSearchRelayList()?.relays()
|
override fun getRelayList(): List<String>? = account.getSearchRelayList()?.relays()
|
||||||
Reference in New Issue
Block a user