Merge pull request #2112 from greenart7c3/claude/add-relay-setting-kxeIb
Add option to forward profile events to local relays
This commit is contained in:
@@ -39,6 +39,7 @@ import com.vitorpamplona.amethyst.commons.richtext.RichTextParser
|
||||
import com.vitorpamplona.amethyst.logTime
|
||||
import com.vitorpamplona.amethyst.model.edits.PrivateStorageRelayListDecryptionCache
|
||||
import com.vitorpamplona.amethyst.model.edits.PrivateStorageRelayListState
|
||||
import com.vitorpamplona.amethyst.model.localRelays.ForwardKind0ToLocalRelayState
|
||||
import com.vitorpamplona.amethyst.model.localRelays.LocalRelayListState
|
||||
import com.vitorpamplona.amethyst.model.nip01UserMetadata.AccountHomeRelayState
|
||||
import com.vitorpamplona.amethyst.model.nip01UserMetadata.AccountOutboxRelayState
|
||||
@@ -267,6 +268,8 @@ class Account(
|
||||
val nip65RelayList = Nip65RelayListState(signer, cache, scope, settings)
|
||||
val localRelayList = LocalRelayListState(signer, cache, scope, settings)
|
||||
|
||||
val forwardKind0ToLocalRelay = ForwardKind0ToLocalRelayState(client, localRelayList, settings)
|
||||
|
||||
val dmRelayList = DmRelayListState(signer, cache, scope, settings)
|
||||
|
||||
val privateStorageDecryptionCache = PrivateStorageRelayListDecryptionCache(signer)
|
||||
@@ -433,6 +436,14 @@ class Account(
|
||||
return false
|
||||
}
|
||||
|
||||
suspend fun updateSendKind0EventsToLocalRelay(send: Boolean): Boolean {
|
||||
if (settings.changeSendKind0EventsToLocalRelay(send)) {
|
||||
sendNewAppSpecificData()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
suspend fun updateFilterSpam(filterSpam: Boolean): Boolean {
|
||||
if (settings.updateFilterSpam(filterSpam)) {
|
||||
if (!settings.syncedSettings.security.filterSpamFromStrangers.value) {
|
||||
|
||||
@@ -424,6 +424,14 @@ class AccountSettings(
|
||||
}
|
||||
}
|
||||
|
||||
fun changeSendKind0EventsToLocalRelay(send: Boolean): Boolean {
|
||||
if (syncedSettings.security.updateSendKind0EventsToLocalRelay(send)) {
|
||||
saveAccountSettings()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun updateUserMetadata(newMetadata: MetadataEvent?) {
|
||||
if (newMetadata == null) return
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ class AccountSyncedSettings(
|
||||
internalSettings.security.warnAboutPostsWithReports,
|
||||
MutableStateFlow(internalSettings.security.filterSpamFromStrangers),
|
||||
MutableStateFlow(internalSettings.security.maxHashtagLimit),
|
||||
MutableStateFlow(internalSettings.security.sendKind0EventsToLocalRelay),
|
||||
)
|
||||
|
||||
fun toInternal(): AccountSyncedSettingsInternal =
|
||||
@@ -76,6 +77,7 @@ class AccountSyncedSettings(
|
||||
security.warnAboutPostsWithReports,
|
||||
security.filterSpamFromStrangers.value,
|
||||
security.maxHashtagLimit.value,
|
||||
security.sendKind0EventsToLocalRelay.value,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -126,6 +128,10 @@ class AccountSyncedSettings(
|
||||
if (security.maxHashtagLimit.value != syncedSettingsInternal.security.maxHashtagLimit) {
|
||||
security.maxHashtagLimit.tryEmit(syncedSettingsInternal.security.maxHashtagLimit)
|
||||
}
|
||||
|
||||
if (security.sendKind0EventsToLocalRelay.value != syncedSettingsInternal.security.sendKind0EventsToLocalRelay) {
|
||||
security.sendKind0EventsToLocalRelay.tryEmit(syncedSettingsInternal.security.sendKind0EventsToLocalRelay)
|
||||
}
|
||||
}
|
||||
|
||||
fun dontTranslateFromFilteredBySpokenLanguages(): Set<String> = languages.dontTranslateFrom.value - getLanguagesSpokenByUser()
|
||||
@@ -211,6 +217,7 @@ class AccountSecurityPreferences(
|
||||
var warnAboutPostsWithReports: Boolean = true,
|
||||
var filterSpamFromStrangers: MutableStateFlow<Boolean> = MutableStateFlow(true),
|
||||
val maxHashtagLimit: MutableStateFlow<Int> = MutableStateFlow(5),
|
||||
var sendKind0EventsToLocalRelay: MutableStateFlow<Boolean> = MutableStateFlow(false),
|
||||
) {
|
||||
fun updateShowSensitiveContent(show: Boolean?): Boolean {
|
||||
if (showSensitiveContent.value != show) {
|
||||
@@ -243,4 +250,12 @@ class AccountSecurityPreferences(
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
fun updateSendKind0EventsToLocalRelay(send: Boolean): Boolean =
|
||||
if (send != sendKind0EventsToLocalRelay.value) {
|
||||
sendKind0EventsToLocalRelay.tryEmit(send)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -106,4 +106,5 @@ class AccountSecurityPreferencesInternal(
|
||||
var warnAboutPostsWithReports: Boolean = true,
|
||||
var filterSpamFromStrangers: Boolean = true,
|
||||
val maxHashtagLimit: Int = 5,
|
||||
var sendKind0EventsToLocalRelay: Boolean = false,
|
||||
)
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.model.localRelays
|
||||
|
||||
import com.vitorpamplona.amethyst.model.AccountSettings
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.EventCollector
|
||||
|
||||
class ForwardKind0ToLocalRelayState(
|
||||
val client: INostrClient,
|
||||
val localRelayList: LocalRelayListState,
|
||||
val settings: AccountSettings,
|
||||
) {
|
||||
private val eventCollector =
|
||||
EventCollector(client) { event, _ ->
|
||||
if (event is MetadataEvent && settings.syncedSettings.security.sendKind0EventsToLocalRelay.value) {
|
||||
val localRelays = localRelayList.flow.value
|
||||
if (localRelays.isNotEmpty()) {
|
||||
client.publish(event, localRelays)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -1144,6 +1144,8 @@ class AccountViewModel(
|
||||
|
||||
fun filterSpamFromStrangers() = account.settings.syncedSettings.security.filterSpamFromStrangers
|
||||
|
||||
fun toggleSendKind0ToLocalRelay(enabled: Boolean) = launchSigner { account.updateSendKind0EventsToLocalRelay(enabled) }
|
||||
|
||||
fun updateWarnReports(warnReports: Boolean) = launchSigner { account.updateWarnReports(warnReports) }
|
||||
|
||||
fun updateFilterSpam(filterSpam: Boolean) =
|
||||
|
||||
+20
@@ -37,6 +37,7 @@ import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -88,6 +89,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.search.SearchRelayLi
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.search.renderSearchItems
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.trusted.TrustedRelayListViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.trusted.renderTrustedItems
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsRow
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.RowColSpacing
|
||||
@@ -351,6 +353,24 @@ fun MappedAllRelayListView(
|
||||
SettingsCategorySpacingModifier,
|
||||
)
|
||||
}
|
||||
item {
|
||||
val sendKind0 by accountViewModel.account.settings.syncedSettings.security.sendKind0EventsToLocalRelay
|
||||
.collectAsStateWithLifecycle()
|
||||
var checked by remember(sendKind0) { mutableStateOf(sendKind0) }
|
||||
|
||||
SettingsRow(
|
||||
R.string.send_kind0_to_local_relay_title,
|
||||
R.string.send_kind0_to_local_relay_description,
|
||||
) {
|
||||
Switch(
|
||||
checked = checked,
|
||||
onCheckedChange = {
|
||||
checked = it
|
||||
accountViewModel.toggleSendKind0ToLocalRelay(it)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
renderLocalItems(localFeedState, localViewModel, accountViewModel, nav)
|
||||
|
||||
item {
|
||||
|
||||
@@ -1517,6 +1517,8 @@
|
||||
<string name="search_section_explainer">List of relays to use when searching content or users. Tagging and search will not work if no options are available. Make sure they implement NIP-50.</string>
|
||||
<string name="local_section">Local Relays</string>
|
||||
<string name="local_section_explainer">List of relays that are running in this device.</string>
|
||||
<string name="send_kind0_to_local_relay_title">Forward profiles to local relay</string>
|
||||
<string name="send_kind0_to_local_relay_description">Send all received profile (kind 0) events to your local relay</string>
|
||||
|
||||
<string name="trusted_relays_title">Trusted Relays</string>
|
||||
<string name="trusted_section">Trusted Relays</string>
|
||||
|
||||
Reference in New Issue
Block a user