Merge pull request #2785 from greenart7c3/claude/disable-client-tags-option-Nb3b4

Add option to disable NIP-89 client tag in published events
This commit is contained in:
Vitor Pamplona
2026-05-08 08:13:49 -04:00
committed by GitHub
9 changed files with 70 additions and 2 deletions
@@ -529,6 +529,14 @@ class Account(
return false return false
} }
suspend fun updateDisableClientTag(disable: Boolean): Boolean {
if (settings.updateDisableClientTag(disable)) {
sendNewAppSpecificData()
return true
}
return false
}
suspend fun updateFilterSpam(filterSpam: Boolean): Boolean { suspend fun updateFilterSpam(filterSpam: Boolean): Boolean {
if (settings.updateFilterSpam(filterSpam)) { if (settings.updateFilterSpam(filterSpam)) {
if (!settings.syncedSettings.security.filterSpamFromStrangers.value) { if (!settings.syncedSettings.security.filterSpamFromStrangers.value) {
@@ -403,6 +403,14 @@ class AccountSettings(
} }
} }
fun updateDisableClientTag(disable: Boolean): Boolean =
if (syncedSettings.security.updateDisableClientTag(disable)) {
saveAccountSettings()
true
} else {
false
}
// --- // ---
// list names // list names
// --- // ---
@@ -55,6 +55,7 @@ class AccountSyncedSettings(
MutableStateFlow(internalSettings.security.filterSpamFromStrangers), MutableStateFlow(internalSettings.security.filterSpamFromStrangers),
MutableStateFlow(internalSettings.security.maxHashtagLimit), MutableStateFlow(internalSettings.security.maxHashtagLimit),
MutableStateFlow(internalSettings.security.sendKind0EventsToLocalRelay), MutableStateFlow(internalSettings.security.sendKind0EventsToLocalRelay),
MutableStateFlow(internalSettings.security.disableClientTag),
) )
val videoPlayer = val videoPlayer =
AccountVideoPlayerPreferences( AccountVideoPlayerPreferences(
@@ -82,6 +83,7 @@ class AccountSyncedSettings(
security.filterSpamFromStrangers.value, security.filterSpamFromStrangers.value,
security.maxHashtagLimit.value, security.maxHashtagLimit.value,
security.sendKind0EventsToLocalRelay.value, security.sendKind0EventsToLocalRelay.value,
security.disableClientTag.value,
), ),
videoPlayer = AccountVideoPlayerPreferencesInternal(videoPlayer.buttonItems.value), videoPlayer = AccountVideoPlayerPreferencesInternal(videoPlayer.buttonItems.value),
) )
@@ -138,6 +140,10 @@ class AccountSyncedSettings(
security.sendKind0EventsToLocalRelay.tryEmit(syncedSettingsInternal.security.sendKind0EventsToLocalRelay) security.sendKind0EventsToLocalRelay.tryEmit(syncedSettingsInternal.security.sendKind0EventsToLocalRelay)
} }
if (security.disableClientTag.value != syncedSettingsInternal.security.disableClientTag) {
security.disableClientTag.tryEmit(syncedSettingsInternal.security.disableClientTag)
}
val newVideoPlayerButtonItems = syncedSettingsInternal.videoPlayer.buttonItems.toImmutableList() val newVideoPlayerButtonItems = syncedSettingsInternal.videoPlayer.buttonItems.toImmutableList()
if (!equalImmutableLists(videoPlayer.buttonItems.value, newVideoPlayerButtonItems)) { if (!equalImmutableLists(videoPlayer.buttonItems.value, newVideoPlayerButtonItems)) {
videoPlayer.buttonItems.tryEmit(newVideoPlayerButtonItems) videoPlayer.buttonItems.tryEmit(newVideoPlayerButtonItems)
@@ -233,6 +239,7 @@ class AccountSecurityPreferences(
var filterSpamFromStrangers: MutableStateFlow<Boolean> = MutableStateFlow(true), var filterSpamFromStrangers: MutableStateFlow<Boolean> = MutableStateFlow(true),
val maxHashtagLimit: MutableStateFlow<Int> = MutableStateFlow(5), val maxHashtagLimit: MutableStateFlow<Int> = MutableStateFlow(5),
var sendKind0EventsToLocalRelay: MutableStateFlow<Boolean> = MutableStateFlow(false), var sendKind0EventsToLocalRelay: MutableStateFlow<Boolean> = MutableStateFlow(false),
val disableClientTag: MutableStateFlow<Boolean> = MutableStateFlow(false),
) { ) {
fun updateShowSensitiveContent(show: Boolean?): Boolean { fun updateShowSensitiveContent(show: Boolean?): Boolean {
if (showSensitiveContent.value != show) { if (showSensitiveContent.value != show) {
@@ -273,4 +280,12 @@ class AccountSecurityPreferences(
} else { } else {
false false
} }
fun updateDisableClientTag(disable: Boolean): Boolean =
if (disable != disableClientTag.value) {
disableClientTag.tryEmit(disable)
true
} else {
false
}
} }
@@ -147,4 +147,5 @@ class AccountSecurityPreferencesInternal(
var filterSpamFromStrangers: Boolean = true, var filterSpamFromStrangers: Boolean = true,
val maxHashtagLimit: Int = 5, val maxHashtagLimit: Int = 5,
var sendKind0EventsToLocalRelay: Boolean = false, var sendKind0EventsToLocalRelay: Boolean = false,
var disableClientTag: Boolean = false,
) )
@@ -135,7 +135,12 @@ class AccountCacheState(
val cached = accounts.value[signer.pubKey] val cached = accounts.value[signer.pubKey]
if (cached != null) return cached if (cached != null) return cached
val signerWithClientTag = NostrSignerWithClientTag(signer, CLIENT_TAG_NAME) val signerWithClientTag =
NostrSignerWithClientTag(
inner = signer,
clientName = CLIENT_TAG_NAME,
disabled = { accountSettings.syncedSettings.security.disableClientTag.value },
)
val accountDir = File(rootFilesDir(), "accounts/${signer.pubKey}").apply { mkdirs() } val accountDir = File(rootFilesDir(), "accounts/${signer.pubKey}").apply { mkdirs() }
@@ -1112,6 +1112,8 @@ class AccountViewModel(
fun updateWarnReports(warnReports: Boolean) = launchSigner { account.updateWarnReports(warnReports) } fun updateWarnReports(warnReports: Boolean) = launchSigner { account.updateWarnReports(warnReports) }
fun updateDisableClientTag(disable: Boolean) = launchSigner { account.updateDisableClientTag(disable) }
fun updateFilterSpam(filterSpam: Boolean) = fun updateFilterSpam(filterSpam: Boolean) =
launchSigner { launchSigner {
if (account.updateFilterSpam(filterSpam)) { if (account.updateFilterSpam(filterSpam)) {
@@ -371,6 +371,21 @@ private fun HeaderOptions(accountViewModel: AccountViewModel) {
) )
} }
SettingsRow(
R.string.disable_client_tag_title,
R.string.disable_client_tag_explainer,
) {
var disableClientTag by remember { mutableStateOf(accountViewModel.account.settings.syncedSettings.security.disableClientTag.value) }
Switch(
checked = disableClientTag,
onCheckedChange = {
disableClientTag = it
accountViewModel.updateDisableClientTag(disableClientTag)
},
)
}
SettingsRow( SettingsRow(
R.string.show_sensitive_content_title, R.string.show_sensitive_content_title,
R.string.show_sensitive_content_explainer, R.string.show_sensitive_content_explainer,
+2
View File
@@ -1178,6 +1178,8 @@
<string name="filter_spam_from_strangers_title">Filter spam</string> <string name="filter_spam_from_strangers_title">Filter spam</string>
<string name="filter_spam_from_strangers_explainer">Hides posts from strangers that were exactly the same for 5 or more times</string> <string name="filter_spam_from_strangers_explainer">Hides posts from strangers that were exactly the same for 5 or more times</string>
<string name="disable_client_tag_title">Don\'t add client tag to my events</string>
<string name="disable_client_tag_explainer">When enabled, Amethyst will not append a NIP-89 client tag to events you publish.</string>
<string name="warn_when_posts_have_reports_from_your_follows_title">Warn on reports</string> <string name="warn_when_posts_have_reports_from_your_follows_title">Warn on reports</string>
<string name="warn_when_posts_have_reports_from_your_follows_explainer">Shows a warning message when posts have 5 or more reports from your follows</string> <string name="warn_when_posts_have_reports_from_your_follows_explainer">Shows a warning message when posts have 5 or more reports from your follows</string>
<string name="show_sensitive_content_title">Show sensitive content</string> <string name="show_sensitive_content_title">Show sensitive content</string>
@@ -40,12 +40,19 @@ import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
class NostrSignerWithClientTag( class NostrSignerWithClientTag(
val inner: NostrSigner, val inner: NostrSigner,
val clientTag: Array<String>, val clientTag: Array<String>,
val disabled: () -> Boolean = { false },
) : NostrSigner(inner.pubKey) { ) : NostrSigner(inner.pubKey) {
constructor( constructor(
inner: NostrSigner, inner: NostrSigner,
clientName: String, clientName: String,
) : this(inner, ClientTag.assemble(clientName)) ) : this(inner, ClientTag.assemble(clientName))
constructor(
inner: NostrSigner,
clientName: String,
disabled: () -> Boolean,
) : this(inner, ClientTag.assemble(clientName), disabled)
constructor( constructor(
inner: NostrSigner, inner: NostrSigner,
clientName: String, clientName: String,
@@ -60,7 +67,12 @@ class NostrSignerWithClientTag(
kind: Int, kind: Int,
tags: Array<Array<String>>, tags: Array<Array<String>>,
content: String, content: String,
): T = inner.sign(createdAt, kind, appendClientTag(tags), content) ): T =
if (disabled()) {
inner.sign(createdAt, kind, tags, content)
} else {
inner.sign(createdAt, kind, appendClientTag(tags), content)
}
override suspend fun nip04Encrypt( override suspend fun nip04Encrypt(
plaintext: String, plaintext: String,