diff --git a/.claude/skills/amy-expert/SKILL.md b/.claude/skills/amy-expert/SKILL.md index c0139959cf..f6cbce8416 100644 --- a/.claude/skills/amy-expert/SKILL.md +++ b/.claude/skills/amy-expert/SKILL.md @@ -129,10 +129,12 @@ via `Output.emit`. The template is in `references/command-template.md`; copy it rather than re-deriving it. Wire-up checklist: -1. New file in `cli/commands/` with the `object` pattern. -2. Add a branch in `Commands.kt`. -3. Add a branch in `Main.kt`'s `dispatch` (or under `marmotDispatch` - / a new group dispatcher). +1. New file in `cli/commands/` with the `object` pattern. Sub-verb + `dispatch` functions use the shared `route(...)` helper in + `Router.kt` rather than a hand-rolled `when (tail[0])`. +2. Add a branch in `Main.kt`'s `dispatch` (top-level verbs call the + command object directly, e.g. `"relay" -> RelayCommands.dispatch(…)`; + `marmot` sub-verbs go through `marmotDispatch`'s `route` map). 4. Extend `printUsage()` in `Main.kt`. 5. Add the row to `cli/README.md`'s command table. 6. Update `cli/ROADMAP.md` — move the row from 🆕 / 📦 to ✅. @@ -173,6 +175,7 @@ cli/ ├── secrets/ # SecretStore backends (keychain / ncryptsec / plaintext) └── commands/ # one file (or group) per top-level verb ├── UseCommand.kt # `amy use NAME` + ├── Router.kt # `route(...)` shared sub-verb dispatcher ├── InitCommands.kt # init, whoami ├── CreateCommand.kt + LoginCommand.kt ├── RelayCommands.kt diff --git a/.claude/skills/amy-expert/references/command-template.md b/.claude/skills/amy-expert/references/command-template.md index b2adc99a75..4546de0367 100644 --- a/.claude/skills/amy-expert/references/command-template.md +++ b/.claude/skills/amy-expert/references/command-template.md @@ -18,8 +18,7 @@ object NotePublishCommand { val args = Args(rest) val text = args.positional(0, "text") - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val event = com.vitorpamplona.amethyst.commons.note @@ -33,13 +32,15 @@ object NotePublishCommand { "rejected_by" to ack.filterValues { !it }.keys.map { it.url }, )) return 0 - } finally { - ctx.close() } } } ``` +`Context` is `AutoCloseable`; wrap it in `use { }` so it's closed +(RunState flushed, relays disconnected) on every exit path — never a +hand-rolled `try { } finally { ctx.close() }`. + `Output.emit(...)` handles the text-vs-JSON mode automatically. The result map IS the `--json` shape; the human-readable text default is derived from the same map by `Output.kt`'s renderer. @@ -51,39 +52,34 @@ When a feature has several verbs (`note publish`, `note show`, ```kotlin object NoteCommands { - suspend fun dispatch(dataDir: DataDir, tail: Array): Int { - if (tail.isEmpty()) return Output.error("bad_args", "note ") - val rest = tail.drop(1).toTypedArray() - return when (tail[0]) { - "publish" -> NotePublishCommand.run(dataDir, rest) - "show" -> NoteShowCommand.run(dataDir, rest) - "react" -> NoteReactCommand.run(dataDir, rest) - else -> Output.error("bad_args", "note ${tail[0]}") - } - } + suspend fun dispatch(dataDir: DataDir, tail: Array): Int = + route("note", tail, "note ", mapOf( + "publish" to { rest -> NotePublishCommand.run(dataDir, rest) }, + "show" to { rest -> NoteShowCommand.run(dataDir, rest) }, + "react" to { rest -> NoteReactCommand.run(dataDir, rest) }, + )) } ``` -Each verb gets its own file. Once a single file crosses ~200 lines, -split it — see `GroupCommands.kt` and its siblings as the reference. +The shared `route(name, tail, usage, routes)` helper (`Router.kt`) +handles the empty-input and unknown-verb `bad_args` branches, so the +`dispatch` body is just the verb→handler map. Each verb gets its own +file. Once a single file crosses ~200 lines, split it — see +`GroupCommands.kt` and its siblings as the reference. ## Wire-up checklist For every new command: 1. File under `cli/commands/`. -2. Branch in `Commands.kt`: +2. Branch in `Main.kt`'s top-level `dispatch`, calling the command + object directly: ```kotlin - suspend fun note(dataDir: DataDir, tail: Array): Int = - NoteCommands.dispatch(dataDir, tail) + "note" -> NoteCommands.dispatch(dataDir, tail) ``` -3. Branch in `Main.kt`'s top-level `dispatch`: - ```kotlin - "note" -> Commands.note(dataDir, tail) - ``` -4. Line in `printUsage()` explaining the verb. -5. Row in `cli/README.md`'s command table. -6. Status flip in `cli/ROADMAP.md` (🆕 / 📦 → ✅). +3. Line in `printUsage()` explaining the verb. +4. Row in `cli/README.md`'s command table. +5. Status flip in `cli/ROADMAP.md` (🆕 / 📦 → ✅). ## What not to do @@ -95,7 +91,7 @@ For every new command: them to `error: …` (text mode) / `{"error":…}` (JSON mode) plus the right exit code. - No holding a connection open across invocations — every run opens - a fresh `Context` and closes it in `finally`. + a fresh `Context` inside `use { }` so it closes on every exit path. - No blocking reads for user input — take a flag. - No global flags that collide with subcommand flags. `--name` is reserved for subcommand use (group/profile name); the global diff --git a/.claude/skills/quartz-integration/SKILL.md b/.claude/skills/quartz-integration/SKILL.md index 1c0bb21759..29b41f2d65 100644 --- a/.claude/skills/quartz-integration/SKILL.md +++ b/.claude/skills/quartz-integration/SKILL.md @@ -7,7 +7,7 @@ description: Integration guide for using the Quartz Nostr KMP library in externa Reference for integrating `com.vitorpamplona.quartz:quartz` into external Nostr KMP projects. -**Published artifact**: `com.vitorpamplona.quartz:quartz:1.12.5` (Maven Central) +**Published artifact**: `com.vitorpamplona.quartz:quartz:1.12.6` (Maven Central) **Targets**: JVM 21+, Android (minSdk 21+), iOS (XCFramework `quartz-kmpKit`) **License**: MIT @@ -19,7 +19,7 @@ Reference for integrating `com.vitorpamplona.quartz:quartz` into external Nostr ```toml [versions] -quartz = "1.12.5" +quartz = "1.12.6" [libraries] quartz = { module = "com.vitorpamplona.quartz:quartz", version.ref = "quartz" } @@ -41,7 +41,7 @@ kotlin { ```kotlin dependencies { - implementation("com.vitorpamplona.quartz:quartz:1.12.5") + implementation("com.vitorpamplona.quartz:quartz:1.12.6") } ``` diff --git a/.claude/skills/quartz-integration/references/gradle-setup.md b/.claude/skills/quartz-integration/references/gradle-setup.md index 5698f007ad..4c3a55e054 100644 --- a/.claude/skills/quartz-integration/references/gradle-setup.md +++ b/.claude/skills/quartz-integration/references/gradle-setup.md @@ -3,7 +3,7 @@ ## Current version ``` -com.vitorpamplona.quartz:quartz:1.12.5 +com.vitorpamplona.quartz:quartz:1.12.6 ``` Check latest: https://central.sonatype.com/artifact/com.vitorpamplona.quartz/quartz @@ -16,7 +16,7 @@ Check latest: https://central.sonatype.com/artifact/com.vitorpamplona.quartz/qua ```toml [versions] -quartz = "1.12.5" +quartz = "1.12.6" [libraries] quartz = { module = "com.vitorpamplona.quartz:quartz", version.ref = "quartz" } @@ -55,7 +55,7 @@ kotlin { ```kotlin // build.gradle.kts (app module) dependencies { - implementation("com.vitorpamplona.quartz:quartz:1.12.5") + implementation("com.vitorpamplona.quartz:quartz:1.12.6") } ``` @@ -70,7 +70,7 @@ plugins { } dependencies { - implementation("com.vitorpamplona.quartz:quartz:1.12.5") + implementation("com.vitorpamplona.quartz:quartz:1.12.6") // JNA needed for libsodium (NIP-44) on JVM implementation("net.java.dev.jna:jna:5.18.1") } diff --git a/.github/workflows/crowdin.yml b/.github/workflows/crowdin.yml index 719f8709cf..3712fed647 100644 --- a/.github/workflows/crowdin.yml +++ b/.github/workflows/crowdin.yml @@ -10,12 +10,21 @@ permissions: pull-requests: write jobs: + # Single job so the Crowdin translation sync and the translator-placeholder seed + # land in ONE pull request instead of two. The Crowdin action only downloads into + # the working tree (push_translations/create_pull_request disabled); the seed + # script then edits translators.json; finally one create-pull-request step opens a + # single PR with both sets of changes (and no-ops when there is no diff). synchronize-with-crowdin: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v6 + with: + # Need tags so scripts/translators.sh can resolve the last v* release tag + # for the "since last tag" window. + fetch-depth: 0 - name: crowdin action uses: crowdin/github-action@v2 @@ -23,50 +32,42 @@ jobs: upload_sources: true upload_translations: true download_translations: true - localization_branch_name: l10n_crowdin_translations - create_pull_request: true - pull_request_title: 'New Crowdin Translations' - pull_request_body: 'New Crowdin translations by [Crowdin GH Action](https://github.com/crowdin/github-action)' - pull_request_base_branch_name: 'main' + # Let the downloaded translations stay in the working tree; the single + # create-pull-request step below opens the combined PR. + push_translations: false + create_pull_request: false env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} - # Keep docs/changelog/translators.json seeded with everyone who has translated - # recently, so the per-release `## Translations` credits (scripts/translators.sh) - # can resolve them to npubs. Runs independently of the sync job above and only - # opens/updates a PR when a genuinely new contributor appears. - seed-translators: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v6 - with: - # Need tags so the script can resolve the last v* release tag for the - # "since last tag" window. - fetch-depth: 0 - + # Keep docs/changelog/translators.json seeded with everyone who has translated + # recently, so the per-release `## Translations` credits (scripts/translators.sh) + # can resolve them to npubs. Only adds rows when a genuinely new contributor + # appears. - name: Seed translator placeholders from Crowdin run: bash scripts/translators.sh --seed env: CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} - - name: Open or update the seed PR + - name: Open or update the combined Crowdin PR # peter-evans/create-pull-request is MIT-licensed CI-only tooling (not # linked into any shipped artifact). It no-ops when there is no diff. uses: peter-evans/create-pull-request@v7 with: token: ${{ secrets.GITHUB_TOKEN }} base: main - branch: chore/seed-translators - add-paths: docs/changelog/translators.json - commit-message: 'chore: seed translator npub placeholders from Crowdin' - title: 'Seed translator npub placeholders' + branch: l10n_crowdin_translations + add-paths: | + amethyst/src/main/res/**/strings.xml + docs/changelog/translators.json + commit-message: 'chore: sync Crowdin translations and seed translator npub placeholders' + title: 'New Crowdin Translations' body: | - New Crowdin contributors were added to `docs/changelog/translators.json` + New Crowdin translations by [Crowdin GH Action](https://github.com/crowdin/github-action). + + Any new Crowdin contributors were added to `docs/changelog/translators.json` with blank npubs. Fill in the npubs you have so the next release's `## Translations` credits generate automatically via - `scripts/translators.sh --from --to `. \ No newline at end of file + `scripts/translators.sh --from --to `. diff --git a/README.md b/README.md index f161899601..9148b6b1be 100644 --- a/README.md +++ b/README.md @@ -297,16 +297,16 @@ repositories { Add the following line to your `commonMain` dependencies: ```gradle -implementation('com.vitorpamplona.quartz:quartz:1.12.5') +implementation('com.vitorpamplona.quartz:quartz:1.12.6') ``` Variations to each platform are also available: ```gradle -implementation('com.vitorpamplona.quartz:quartz-android:1.12.5') -implementation('com.vitorpamplona.quartz:quartz-jvm:1.12.5') -implementation('com.vitorpamplona.quartz:quartz-iosarm64:1.12.5') -implementation('com.vitorpamplona.quartz:quartz-iossimulatorarm64:1.12.5') +implementation('com.vitorpamplona.quartz:quartz-android:1.12.6') +implementation('com.vitorpamplona.quartz:quartz-jvm:1.12.6') +implementation('com.vitorpamplona.quartz:quartz-iosarm64:1.12.6') +implementation('com.vitorpamplona.quartz:quartz-iossimulatorarm64:1.12.6') ``` Check versions on [MavenCentral](https://central.sonatype.com/search?q=com.vitorpamplona.quartz) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt index 4f5854a76c..79ef5a3bd9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt @@ -123,6 +123,7 @@ private object PrefKeys { const val DEFAULT_BROWSE_EMOJI_SETS_FOLLOW_LIST = "defaultBrowseEmojiSetsFollowList" const val DEFAULT_COMMUNITIES_FOLLOW_LIST = "defaultCommunitiesFollowList" const val DEFAULT_FOLLOW_PACKS_FOLLOW_LIST = "defaultFollowPacksFollowList" + const val DEFAULT_APP_RECOMMENDATIONS_FOLLOW_LIST = "defaultAppRecommendationsFollowList" const val ZAP_PAYMENT_REQUEST_SERVER = "zapPaymentServer" // legacy, kept for migration const val NWC_WALLETS = "nwcWallets" const val DEFAULT_NWC_WALLET_ID = "defaultNwcWalletId" // legacy, migrated into DEFAULT_PAYMENT_SOURCE_ID @@ -152,6 +153,7 @@ private object PrefKeys { const val HIDE_NIP_17_WARNING_DIALOG = "hide_nip24_warning_dialog" // delete later const val ALWAYS_ON_NOTIFICATION_SERVICE = "always_on_notification_service" const val SPLIT_NOTIFICATIONS_ENABLED = "split_notifications_enabled" + const val SHOW_MESSAGES_IN_NOTIFICATIONS = "show_messages_in_notifications" // One-shot stamp: set once an account has gone through the notifications // Global -> Selected (Curated) migration (or was created after it shipped). @@ -406,6 +408,7 @@ object LocalPreferences { putString(PrefKeys.DEFAULT_BROWSE_EMOJI_SETS_FOLLOW_LIST, JsonMapper.toJson(settings.defaultBrowseEmojiSetsFollowList.value)) putString(PrefKeys.DEFAULT_COMMUNITIES_FOLLOW_LIST, JsonMapper.toJson(settings.defaultCommunitiesFollowList.value)) putString(PrefKeys.DEFAULT_FOLLOW_PACKS_FOLLOW_LIST, JsonMapper.toJson(settings.defaultFollowPacksFollowList.value)) + putString(PrefKeys.DEFAULT_APP_RECOMMENDATIONS_FOLLOW_LIST, JsonMapper.toJson(settings.defaultAppRecommendationsFollowList.value)) val walletEntries = settings.nwcWallets.value.mapNotNull { it.denormalize() } if (walletEntries.isNotEmpty()) { @@ -467,6 +470,7 @@ object LocalPreferences { putBoolean(PrefKeys.CALLS_ENABLED, settings.callsEnabled.value) putBoolean(PrefKeys.ALWAYS_ON_NOTIFICATION_SERVICE, settings.alwaysOnNotificationService.value) putBoolean(PrefKeys.SPLIT_NOTIFICATIONS_ENABLED, settings.splitNotificationsEnabled.value) + putBoolean(PrefKeys.SHOW_MESSAGES_IN_NOTIFICATIONS, settings.showMessagesInNotifications.value) // Any account that reaches a save has its notification filter in its // post-split meaning, so stamp it as migrated. This keeps the one-shot // Global -> Selected rewrite from ever touching it again and preserves a @@ -582,6 +586,7 @@ object LocalPreferences { val callsEnabled = getBoolean(PrefKeys.CALLS_ENABLED, true) val alwaysOnNotificationService = getBoolean(PrefKeys.ALWAYS_ON_NOTIFICATION_SERVICE, false) val splitNotificationsEnabled = getBoolean(PrefKeys.SPLIT_NOTIFICATIONS_ENABLED, false) + val showMessagesInNotifications = getBoolean(PrefKeys.SHOW_MESSAGES_IN_NOTIFICATIONS, true) val hasDonatedInVersion = getStringSet(PrefKeys.HAS_DONATED_IN_VERSION, null) ?: setOf() val dismissedPollNoteIds = getStringSet(PrefKeys.DISMISSED_POLL_NOTE_IDS, null) ?: setOf() val viewedPollResultNoteIdsStr = getString(PrefKeys.VIEWED_POLL_RESULT_NOTE_IDS, null) @@ -727,6 +732,7 @@ object LocalPreferences { defaultBrowseEmojiSetsFollowList = MutableStateFlow(followListPrefs.browseEmojiSets), defaultCommunitiesFollowList = MutableStateFlow(followListPrefs.communities), defaultFollowPacksFollowList = MutableStateFlow(followListPrefs.followPacks), + defaultAppRecommendationsFollowList = MutableStateFlow(followListPrefs.appRecommendations), nwcWallets = MutableStateFlow(nwcWalletsLoaded.await().first), clinkDebitWallets = MutableStateFlow(clinkDebitsLoaded.await()), // Prefer the new unified default; migrate from the legacy NWC default; @@ -742,6 +748,7 @@ object LocalPreferences { hideNIP17WarningDialog = hideNIP17WarningDialog, alwaysOnNotificationService = MutableStateFlow(alwaysOnNotificationService), splitNotificationsEnabled = MutableStateFlow(splitNotificationsEnabled), + showMessagesInNotifications = MutableStateFlow(showMessagesInNotifications), backupUserMetadata = latestUserMetadata.await(), backupContactList = latestContactList.await(), backupNIP65RelayList = latestNip65RelayList.await(), @@ -815,6 +822,7 @@ object LocalPreferences { val browseEmojiSets: TopFilter, val communities: TopFilter, val followPacks: TopFilter, + val appRecommendations: TopFilter, ) /** @@ -867,6 +875,7 @@ object LocalPreferences { browseEmojiSets = parseTopFilterOrDefault(getString(PrefKeys.DEFAULT_BROWSE_EMOJI_SETS_FOLLOW_LIST, null), TopFilter.Global), communities = parseTopFilterOrDefault(getString(PrefKeys.DEFAULT_COMMUNITIES_FOLLOW_LIST, null), TopFilter.AllFollows), followPacks = parseTopFilterOrDefault(getString(PrefKeys.DEFAULT_FOLLOW_PACKS_FOLLOW_LIST, null), TopFilter.Global), + appRecommendations = parseTopFilterOrDefault(getString(PrefKeys.DEFAULT_APP_RECOMMENDATIONS_FOLLOW_LIST, null), TopFilter.Global), ) private inline fun parseOrNull(value: String?): T? { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index b2bcd2daf8..6ac097df8e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -425,6 +425,8 @@ class Account( scope = scope, assembler = cashuWalletFilterAssembler(), outboxRelaysFlow = outboxRelays.flow, + inboxRelaysFlow = notificationRelays.flow, + dmRelaysFlow = dmRelays.flow, settings = settings, okHttpClient = okHttpClientForMoney, ) @@ -586,6 +588,11 @@ class Account( val liveFollowPacksFollowLists: StateFlow = topNavFilterFlow(settings.defaultFollowPacksFollowList) val liveFollowPacksFollowListsPerRelay = OutboxLoaderState(liveFollowPacksFollowLists, cache, scope).flow + // App recommendations are read straight from LocalCache (no relay feed of its + // own), so only the in-memory author/tag matcher is needed here, not a + // per-relay outbox loader. + val liveAppRecommendationsFollowLists: StateFlow = topNavFilterFlow(settings.defaultAppRecommendationsFollowList) + override fun isWriteable(): Boolean = settings.isWriteable() suspend fun updateWarnReports(warnReports: Boolean): Boolean { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSettings.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSettings.kt index 93e89ca49e..df6f82ba37 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSettings.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSettings.kt @@ -207,6 +207,7 @@ class AccountSettings( val defaultBrowseEmojiSetsFollowList: MutableStateFlow = MutableStateFlow(TopFilter.Global), val defaultCommunitiesFollowList: MutableStateFlow = MutableStateFlow(TopFilter.AllFollows), val defaultFollowPacksFollowList: MutableStateFlow = MutableStateFlow(TopFilter.Global), + val defaultAppRecommendationsFollowList: MutableStateFlow = MutableStateFlow(TopFilter.Global), val nwcWallets: MutableStateFlow> = MutableStateFlow(emptyList()), val clinkDebitWallets: MutableStateFlow> = MutableStateFlow(emptyList()), // The unified default spend rail (an NWC wallet OR a CLINK debit). Persisted under a @@ -217,6 +218,7 @@ class AccountSettings( var hideNIP17WarningDialog: Boolean = false, val alwaysOnNotificationService: MutableStateFlow = MutableStateFlow(false), val splitNotificationsEnabled: MutableStateFlow = MutableStateFlow(false), + val showMessagesInNotifications: MutableStateFlow = MutableStateFlow(true), var backupUserMetadata: MetadataEvent? = null, var backupContactList: ContactListEvent? = null, var backupDMRelayList: ChatMessageRelayListEvent? = null, @@ -295,6 +297,13 @@ class AccountSettings( return newValue } + fun toggleShowMessagesInNotifications(): Boolean { + val newValue = !showMessagesInNotifications.value + showMessagesInNotifications.tryEmit(newValue) + saveAccountSettings() + return newValue + } + // --- // Zaps and Reactions // --- @@ -818,6 +827,17 @@ class AccountSettings( } } + fun changeDefaultAppRecommendationsFollowList(name: FeedDefinition) { + changeDefaultAppRecommendationsFollowList(name.code) + } + + fun changeDefaultAppRecommendationsFollowList(name: TopFilter) { + if (defaultAppRecommendationsFollowList.value != name) { + defaultAppRecommendationsFollowList.tryEmit(name) + saveAccountSettings() + } + } + // --- // language services // --- diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index c985f20823..fc6a9d14e3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -59,6 +59,7 @@ import com.vitorpamplona.quartz.experimental.edits.TextNoteModificationEvent import com.vitorpamplona.quartz.experimental.ephemChat.chat.EphemeralChatEvent import com.vitorpamplona.quartz.experimental.ephemChat.chat.RoomId import com.vitorpamplona.quartz.experimental.ephemChat.list.EphemeralChatListEvent +import com.vitorpamplona.quartz.experimental.fitness.workout.ExerciseTemplateEvent import com.vitorpamplona.quartz.experimental.fitness.workout.WorkoutRecordEvent import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryReadingStateEvent @@ -4014,6 +4015,10 @@ object LocalCache : ILocalCache, ICacheProvider { consumeRegularEvent(event, relay, wasVerified) } + is ExerciseTemplateEvent -> { + consumeBaseReplaceable(event, relay, wasVerified) + } + is PaymentTargetsEvent -> { consume(event, relay, wasVerified) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip60Cashu/CashuWalletOps.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip60Cashu/CashuWalletOps.kt index bd8472aa6a..ae264b938d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip60Cashu/CashuWalletOps.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip60Cashu/CashuWalletOps.kt @@ -153,9 +153,11 @@ class CashuWalletOps( val walletEvent = signer.sign(walletTemplate) publish(walletEvent) - // Populate `relay` tags so senders know where to publish nutzaps — - // without these, they fall back to NIP-65 outbox and may miss our - // subscription scope on relays we don't read from. + // Populate `relay` tags so senders know where to publish nutzaps. + // Per NIP-61 these are the relays where the recipient reads incoming + // token events, so callers pass our inbox-side relays here (NIP-65 + // outbox model). Without them, senders fall back to NIP-65 and may + // publish where we don't subscribe for inbound nutzaps. val nutzapInfoTemplate = NutzapInfoEvent.build( mints = mints.map { NutzapMintTag(it, listOf("sat")) }, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip60Cashu/CashuWalletState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip60Cashu/CashuWalletState.kt index 938dccf661..82961b923d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip60Cashu/CashuWalletState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip60Cashu/CashuWalletState.kt @@ -97,6 +97,8 @@ class CashuWalletState( private val scope: CoroutineScope, private val assembler: CashuWalletFilterAssembler, private val outboxRelaysFlow: StateFlow>, + private val inboxRelaysFlow: StateFlow>, + private val dmRelaysFlow: StateFlow>, private val settings: AccountSettings, okHttpClient: (String) -> OkHttpClient, ) { @@ -436,12 +438,31 @@ class CashuWalletState( triggerAutoRedeem() } - // Keep the relay subscription in sync with the outbox set. + // Keep the wallet subscription in sync with the relay sets it reads + // from. Following the NIP-65 outbox model, the two halves of the + // subscription read from different places: + // - our own NIP-60 events (wallet/token/history) are read back from + // our OUTBOX relays, where we published them; + // - inbound kind:9321 nutzaps are read from our INBOX set, since + // that is where other people deliver them. Per NIP-61 the source + // of truth for "where to send me nutzaps" is the `relay` tags in + // our own kind:10019 — and another client may have published that + // with relays unrelated to our NIP-65 lists — so we listen on the + // union of those plus our NIP-65 inbox + DM relays. jobs += scope.launch(Dispatchers.IO) { - outboxRelaysFlow.collect { relays -> - syncSubscription(relays) - } + combine( + outboxRelaysFlow, + inboxRelaysFlow, + dmRelaysFlow, + _nutzapInfoEvent, + ) { outbox, inbox, dm, info -> + CashuWalletQueryState( + pubkey = pubKey, + ownEventRelays = outbox, + inboxRelays = inbox + dm + (info?.relays() ?: emptyList()), + ) + }.collect { syncSubscription(it) } } // Reactive incremental update: any new event arrival that matches our @@ -504,17 +525,16 @@ class CashuWalletState( // ============================================================ // Subscription management // ============================================================ - private fun syncSubscription(relays: Set) { + private fun syncSubscription(next: CashuWalletQueryState) { val previous = currentSubscription - if (relays.isEmpty()) { + if (next.ownEventRelays.isEmpty() && next.inboxRelays.isEmpty()) { previous?.let { runCatching { assembler.unsubscribe(it) } } currentSubscription = null return } - if (previous != null && previous.relays == relays) return // unchanged + if (previous == next) return // unchanged previous?.let { runCatching { assembler.unsubscribe(it) } } - val next = CashuWalletQueryState(pubKey, relays) currentSubscription = next assembler.subscribe(next) } @@ -875,7 +895,11 @@ class CashuWalletState( ops.publishWalletEvents( mints = currentMints, p2pkPrivkeyHex = manualPrivkeyHex?.takeIf { it.isNotBlank() }, - nutzapRelays = outboxRelaysFlow.value.toList(), + // Advertise our NIP-65 inbox relays as the nutzap relays (NIP-65 + // outbox model): senders publish kind:9321 where we read inbound + // events. We listen on a wider set (inbox + DM + these tags), but + // the kind:10019 default copies the inbox relay list, not outbox. + nutzapRelays = inboxRelaysFlow.value.toList(), ) // The NUT-13 seed (derived from the P2PK key) is invalidated by // applyEvents when the new kind:17375 round-trips in, so it re-derives diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt index ef0fc8550e..7a401f57b8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CachedRichTextParser.kt @@ -27,7 +27,11 @@ import com.vitorpamplona.amethyst.commons.richtext.RichTextViewerState import com.vitorpamplona.amethyst.commons.richtext.UrlParser object CachedRichTextParser { - private val richTextCache = LruCache(50) + // Global across every feed. Sized to hold the active feed's visible + prefetched + // (see PrefetchFeedMedia) working set plus a few other feeds' recent entries, so + // pre-parsed bodies survive until the render reads them and feed switches don't + // thrash. Each entry is one note's parsed segments — typically single-digit KB. + private val richTextCache = LruCache(500) private val isMarkdownCache = LruCache(200) private fun hashCodeCache( @@ -37,7 +41,14 @@ object CachedRichTextParser { authorPubKey: String?, ): Int { var result = content.hashCode() - result = 31 * result + tags.lists.hashCode() + // Content-addressed (memoized contentHash), not identity — `lists` is an + // Array>, so a fresh instance with the same tag content must + // map to the same entry. This lets an off-thread pre-parse (the feed media + // prefetcher) populate the exact entry the renderer later looks up, turning + // the scroll-time parse into a cache hit. The parse is a pure function of + // tag content, so equal content sharing one entry is correct. The hash is + // cached on the instance so this stays O(1)-amortized per tag list. + result = 31 * result + tags.contentHash() if (callbackUri != null) { result = 31 * result + callbackUri.hashCode() } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt index 5860829872..2a1ea4887c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt @@ -69,6 +69,7 @@ import com.vitorpamplona.quartz.nip22Comments.CommentEvent import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent +import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji import com.vitorpamplona.quartz.nip34Git.issue.GitIssueEvent import com.vitorpamplona.quartz.nip34Git.patch.GitPatchEvent import com.vitorpamplona.quartz.nip54Wiki.WikiNoteEvent @@ -174,7 +175,13 @@ class EventNotificationConsumer( val accountHex = npubToHexOrNull(savedAccount.npub) ?: return@forEach if (matchingNote != null) { - if (!event.isTaggedUser(accountHex)) return@forEach + // Public chat replies into my messages often omit the `p` + // tag; relax the gate for them (tagsAnEventByUser keeps it + // scoped to messages actually replying to me). + val taggedOrPublicChatReply = + event.isTaggedUser(accountHex) || + NotificationFeedFilter.isNotifiablePublicChatReply(matchingNote, accountHex) + if (!taggedOrPublicChatReply) return@forEach if (!NotificationFeedFilter.tagsAnEventByUser(matchingNote, accountHex)) return@forEach } @@ -251,12 +258,13 @@ class EventNotificationConsumer( is CommentEvent -> notify(event, account) + is ChannelMessageEvent -> notify(event, account) + is PictureEvent, is VideoNormalEvent, is VideoShortEvent, is VideoHorizontalEvent, is VideoVerticalEvent, - is ChannelMessageEvent, is PollEvent, is GitPatchEvent, is GitIssueEvent, @@ -755,7 +763,12 @@ class EventNotificationConsumer( // p-tag match already enforced by consumeFromCache; no redundant // isTaggedUser re-check needed. - val reactedPostId = event.originalPost().firstOrNull() ?: return + // NIP-25: when a reaction carries multiple `e` tags (e.g. both the + // thread root and the replied-to note), the LAST one is the event + // actually being reacted to. Using the first tag would surface the + // root in the tray when the like was really on a reply. This matches + // the in-app card, which resolves the target via replyTo.lastOrNull(). + val reactedPostId = event.originalPost().lastOrNull() ?: return val reactedNote = LocalCache.checkGetOrCreateNote(reactedPostId) // Drop reactions on muted threads, hidden authors, etc. @@ -766,14 +779,24 @@ class EventNotificationConsumer( val userPicture = author.profilePicture() val reactionContent = event.content - val reactionSymbol = - when { - reactionContent == ReactionEvent.LIKE || reactionContent.isBlank() -> "\uD83E\uDD19" - reactionContent == ReactionEvent.DISLIKE -> "\uD83D\uDC4E" - else -> reactionContent - } - val title = "$reactionSymbol $user" + // NIP-30 custom emoji: content is ":shortcode:" backed by an ["emoji", shortcode, url] + // tag. The image can't be rendered as text, so it is surfaced as a badge on the author's + // avatar (see sendReactionNotification) and the title keeps just the author's name. + val customEmojiUrl = CustomEmoji.createEmojiMap(event.tags)[reactionContent] + + val title = + if (customEmojiUrl != null) { + user + } else { + val reactionSymbol = + when { + reactionContent == ReactionEvent.LIKE || reactionContent.isBlank() -> "\uD83E\uDD19" + reactionContent == ReactionEvent.DISLIKE -> "\uD83D\uDC4E" + else -> reactionContent + } + "$reactionSymbol $user" + } val reactedContent = reactedNote @@ -813,6 +836,7 @@ class EventNotificationConsumer( userPicture, noteUri, applicationContext, + emojiUrl = customEmojiUrl, ) } @@ -865,6 +889,32 @@ class EventNotificationConsumer( notifyReply(event, account, parentContent, threadRoot) } + private suspend fun notify( + event: ChannelMessageEvent, + account: Account, + ) { + Log.d(TAG, "New Public Chat Message to Notify") + // Age + self-author gates run centrally in dispatchForAccount. + val note = LocalCache.getNoteIfExists(event.id) ?: return + + // A reply into one of my messages in this channel — even when the + // sender didn't p-tag me. Render it as a reply (threaded + inline + // reply action) grouped by channel so a busy room collapses into one + // notification instead of spamming. Falls back to a plain mention when + // I'm only p-tagged (a citation, not a reply to my message). + if (NotificationFeedFilter.isNotifiablePublicChatReply(note, account.signer.pubKey)) { + val parentContent = + note.replyTo + ?.lastOrNull() + ?.event + ?.content + val threadRoot = event.channelId() ?: event.id + notifyReply(event, account, parentContent, threadRoot) + } else { + notifyMention(event, account) + } + } + private suspend fun notifyReply( event: Event, account: Account, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationDispatcher.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationDispatcher.kt index 67407a0907..37e6fb2f96 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationDispatcher.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationDispatcher.kt @@ -203,7 +203,14 @@ class NotificationDispatcher( // always miss for replies into addressable posts. val note = LocalCache.getNoteIfExists(event) ?: return@predicate false pubkeys.any { pubkey -> - event.isTaggedUser(pubkey) && + // Public chat replies into my own messages often + // omit the `p` tag; relax the gate for them (the + // tagsAnEventByUser check still scopes it to + // messages actually replying to me). + ( + event.isTaggedUser(pubkey) || + NotificationFeedFilter.isNotifiablePublicChatReply(note, pubkey) + ) && NotificationFeedFilter.tagsAnEventByUser(note, pubkey) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationReplyReceiver.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationReplyReceiver.kt index 3f4c9c6483..5f3cf8eb5d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationReplyReceiver.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationReplyReceiver.kt @@ -29,11 +29,13 @@ import androidx.core.content.ContextCompat import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.model.LocalCache +import com.vitorpamplona.amethyst.model.accountsCache.AccountCacheState import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip89AppHandlers.clientTag.isClient import com.vitorpamplona.quartz.utils.Log import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -198,8 +200,19 @@ class NotificationReplyReceiver : BroadcastReceiver() { val targetEvent = LocalCache.getNoteIfExists(targetEventId)?.event ?: return val template = - when (targetEvent) { - is TextNoteEvent -> { + when { + // A brand-new Amethyst kind-1 thread root is replied to with a NIP-22 + // kind 1111 Comment instead of a kind 1 reply. + targetEvent is TextNoteEvent && + targetEvent.isNewThread() && + targetEvent.isClient(AccountCacheState.CLIENT_TAG_NAME) -> { + CommentEvent.replyBuilder( + msg = replyText, + replyingTo = EventHintBundle(targetEvent), + ) + } + + targetEvent is TextNoteEvent -> { TextNoteEvent.build( note = replyText, replyingTo = EventHintBundle(targetEvent), diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationUtils.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationUtils.kt index 27b56d05bd..1f5eb63239 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationUtils.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/NotificationUtils.kt @@ -20,12 +20,16 @@ */ package com.vitorpamplona.amethyst.service.notifications +import android.app.Notification import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.content.Context import android.content.Intent import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.RectF import android.graphics.drawable.BitmapDrawable import android.service.notification.StatusBarNotification import androidx.core.app.NotificationCompat @@ -40,6 +44,7 @@ import coil3.request.allowHardware import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.MainActivity import com.vitorpamplona.amethyst.ui.stringRes +import com.vitorpamplona.quartz.nip01Core.core.HexKey import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -221,6 +226,7 @@ object NotificationUtils { pictureUrl: String?, uri: String, applicationContext: Context, + emojiUrl: String? = null, ) { getOrCreateReactionChannel(applicationContext) val channelId = stringRes(applicationContext, R.string.app_notification_reactions_channel_id) @@ -231,6 +237,7 @@ object NotificationUtils { messageTitle = messageTitle, time = time, pictureUrl = pictureUrl, + badgeUrl = emojiUrl, uri = uri, channelId = channelId, notificationGroupKey = REACTION_GROUP_KEY, @@ -423,6 +430,36 @@ object NotificationUtils { } } + /** + * Draws the badge image (e.g. a NIP-30 custom-emoji reaction) onto the bottom-right corner + * of the base avatar. Returns the base unchanged if the badge can't be loaded, or the badge + * alone if there is no base avatar. + */ + private suspend fun overlayBadge( + base: Bitmap?, + badgeUrl: String, + applicationContext: Context, + ): Bitmap? { + val badge = loadBitmap(badgeUrl, applicationContext) ?: return base + if (base == null) return badge + + return withContext(Dispatchers.Default) { + val result = base.copy(base.config ?: Bitmap.Config.ARGB_8888, true) + val canvas = Canvas(result) + val badgeSize = minOf(result.width, result.height) * 0.45f + val dest = + RectF( + result.width - badgeSize, + result.height - badgeSize, + result.width.toFloat(), + result.height.toFloat(), + ) + val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { isFilterBitmap = true } + canvas.drawBitmap(badge, null, dest, paint) + result + } + } + private suspend fun NotificationManager.sendDMNotificationStyled( id: String, messageBody: String, @@ -625,6 +662,7 @@ object NotificationUtils { summaryText: String, applicationContext: Context, inlineReply: InlineReplyTarget? = null, + badgeUrl: String? = null, ) { val notId = id.hashCode() @@ -632,6 +670,10 @@ object NotificationUtils { val bitmap = pictureUrl?.let { loadBitmap(it, applicationContext) } + // For custom-emoji (NIP-30) reactions, the emoji is an image URL that can't render + // as text in the notification, so overlay it as a badge on the author's avatar. + val largeIcon = badgeUrl?.let { overlayBadge(bitmap, it, applicationContext) } ?: bitmap + val contentIntent = Intent(applicationContext, MainActivity::class.java).apply { data = uri.toUri() } @@ -662,7 +704,7 @@ object NotificationUtils { .setContentTitle(messageTitle) .setContentText(messageBody) .setStyle(NotificationCompat.BigTextStyle().bigText(messageBody)) - .setLargeIcon(bitmap) + .setLargeIcon(largeIcon) .setContentIntent(contentPendingIntent) .setPublicVersion(builderPublic.build()) .setPriority(NotificationCompat.PRIORITY_HIGH) @@ -751,4 +793,35 @@ object NotificationUtils { fun NotificationManager.cancelNotifications() { cancelAll() } + + /** + * Dismisses the tray notification posted for [eventId] — used to auto-clear a + * notification once the user reads the underlying event in-app. + * + * Per-event notifications are keyed by `id.hashCode()` (see [sendNotification] + * and [sendDMNotificationStyled]), so hashing the same event id targets exactly + * the notification posted for it. Cancelling an id that isn't currently shown is + * a harmless no-op. After removing the child, any group summary left without + * children is cancelled too so the tray doesn't keep an empty summary around. + */ + fun NotificationManager.dismissNotificationForEvent(eventId: HexKey) { + val notId = eventId.hashCode() + + // Most events the user reads never had a tray notification (regular feed + // items), so bail out before touching anything when nothing is posted for it. + if (activeNotifications.none { it.id == notId }) return + + cancel(notId) + cancelChildlessGroupSummaries() + } + + private fun NotificationManager.cancelChildlessGroupSummaries() { + val active = activeNotifications + for (summary in active) { + if (summary.notification.flags and Notification.FLAG_GROUP_SUMMARY == 0) continue + val group = summary.notification.group ?: continue + val hasChildren = active.any { it.id != summary.id && it.notification.group == group } + if (!hasChildren) cancel(summary.id) + } + } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/OkHttpClientFactory.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/OkHttpClientFactory.kt index b41ae1250f..88b65d845a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/OkHttpClientFactory.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/okhttp/OkHttpClientFactory.kt @@ -75,6 +75,14 @@ class OkHttpClientFactory( .connectionPool(connectionPool) .dns(dns) .eventListenerFactory(MediaCallEventListenerFactory(dispatcher, connectionPool, dns)) + // Some media hosts (e.g. blossom.primal.net) silently drop idle HTTP/2 + // connections between the bursts of a feed scroll. Without a keepalive + // ping, OkHttp can pull such a dead connection from the 5-min pool and + // the request stalls until the read timeout (30s wifi / 90s mobile), + // which shows up as "the first image after a pause takes forever". + // An HTTP/2 ping detects the dead connection in seconds and lets + // retryOnConnectionFailure re-issue the request on a fresh one. + .pingInterval(Duration.ofSeconds(HTTP2_PING_INTERVAL_SECS)) .followRedirects(true) .followSslRedirects(true) .addInterceptor(DefaultContentTypeInterceptor(userAgent)) @@ -128,4 +136,11 @@ class OkHttpClientFactory( } fun buildLocalSocksProxy(port: Int?) = Proxy(Proxy.Type.SOCKS, InetSocketAddress("127.0.0.1", port ?: DEFAULT_SOCKS_PORT)) + + companion object { + // HTTP/2 keepalive ping for pooled media connections. Short enough to + // evict a silently-dropped connection well before the read timeout would + // otherwise stall a request for the full 30s/90s. + const val HTTP2_PING_INTERVAL_SECS: Long = 10 + } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserObservers.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserObservers.kt index 30db8918c5..447b4f68d8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserObservers.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserObservers.kt @@ -150,9 +150,15 @@ fun observeUserBanner( fun observeUserPicture( user: User, accountViewModel: AccountViewModel, + subscribe: Boolean = true, ): State { // Subscribe in the relay for changes in the metadata of this user. - UserFinderFilterAssemblerSubscription(user, accountViewModel) + // Callers that already hold a single shared subscription for the same user + // (e.g. an author avatar that also observes the contact-card score) can pass + // subscribe = false to avoid setting up a redundant relay subscription. + if (subscribe) { + UserFinderFilterAssemblerSubscription(user, accountViewModel) + } // Subscribe in the LocalCache for changes that arrive in the device val flow = @@ -476,9 +482,14 @@ fun observeUserIsFollowingChannel( fun observeUserContactCardsScore( user: User, accountViewModel: AccountViewModel, + subscribe: Boolean = true, ): State { // Subscribe in the relay for changes in the metadata of this user. - UserFinderFilterAssemblerSubscription(user, accountViewModel) + // See observeUserPicture: pass subscribe = false when a shared subscription + // for the same user already exists. + if (subscribe) { + UserFinderFilterAssemblerSubscription(user, accountViewModel) + } // Subscribe in the LocalCache for changes that arrive in the device val flow = remember(user) { user.cards().rankFlow(accountViewModel.account.trustProviderList) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/FeedContentStateView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/FeedContentStateView.kt index abf9751322..61e00c0aa5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/FeedContentStateView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/FeedContentStateView.kt @@ -109,7 +109,10 @@ fun RenderFeedContentState( when (state) { is FeedState.Empty -> onEmpty() is FeedState.FeedError -> onError(state.errorMessage) - is FeedState.Loaded -> onLoaded(state) + is FeedState.Loaded -> { + PrefetchLoadedFeedMedia(state, listState, accountViewModel) + onLoaded(state) + } is FeedState.Loading -> onLoading() } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/PrefetchFeedMedia.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/PrefetchFeedMedia.kt new file mode 100644 index 0000000000..27d1601cf0 --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/PrefetchFeedMedia.kt @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.ui.feeds + +import android.content.Context +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.grid.LazyGridState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.snapshotFlow +import androidx.compose.ui.platform.LocalContext +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import coil3.imageLoader +import coil3.request.ImageRequest +import coil3.request.SuccessResult +import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists +import com.vitorpamplona.amethyst.commons.richtext.MediaUrlImage +import com.vitorpamplona.amethyst.commons.richtext.MediaUrlVideo +import com.vitorpamplona.amethyst.commons.richtext.RichTextParser +import com.vitorpamplona.amethyst.commons.richtext.RichTextViewerState +import com.vitorpamplona.amethyst.commons.richtext.UrlParser +import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState +import com.vitorpamplona.amethyst.model.MediaAspectRatioCache +import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.model.UrlCachedPreviewer +import com.vitorpamplona.amethyst.service.CachedRichTextParser +import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip14Subject.subject +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip71Video.image +import com.vitorpamplona.quartz.nip92IMeta.IMetaTag +import com.vitorpamplona.quartz.nip92IMeta.imetas +import com.vitorpamplona.quartz.nip94FileMetadata.tags.MimeTypeTag +import com.vitorpamplona.quartz.nip94FileMetadata.tags.UrlTag +import kotlinx.collections.immutable.ImmutableList +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.withContext +import java.util.concurrent.ConcurrentHashMap + +/** How many notes on each side of the viewport to warm. */ +private const val PREFETCH_RADIUS = 3 + +private const val MIME_TYPE_KEY = "m" + +private const val DIM_KEY = "dim" + +/** + * Warms the feed notes just outside the viewport — on **both** sides, so scrolling + * either direction is covered — off the main thread, so they are ready by the time + * the user reaches them. For each note [warm] does three things: + * + * 1. **Pre-parses** the rich-text body into [CachedRichTextParser]'s shared cache + * using the exact same key the renderer will use, so the scroll-time + * composition becomes a cache hit instead of parsing on the UI thread. This is + * only possible for kinds whose render key we can reproduce (text notes and + * comments); other kinds still get their media/links prefetched (below), just + * without the render-cache warm. + * 2. **Prefetches images** — inline content images and video poster frames, from + * both NIP-92 imeta tags (every kind) and the body — into Coil's cache (gated + * on [AccountViewModel] `showImages()`), recording each decoded aspect ratio so + * the composable reserves the right space on first layout (no jump). + * 3. **Warms OpenGraph/link previews** for non-media URLs via [UrlCachedPreviewer] + * (gated on `showUrlPreview()`), so link cards render instantly. + * + * A `warmed` set keeps back-and-forth scrolling cheap: a note already processed is + * skipped entirely. `collectLatest` also cancels a stale pass as soon as the + * visible range changes. The only main-thread cost is reading the visible item + * keys in the snapshot flow. + * + * Video *bytes* are deliberately not prefetched — they are large, often HLS + * (whose prefix can't be cleanly pre-cached), and the player pool already starts + * fast once a video is on screen. Warming the poster covers the visible card. + */ +@Composable +fun PrefetchFeedMedia( + listState: LazyListState, + notes: ImmutableList, + accountViewModel: AccountViewModel, + radius: Int = PREFETCH_RADIUS, +) { + val visibleEnds = remember(listState) { listState.visibleEnds() } + PrefetchVisibleMedia(listState, visibleEnds, notes, accountViewModel, radius) +} + +/** Grid variant: identical behavior, driven by a [LazyGridState] (galleries, discover, products). */ +@Composable +fun PrefetchFeedMedia( + gridState: LazyGridState, + notes: ImmutableList, + accountViewModel: AccountViewModel, + radius: Int = PREFETCH_RADIUS, +) { + val visibleEnds = remember(gridState) { gridState.visibleEnds() } + PrefetchVisibleMedia(gridState, visibleEnds, notes, accountViewModel, radius) +} + +@Composable +private fun PrefetchVisibleMedia( + stateKey: Any, + visibleEnds: Flow, + notes: ImmutableList, + accountViewModel: AccountViewModel, + radius: Int, +) { + val context = LocalContext.current + val currentNotes by rememberUpdatedState(notes) + val warmed = remember(stateKey) { ConcurrentHashMap.newKeySet() } + + LaunchedEffect(stateKey, accountViewModel) { + visibleEnds.collectLatest { ends -> + withContext(Dispatchers.Default) { + currentNotes.notesAround(ends, radius).forEach { note -> + if (note.idHex !in warmed) { + note.warm(context, accountViewModel) + warmed.add(note.idHex) + } + } + } + } + } +} + +/** + * Prefetches media for a loaded feed. The shared entry point used by the feed + * dispatchers (`RenderFeedContentState` and `RenderFeedState`), so every list feed + * that routes through them gets prefetching without per-screen wiring. + */ +@Composable +fun PrefetchLoadedFeedMedia( + loaded: FeedState.Loaded, + listState: LazyListState, + accountViewModel: AccountViewModel, +) { + val items by loaded.feed.collectAsStateWithLifecycle() + PrefetchFeedMedia(listState, items.list, accountViewModel) +} + +/** Grid variant of [PrefetchLoadedFeedMedia] for [LazyGridState]-backed feeds. */ +@Composable +fun PrefetchLoadedFeedMedia( + loaded: FeedState.Loaded, + gridState: LazyGridState, + accountViewModel: AccountViewModel, +) { + val items by loaded.feed.collectAsStateWithLifecycle() + PrefetchFeedMedia(gridState, items.list, accountViewModel) +} + +/** The keys (note `idHex`) of the first and last visible feed items. */ +private data class VisibleEnds( + val firstKey: String?, + val lastKey: String?, +) + +/** Emits the visible range ends, once per change. */ +private fun LazyListState.visibleEnds(): Flow = + snapshotFlow { + val visible = layoutInfo.visibleItemsInfo + VisibleEnds(visible.firstOrNull()?.key as? String, visible.lastOrNull()?.key as? String) + }.distinctUntilChanged() + +/** Grid equivalent of [visibleEnds]. */ +private fun LazyGridState.visibleEnds(): Flow = + snapshotFlow { + val visible = layoutInfo.visibleItemsInfo + VisibleEnds(visible.firstOrNull()?.key as? String, visible.lastOrNull()?.key as? String) + }.distinctUntilChanged() + +/** Up to [radius] notes immediately before the first visible and after the last visible. */ +private fun List.notesAround( + ends: VisibleEnds, + radius: Int, +): List = notesBefore(ends.firstKey, radius) + notesAfter(ends.lastKey, radius) + +private fun List.notesBefore( + key: String?, + count: Int, +): List { + val idx = key?.let { k -> indexOfFirst { it.idHex == k } } ?: -1 + if (idx <= 0) return emptyList() + return subList(maxOf(0, idx - count), idx) +} + +private fun List.notesAfter( + key: String?, + count: Int, +): List { + val idx = key?.let { k -> indexOfFirst { it.idHex == k } } ?: -1 + if (idx < 0) return emptyList() + return subList(minOf(idx + 1, size), minOf(idx + 1 + count, size)) +} + +/** Prefetches this note's media into Coil and warms its link previews, honoring the data-saver gates. */ +private fun Note.warm( + context: Context, + accountViewModel: AccountViewModel, +) { + val targets = collectWarmTargets() ?: return + + if (accountViewModel.settings.showImages()) { + targets.forEachImage(context::prefetchImage) + } + if (accountViewModel.settings.showUrlPreview()) { + targets.links.forEach { url -> + if (UrlCachedPreviewer.cache.get(url) == null) { + accountViewModel.urlPreview(url) {} + } + } + } +} + +/** The set of URLs worth warming ahead of a note scrolling into view. */ +private class WarmTargets { + // image URL -> a video URL whose layout box should also be seeded from this + // image's (poster's) decoded aspect ratio, or null for a plain image. + private val images = LinkedHashMap() + val links = LinkedHashSet() + + fun image(url: String) { + images.putIfAbsent(url, null) + } + + /** A video poster: warmed as an image, and its decoded ratio also seeds [videoUrl]'s box (if non-null). */ + fun videoPoster( + posterUrl: String, + videoUrl: String?, + ) { + // Never downgrade an existing video association back to null. + images[posterUrl] = videoUrl ?: images[posterUrl] + } + + fun link(url: String) { + links.add(url) + } + + fun forEachImage(action: (url: String, videoUrlForDims: String?) -> Unit) { + images.forEach { (url, videoUrl) -> action(url, videoUrl) } + } + + /** Harvest media and links from a fully parsed rich-text body. */ + fun harvest(state: RichTextViewerState) { + state.mediaList.forEach { media -> + when (media) { + is MediaUrlImage -> image(media.url) + is MediaUrlVideo -> + media.artworkUri?.let { poster -> + videoPoster(poster, media.url.takeIf { media.dim == null }) + } + } + } + state.urlSet.withScheme.forEach { url -> + if (!RichTextParser.isImageOrVideoUrl(url)) link(url) + } + } + + /** + * Lightweight discovery for kinds we don't render-warm: pull http(s) URLs from + * the body and classify them by extension. A bare content video has no poster + * we can cheaply warm, so it is skipped. + */ + fun harvestContentUrls(content: String) { + UrlParser().parseValidUrls(content).withScheme.forEach { url -> + when { + RichTextParser.isImageUrl(url) -> image(url) + RichTextParser.isVideoUrl(url) -> Unit + else -> link(url) + } + } + } + + /** + * Adds NIP-94 file-header media: blobs declared as top-level `url` tags (not + * imeta), as used by FileHeaderEvent and the gallery/file kinds. Only image + * files are prefetched — detected by the URL extension or the event's top-level + * `m` mime type (a hashed URL may carry no extension). The decode listener + * records their dims like any other image. + */ + fun addFileHeaderMedia(event: Event) { + val urls = event.tags.mapNotNull(UrlTag::parse) + if (urls.isEmpty()) return + val imageMime = event.tags.firstNotNullOfOrNull(MimeTypeTag::parse)?.startsWith("image/") == true + urls.forEach { url -> + if (imageMime || RichTextParser.isImageUrl(url)) image(url) + } + } +} + +/** + * Collects everything worth warming for this note. Reads NIP-92 imeta tags (every + * kind), then the free-text body: text notes and comments go through the shared + * render cache — which both warms the renderer and yields a fully classified body + * — while every other kind gets a cheap URL scan. Returns null only when the note + * has no event. + */ +private fun Note.collectWarmTargets(): WarmTargets? { + val ev = event ?: return null + val targets = WarmTargets() + + // Structured media declared in NIP-92 imeta tags (text-note attachments, and the + // kinds whose typed accessors wrap imetas() — Picture, Video). Video imeta carries + // its poster in the `image` field. + ev.tags.imetas().forEach { meta -> + if (meta.isImage()) targets.image(meta.url) + meta.image()?.forEach { poster -> targets.videoPoster(poster, meta.videoUrlForPosterDims()) } + } + + // NIP-94 file-header convention: the blob is a top-level `url` tag with sibling + // `m`/`dim`, not imeta (FileHeaderEvent and the gallery/file kinds). The generic + // imetas() above misses these entirely. + targets.addFileHeaderMedia(ev) + + // Free-text body. The reproducible-key kinds parse through the shared cache + // (which also warms the render); everything else is scanned for URLs only. + val rendered = warmRenderCache(ev) + if (rendered != null) { + targets.harvest(rendered) + } else { + targets.harvestContentUrls(ev.content) + } + + return targets +} + +/** + * Parses the body through [CachedRichTextParser] so the result lands in the exact + * entry the composition later looks up — turning the scroll-time parse into a cache + * hit. Returns the parsed state, or null when we can't reproduce the renderer's key. + * + * Deliberately limited to text notes and comments. The cache key is + * `(content, tags, callbackUri, authorPubKey)`, and each renderer passes its own + * shape: Picture uses `EmptyTagList`, Highlight uses `EmptyTagList` + `null` + * callbackUri, Video/Poll/Git pass derived content vars, etc. We can only reproduce + * the key for these two kinds (verified to hit at runtime). Parsing the others with + * a guessed key would miss at render time *and* pollute this shared cache with dead + * entries — evicting the text-note entries that do hit — so it would be a net loss. + * Their media and links are still prefetched via [WarmTargets.harvestContentUrls]. + */ +private fun Note.warmRenderCache(ev: Event): RichTextViewerState? { + val body = + when (ev) { + is TextNoteEvent -> { + // Matches RenderTextEvent: a subject is prepended when not already in the body. + val subject = ev.subject()?.ifBlank { null } + if (subject != null && !ev.content.contains(subject, ignoreCase = true)) { + "$subject\n\n${ev.content}" + } else { + ev.content + } + } + is CommentEvent -> ev.content + else -> return null + } + + val tags = ev.tags.toImmutableListOfLists() + // callbackUri = note.toNostrUri(), authorPubKey = null — the values the feed passes. + return CachedRichTextParser.parseText(body, tags, toNostrUri(), null) +} + +/** Enqueues an image prefetch that also records its decoded aspect ratio. */ +private fun Context.prefetchImage( + url: String, + videoUrlForDims: String?, +) { + runCatching { + imageLoader.enqueue( + ImageRequest + .Builder(this) + .data(url) + .listener(CaptureAspectRatio(url, videoUrlForDims)) + .build(), + ) + } +} + +/** + * Records the decoded aspect ratio of a prefetched image so the composable can + * reserve the right space on first layout (no jump) even when the note carries no + * imeta `dim` — the renderer reads `MediaAspectRatioCache.get(url)` as its + * fallback. We decode for the cache warm anyway, so this is essentially free. + * + * For a video poster, [videoUrlForDims] is the video URL; its box is seeded from + * the poster's ratio (a poster is a frame of the video), but only when nothing is + * cached yet, so we never stomp a real ratio. ExoPlayer's onVideoSizeChanged + * corrects it to the exact size once the video plays. + */ +private class CaptureAspectRatio( + private val imageUrl: String, + private val videoUrlForDims: String?, +) : ImageRequest.Listener { + override fun onSuccess( + request: ImageRequest, + result: SuccessResult, + ) { + val w = result.image.width + val h = result.image.height + MediaAspectRatioCache.add(imageUrl, w, h) + if (videoUrlForDims != null && MediaAspectRatioCache.get(videoUrlForDims) == null) { + MediaAspectRatioCache.add(videoUrlForDims, w, h) + } + } +} + +/** The video URL this imeta's poster should seed dims for, or null when the video declares its own dim. */ +private fun IMetaTag.videoUrlForPosterDims(): String? = url.takeIf { properties[DIM_KEY].isNullOrEmpty() } + +/** + * True only for image blobs. A missing mime type falls back to the URL extension; + * we never treat video imeta as an image (its poster is warmed separately). + */ +private fun IMetaTag.isImage(): Boolean { + val mimeType = properties[MIME_TYPE_KEY]?.firstOrNull() + return mimeType?.startsWith("image/") ?: RichTextParser.isImageUrl(url) +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarNestedScroll.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarNestedScroll.kt index e49922f349..7e81278143 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarNestedScroll.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarNestedScroll.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.NestedScrollConnection import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.unit.Velocity +import kotlin.math.abs /** * Scroll-linked connection that hides/reveals the top and bottom bars together. @@ -43,10 +44,16 @@ import androidx.compose.ui.unit.Velocity * - onPostFling snaps a mid-way bar to the nearest edge, using the fling's remaining * velocity as the spring's initial velocity so the settle feels continuous. No velocity * is returned upward to avoid phantom scrolls on parent containers. - * - Hiding tracks the finger 1:1, but revealing is damped by [REVEAL_SENSITIVITY]. Once the - * bars are hidden, the small reverse drag a finger naturally makes when it catches/stops a - * fast scroll would otherwise be enough to snap the chrome (and the OS status bar) back. - * Damping the reveal direction makes bringing the bars back a more deliberate gesture. + * - Both hiding and revealing track the finger 1:1. The bar offset must equal the content's + * scroll offset so the bar's bottom edge stays glued to the first item's top edge; any + * asymmetry (e.g. a damped reveal) leaves the bar lagging behind the content and opens a + * blank band between the bar and the first item when the list returns to the top. + * + * Making the reveal a *deliberate* gesture — so the tiny reverse drag a finger makes when it + * catches/stops a fast scroll doesn't pop the chrome back — is handled without breaking that + * 1:1 invariant: a partial reveal that doesn't cross the halfway point is snapped back to the + * hidden edge by [DisappearingBarState.settleToNearestEdge] on fling/lift, and the binary OS + * status bar is debounced by the show/hide hysteresis in the scaffold. */ class DisappearingBarNestedScroll( private val state: DisappearingBarState, @@ -60,7 +67,10 @@ class DisappearingBarNestedScroll( ): Offset { if (!canScroll()) return Offset.Zero val totalY = consumed.y + available.y - if (totalY == 0f) return Offset.Zero + // Dead-zone: ignore sub-pixel jitter so the bars (and the binary status-bar toggle that + // tracks their collapse fraction) don't twitch on scroll noise. Kept symmetric and tiny so + // it never makes the reveal lag the content enough to open a visible gap. + if (abs(totalY) < MIN_SCROLL_DELTA) return Offset.Zero // If the list did not consume any scroll and the bars are fully visible, treat // this as a non-scrollable list and keep the bars in place. Without this, a tiny @@ -90,19 +100,18 @@ class DisappearingBarNestedScroll( private fun applyDelta(deltaY: Float) { val topLimit = state.topHeightLimit val bottomLimit = state.bottomHeightLimit - // Positive delta reveals the bars; negative delta hides them. Hiding stays 1:1 with the - // finger, while revealing is damped so a stray reverse drag doesn't bring the chrome back. - val effectiveDelta = if (deltaY > 0f) deltaY * REVEAL_SENSITIVITY else deltaY - state.topHeightOffset = (state.topHeightOffset + effectiveDelta).coerceIn(-topLimit, 0f) - state.bottomHeightOffset = (state.bottomHeightOffset + effectiveDelta).coerceIn(-bottomLimit, 0f) + // 1:1 in both directions: the bar offset mirrors the content scroll so the bar stays glued + // to the first item. Deliberate reveal is enforced on settle, not by damping the delta here. + state.topHeightOffset = (state.topHeightOffset + deltaY).coerceIn(-topLimit, 0f) + state.bottomHeightOffset = (state.bottomHeightOffset + deltaY).coerceIn(-bottomLimit, 0f) } companion object { /** - * Fraction of scroll distance applied when revealing the bars (1.0 = same rate as hiding). - * Lower values require a more deliberate downward scroll to bring the chrome back, so the - * tiny reverse movement of a finger stopping a fast scroll no longer pops the bars open. + * Sub-pixel dead-zone: scroll attempts smaller than this are ignored so jitter doesn't nudge + * the bars. Tiny on purpose — large enough to swallow fractional noise, small enough that the + * bar offset never measurably lags the content scroll. */ - const val REVEAL_SENSITIVITY = 0.5f + const val MIN_SCROLL_DELTA = 0.5f } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarState.kt index 8d743246db..13cddbc185 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarState.kt @@ -46,8 +46,46 @@ class DisappearingBarState( initialTopHeightOffset: Float = 0f, initialBottomHeightOffset: Float = 0f, ) { - var topHeightOffset by mutableFloatStateOf(initialTopHeightOffset) - var bottomHeightOffset by mutableFloatStateOf(initialBottomHeightOffset) + private var _topHeightOffset by mutableFloatStateOf(initialTopHeightOffset) + private var _bottomHeightOffset by mutableFloatStateOf(initialBottomHeightOffset) + + /** + * Latches that record whether each bar has been driven all the way to its hidden edge by real + * scrolling since it was last fully in view. The settle reads them to tell a deliberate hide — + * where the content has scrolled at least a full bar height, so snapping the bar fully hidden + * leaves content (not a blank band) in the slot it vacates — apart from a small near-top + * collapse, where snapping hidden would expose the background because the content hasn't + * scrolled far enough to fill the bar's slot. + */ + private var topReachedHiddenEdge = false + private var bottomReachedHiddenEdge = false + + var topHeightOffset: Float + get() = _topHeightOffset + set(value) { + _topHeightOffset = value + updateLatch(value, topHeightLimit) { topReachedHiddenEdge = it } + } + + var bottomHeightOffset: Float + get() = _bottomHeightOffset + set(value) { + _bottomHeightOffset = value + updateLatch(value, bottomHeightLimit) { bottomReachedHiddenEdge = it } + } + + private inline fun updateLatch( + offset: Float, + limit: Float, + set: (Boolean) -> Unit, + ) { + if (limit <= 0f) return + if (offset >= 0f) { + set(false) + } else if (offset <= -limit) { + set(true) + } + } var topHeightLimit: Float = 0f set(value) { @@ -76,8 +114,8 @@ class DisappearingBarState( */ suspend fun settleToNearestEdge(initialVelocityY: Float = 0f) { coroutineScope { - launch { settleOne({ topHeightOffset }, topHeightLimit, initialVelocityY) { topHeightOffset = it } } - launch { settleOne({ bottomHeightOffset }, bottomHeightLimit, initialVelocityY) { bottomHeightOffset = it } } + launch { settleOne({ topHeightOffset }, topHeightLimit, topReachedHiddenEdge, initialVelocityY) { topHeightOffset = it } } + launch { settleOne({ bottomHeightOffset }, bottomHeightLimit, bottomReachedHiddenEdge, initialVelocityY) { bottomHeightOffset = it } } } } @@ -94,6 +132,7 @@ class DisappearingBarState( private suspend fun settleOne( get: () -> Float, limit: Float, + canFullyHide: Boolean, initialVelocityY: Float, set: (Float) -> Unit, ) { @@ -105,6 +144,11 @@ class DisappearingBarState( val positionBiasToHide = -current > limit / 2f val target = when { + // Snapping to the hidden edge is only safe once the bar has actually been scrolled + // there (canFullyHide): the content has then moved at least a full bar height and + // fills the slot the bar vacates. From a small near-top collapse it hasn't, so + // snapping hidden would open a blank band — settle back into view instead. + !canFullyHide -> 0f initialVelocityY < -VELOCITY_BIAS_THRESHOLD -> -limit initialVelocityY > VELOCITY_BIAS_THRESHOLD -> 0f positionBiasToHide -> -limit @@ -142,10 +186,14 @@ class DisappearingBarState( companion object { private const val VELOCITY_BIAS_THRESHOLD = 200f + // Bounce-free so the chrome never wobbles past its edge, but stiff enough to feel like a + // quick native snap rather than a slow float once the finger lifts. Overshoot from a strong + // initial velocity is still caught by the bounds in animateOne, so a higher stiffness here + // only affects how briskly the bar resolves to its edge. private val SETTLE_SPRING = spring( dampingRatio = Spring.DampingRatioNoBouncy, - stiffness = Spring.StiffnessMediumLow, + stiffness = Spring.StiffnessMedium, ) val Saver: Saver = diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/AuthorGalleryRenderContext.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/AuthorGalleryRenderContext.kt new file mode 100644 index 0000000000..702d846009 --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/AuthorGalleryRenderContext.kt @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.ui.note + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.compositionLocalOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel + +/** + * The notification galleries (reactions, zaps, nutzaps, boosts) render up to 30 + * author avatars each. A couple of the inputs to every avatar are *account-global* + * — the auto-play-gif setting and the logged-in user's follow set — yet the avatar + * code used to collect each of them **once per author**. With dozens of authors per + * card that produced dozens of redundant Flow collectors / coroutine launches every + * time a card scrolled into view, a measurable chunk of the per-card composition cost. + * + * Hoisting those reads to a single collection per gallery and handing the snapshot + * down through [LocalAuthorGalleryRenderContext] lets each avatar read plain values + * and stay skippable. When the local is absent the avatar falls back to its old + * per-author behaviour, so callers that don't provide a context keep working. + */ +@Immutable +class AuthorGalleryRenderContext( + val autoPlayGif: Boolean, + val follows: Set, +) + +val LocalAuthorGalleryRenderContext = compositionLocalOf { null } + +/** + * Collects the account-global render inputs a single time. Provide the result via + * [LocalAuthorGalleryRenderContext] around a gallery's author list. + */ +@Composable +fun rememberAuthorGalleryRenderContext(accountViewModel: AccountViewModel): AuthorGalleryRenderContext { + val autoPlayGif by accountViewModel.settings.autoPlayVideosFlow.collectAsStateWithLifecycle() + val follows by accountViewModel.account.allFollows.flow + .collectAsStateWithLifecycle() + + val followAuthors = follows.authors + return remember(autoPlayGif, followAuthors) { + AuthorGalleryRenderContext(autoPlayGif, followAuthors) + } +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt index cc1e97ba06..672ce202f6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt @@ -40,6 +40,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.Immutable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState @@ -72,6 +73,7 @@ import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.NoteState import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.CachedRichTextParser +import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinderFilterAssemblerSubscription import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserContactCardsScore import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserPicture import com.vitorpamplona.amethyst.ui.components.AnimatedBorderTextCornerRadius @@ -463,8 +465,12 @@ fun AuthorGalleryZaps( nav: INav, accountViewModel: AccountViewModel, ) { - Column(modifier = StdStartPadding) { - FlowRow { authorNotes.forEach { RenderState(it, backgroundColor, accountViewModel, nav) } } + CompositionLocalProvider( + LocalAuthorGalleryRenderContext provides rememberAuthorGalleryRenderContext(accountViewModel), + ) { + Column(modifier = StdStartPadding) { + FlowRow { authorNotes.forEach { RenderState(it, backgroundColor, accountViewModel, nav) } } + } } } @@ -631,8 +637,12 @@ fun AuthorGallery( accountViewModel: AccountViewModel, clickRoute: (Note) -> Route? = ::authorRouteFor, ) { - Column(modifier = StdStartPadding) { - FlowRow { authorNotes.forEach { note -> BoxedAuthor(note, nav, accountViewModel, clickRoute) } } + CompositionLocalProvider( + LocalAuthorGalleryRenderContext provides rememberAuthorGalleryRenderContext(accountViewModel), + ) { + Column(modifier = StdStartPadding) { + FlowRow { authorNotes.forEach { note -> BoxedAuthor(note, nav, accountViewModel, clickRoute) } } + } } } @@ -643,9 +653,13 @@ fun AuthorGallery( nav: INav, accountViewModel: AccountViewModel, ) { - Column(modifier = StdStartPadding) { - FlowRow { - noteToGetBoostEvents.note.boosts.forEach { note -> BoxedAuthor(note, nav, accountViewModel) } + CompositionLocalProvider( + LocalAuthorGalleryRenderContext provides rememberAuthorGalleryRenderContext(accountViewModel), + ) { + Column(modifier = StdStartPadding) { + FlowRow { + noteToGetBoostEvents.note.boosts.forEach { note -> BoxedAuthor(note, nav, accountViewModel) } + } } } } @@ -684,7 +698,27 @@ fun WatchUserMetadataAndFollowsAndRenderUserProfilePicture( author: User, accountViewModel: AccountViewModel, ) { - WatchUserMetadata(author, accountViewModel) { baseUserPicture -> + // When rendered inside a gallery, the account-global auto-play and follow-set + // reads are hoisted to a single collection for the whole gallery (see + // [rememberAuthorGalleryRenderContext]). Falls back to per-author collection + // for callers that don't provide a context. + val galleryContext = LocalAuthorGalleryRenderContext.current + + // One shared relay subscription per author. The profile picture and the + // contact-card score below both fetch the same kind-0 metadata, so we + // subscribe once here and let them skip their own (formerly duplicate) one. + UserFinderFilterAssemblerSubscription(author, accountViewModel) + + WatchUserMetadata(author, accountViewModel, subscribe = false) { baseUserPicture -> + val autoPlayGif = + if (galleryContext != null) { + galleryContext.autoPlayGif + } else { + accountViewModel.settings.autoPlayVideosFlow + .collectAsStateWithLifecycle() + .value + } + RobohashFallbackAsyncImage( robot = author.pubkeyHex, model = baseUserPicture, @@ -693,30 +727,39 @@ fun WatchUserMetadataAndFollowsAndRenderUserProfilePicture( contentScale = ContentScale.Crop, loadProfilePicture = accountViewModel.settings.showProfilePictures(), loadRobohash = accountViewModel.settings.isNotPerformanceMode(), - autoPlayGif = - accountViewModel.settings.autoPlayVideosFlow - .collectAsStateWithLifecycle() - .value, + autoPlayGif = autoPlayGif, ) } - WatchUserFollows(author.pubkeyHex, accountViewModel) { isFollowing -> + if (galleryContext != null) { + val isFollowing = + accountViewModel.isLoggedUser(author.pubkeyHex) || + author.pubkeyHex in galleryContext.follows if (isFollowing) { Box(modifier = Size35Modifier, contentAlignment = Alignment.TopEnd) { FollowingIcon(Size10Modifier) } } + } else { + WatchUserFollows(author.pubkeyHex, accountViewModel) { isFollowing -> + if (isFollowing) { + Box(modifier = Size35Modifier, contentAlignment = Alignment.TopEnd) { + FollowingIcon(Size10Modifier) + } + } + } } - ObserveAndRenderBoxedUserCards(author, accountViewModel) + ObserveAndRenderBoxedUserCards(author, accountViewModel, subscribe = false) } @Composable fun ObserveAndRenderBoxedUserCards( user: User, accountViewModel: AccountViewModel, + subscribe: Boolean = true, ) { - val score by observeUserContactCardsScore(user, accountViewModel) + val score by observeUserContactCardsScore(user, accountViewModel, subscribe) score?.let { Box(modifier = Size35Modifier, contentAlignment = Alignment.BottomCenter) { @@ -729,9 +772,10 @@ fun ObserveAndRenderBoxedUserCards( private fun WatchUserMetadata( author: User, accountViewModel: AccountViewModel, + subscribe: Boolean = true, onNewMetadata: @Composable (String?) -> Unit, ) { - val userProfile by observeUserPicture(author, accountViewModel) + val userProfile by observeUserPicture(author, accountViewModel, subscribe) onNewMetadata(userProfile) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index 4c452624ba..1579dae613 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -196,6 +196,7 @@ import com.vitorpamplona.amethyst.ui.note.types.observeZapSender import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.types.RenderChatClip import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.nip28PublicChat.RenderPublicChatChannelHeader +import com.vitorpamplona.amethyst.ui.screen.loggedIn.workouts.ExerciseTemplateDisplay import com.vitorpamplona.amethyst.ui.screen.loggedIn.workouts.WorkoutDisplay import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer @@ -228,6 +229,7 @@ import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent import com.vitorpamplona.quartz.experimental.birdstar.BirdexEvent import com.vitorpamplona.quartz.experimental.bounties.bountyBaseReward import com.vitorpamplona.quartz.experimental.edits.TextNoteModificationEvent +import com.vitorpamplona.quartz.experimental.fitness.workout.ExerciseTemplateEvent import com.vitorpamplona.quartz.experimental.fitness.workout.WorkoutRecordEvent import com.vitorpamplona.quartz.experimental.forks.IForkableEvent import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryBaseEvent @@ -242,6 +244,7 @@ import com.vitorpamplona.quartz.experimental.nipsOnNostr.NipTextEvent import com.vitorpamplona.quartz.experimental.roadstr.confirmation.RoadEventConfirmationEvent import com.vitorpamplona.quartz.experimental.roadstr.report.RoadEventReportEvent import com.vitorpamplona.quartz.experimental.zapPolls.ZapPollEvent +import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.tags.geohash.geoHashOrScope import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent @@ -532,6 +535,7 @@ fun calculateBackgroundColor( routeForLastRead: String? = null, parentBackgroundColor: MutableState? = null, accountViewModel: AccountViewModel, + dismissNotificationId: HexKey? = null, ): MutableState { val defaultBackgroundColor = MaterialTheme.colorScheme.background val newItemColor = MaterialTheme.colorScheme.newItemBackgroundColor @@ -544,7 +548,7 @@ fun calculateBackgroundColor( val isNew = remember(createdAt, routeForLastRead) { - routeForLastRead != null && accountViewModel.loadAndMarkAsRead(routeForLastRead, createdAt) + routeForLastRead != null && accountViewModel.loadAndMarkAsRead(routeForLastRead, createdAt, dismissNotificationId) } val bgColor = @@ -593,6 +597,7 @@ private fun CheckNewAndRenderNote( routeForLastRead, parentBackgroundColor, accountViewModel, + dismissNotificationId = baseNote.idHex, ) InnerNoteWithReactions( @@ -1417,6 +1422,10 @@ private fun RenderNoteRow( WorkoutDisplay(baseNote, backgroundColor, canPreview, quotesLeft, accountViewModel, nav) } + is ExerciseTemplateEvent -> { + ExerciseTemplateDisplay(baseNote, backgroundColor, canPreview, quotesLeft, accountViewModel, nav) + } + is BaseVoiceEvent -> { RenderVoiceTrack(baseNote, accountViewModel, nav) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt index 35ddc2ed2d..9ae6954ce8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt @@ -21,7 +21,6 @@ package com.vitorpamplona.amethyst.ui.note import android.content.Context -import android.content.Intent import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedContentTransitionScope import androidx.compose.animation.AnimatedVisibility @@ -148,6 +147,7 @@ import com.vitorpamplona.amethyst.ui.components.toasts.multiline.UserBasedErrorM import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.routes.routeReplyTo +import com.vitorpamplona.amethyst.ui.note.elements.ShareOptionsBottomSheet import com.vitorpamplona.amethyst.ui.note.types.EditState import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.header.PaymentTargetsDialog @@ -318,6 +318,7 @@ private fun InnerReactionRow( if (!isPrivateRumor) { ShareReaction( note = baseNote, + nav = nav, grayTint = MaterialTheme.colorScheme.placeholderText, ) } @@ -338,38 +339,26 @@ private fun InnerReactionRow( @Composable fun ShareReaction( note: Note, + nav: INav, grayTint: Color, barChartModifier: Modifier = Size19Modifier, ) { - val context = LocalContext.current + var showShareSheet by remember { mutableStateOf(false) } ClickableBox( modifier = barChartModifier, - onClick = { - val sendIntent = - Intent().apply { - action = Intent.ACTION_SEND - type = "text/plain" - putExtra( - Intent.EXTRA_TEXT, - externalLinkForNote(note), - ) - putExtra( - Intent.EXTRA_TITLE, - stringRes(context, R.string.quick_action_share_browser_link), - ) - } - - val shareIntent = - Intent.createChooser( - sendIntent, - stringRes(context, R.string.quick_action_share), - ) - context.startActivity(shareIntent) - }, + onClick = { showShareSheet = true }, ) { ShareIcon(barChartModifier, grayTint) } + + if (showShareSheet) { + ShareOptionsBottomSheet( + note = note, + nav = nav, + onDismiss = { showShareSheet = false }, + ) + } } @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapPollNote.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapPollNote.kt index a16430e086..31e85dfb4c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapPollNote.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapPollNote.kt @@ -104,7 +104,6 @@ import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.ripple24dp import com.vitorpamplona.amethyst.ui.theme.subtleBorder import com.vitorpamplona.quartz.experimental.zapPolls.ZapPollEvent -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.Dispatchers @@ -204,7 +203,6 @@ fun ZapZapPollNotePreview2() { arrayOf("poll_option", "1", "Pesquisa em ingles"), arrayOf("value_maximum", "2"), arrayOf("value_minimum", "2"), - AltTag.assemble("Poll event"), ), ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt index 20af25f5f1..892b1f72c6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt @@ -20,7 +20,6 @@ */ package com.vitorpamplona.amethyst.ui.note.elements -import android.content.Intent import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.runtime.State @@ -30,7 +29,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalClipboard -import androidx.compose.ui.platform.LocalContext import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols @@ -47,7 +45,6 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.routes.routeEditDraftTo import com.vitorpamplona.amethyst.ui.note.VerticalDotsIcon -import com.vitorpamplona.amethyst.ui.note.externalLinkForNote import com.vitorpamplona.amethyst.ui.note.types.EditState import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.report.ReportNoteDialog @@ -116,6 +113,23 @@ fun NoteDropDownMenu( ) { var reportDialogShowing by remember { mutableStateOf(false) } var addLabelDialogShowing by remember { mutableStateOf(false) } + var showShareSheet by remember { mutableStateOf(false) } + + // Tapping "Share" hands the note's share options off to the shared Share + // drawer (ShareOptionsBottomSheet). We render it INSTEAD of the menu dialog + // — not on top of it — so the menu doesn't sit dimmed behind the sheet; + // dismissing the drawer closes the whole menu. + if (showShareSheet) { + ShareOptionsBottomSheet( + note = note, + nav = nav, + onDismiss = { + showShareSheet = false + onDismiss() + }, + ) + return + } val state by observeBookmarksFollowsAndAccount(note, accountViewModel).collectAsStateWithLifecycle( DropDownParams( @@ -158,7 +172,6 @@ fun NoteDropDownMenu( onDismiss = onDismiss, ) { val clipboardManager = LocalClipboard.current - val actContext = LocalContext.current val scope = rememberCoroutineScope() // Unsealed rumors (private replies/posts received in gift wraps) are @@ -189,7 +202,8 @@ fun NoteDropDownMenu( } } - // Copy & Share section + // Copy & Share section. The copy-to-clipboard rows live here (and only + // here); the "Share" row hands off to the shared Share drawer. M3ActionSection { M3ActionRow(icon = MaterialSymbols.ContentCopy, text = stringRes(R.string.copy_text)) { val lastNoteVersion = (editState?.value as? GenericLoadable.Loaded)?.loaded?.modificationToShow?.value ?: note @@ -228,26 +242,7 @@ fun NoteDropDownMenu( } if (!isPrivateRumor) { M3ActionRow(icon = MaterialSymbols.Share, text = stringRes(R.string.quick_action_share)) { - val sendIntent = - Intent().apply { - action = Intent.ACTION_SEND - type = "text/plain" - putExtra(Intent.EXTRA_TEXT, externalLinkForNote(note)) - putExtra(Intent.EXTRA_TITLE, stringRes(actContext, R.string.quick_action_share_browser_link)) - } - val shareIntent = Intent.createChooser(sendIntent, stringRes(actContext, R.string.quick_action_share)) - actContext.startActivity(shareIntent) - onDismiss() - } - M3ActionRow(icon = MaterialSymbols.Image, text = stringRes(R.string.share_as_image)) { - val shareId = if (note is AddressableNote) note.address.toValue() else note.idHex - nav.nav(Route.ShareNoteAsImageFile(shareId)) - onDismiss() - } - M3ActionRow(icon = MaterialSymbols.Image, text = stringRes(R.string.share_as_image_url)) { - val shareId = if (note is AddressableNote) note.address.toValue() else note.idHex - nav.nav(Route.ShareNoteAsImage(shareId)) - onDismiss() + showShareSheet = true } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ShareActions.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ShareActions.kt new file mode 100644 index 0000000000..15693b2e7e --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ShareActions.kt @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.ui.note.elements + +import android.content.Intent +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext +import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols +import com.vitorpamplona.amethyst.model.AddressableNote +import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.ui.components.M3ActionRow +import com.vitorpamplona.amethyst.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.ui.navigation.routes.Route +import com.vitorpamplona.amethyst.ui.note.externalLinkForNote +import com.vitorpamplona.amethyst.ui.stringRes + +/** + * The shared Share rows used by the [ShareOptionsBottomSheet] drawer (opened + * both from the reaction-row Share button and from the note's 3-dot menu). + * + * Only the true "send it somewhere" options live here — browser link, image + * file, image URL. The copy-to-clipboard options stay in the 3-dot menu, so + * they are intentionally NOT part of this shared element. + * + * Callers only render these for non-private notes: every option exposes the + * note publicly (a shareable web link, or an image of it), which must never + * happen for a private gift-wrapped rumor. + */ +@Composable +fun ShareActionRows( + note: Note, + nav: INav, + onDismiss: () -> Unit, +) { + val actContext = LocalContext.current + // AddressableNotes are shared by their replaceable address; everything else + // by event id. The two image routes resolve the note from this same id. + val shareId = if (note is AddressableNote) note.address.toValue() else note.idHex + + M3ActionRow(icon = MaterialSymbols.Share, text = stringRes(R.string.quick_action_share)) { + val sendIntent = + Intent().apply { + action = Intent.ACTION_SEND + type = "text/plain" + putExtra(Intent.EXTRA_TEXT, externalLinkForNote(note)) + putExtra(Intent.EXTRA_TITLE, stringRes(actContext, R.string.quick_action_share_browser_link)) + } + val shareIntent = Intent.createChooser(sendIntent, stringRes(actContext, R.string.quick_action_share)) + actContext.startActivity(shareIntent) + onDismiss() + } + M3ActionRow(icon = MaterialSymbols.Image, text = stringRes(R.string.share_as_image)) { + nav.nav(Route.ShareNoteAsImageFile(shareId)) + onDismiss() + } + M3ActionRow(icon = MaterialSymbols.Image, text = stringRes(R.string.share_as_image_url)) { + nav.nav(Route.ShareNoteAsImage(shareId)) + onDismiss() + } +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ShareOptionsBottomSheet.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ShareOptionsBottomSheet.kt new file mode 100644 index 0000000000..f65c26bde4 --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ShareOptionsBottomSheet.kt @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.ui.note.elements + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.Text +import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.ui.components.M3ActionSection +import com.vitorpamplona.amethyst.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.ui.stringRes + +/** + * Bottom drawer that offers the note's Share options ([ShareActionRows]). + * Opened from the reaction-row Share button and from the note's 3-dot menu, + * so both entry points share the exact same list. + */ +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ShareOptionsBottomSheet( + note: Note, + nav: INav, + onDismiss: () -> Unit, +) { + val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) + + ModalBottomSheet(onDismissRequest = onDismiss, sheetState = sheetState) { + Column( + modifier = + Modifier + .fillMaxWidth() + .padding(bottom = 12.dp), + ) { + Text( + text = stringRes(R.string.quick_action_share), + style = MaterialTheme.typography.titleSmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + textAlign = TextAlign.Center, + modifier = + Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp, vertical = 8.dp), + ) + M3ActionSection { + ShareActionRows( + note = note, + nav = nav, + onDismiss = onDismiss, + ) + } + } + } +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/SoftwareApp.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/SoftwareApp.kt index 65f9e9495d..b6830f35c2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/SoftwareApp.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/SoftwareApp.kt @@ -43,6 +43,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.State import androidx.compose.runtime.getValue import androidx.compose.runtime.key import androidx.compose.runtime.produceState @@ -59,6 +60,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import coil3.compose.AsyncImage import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.richtext.MediaUrlImage @@ -90,10 +92,14 @@ import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.asset.SoftwareAss import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.release.SoftwareReleaseEvent import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.release.asSoftwareRelease import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.release.isNip82SoftwareRelease +import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.release.tags.AppIdTag +import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map /** * NIP-82 kind 32267 — compact feed card. Renders icon, name, latest version @@ -188,52 +194,79 @@ fun RenderSoftwareApplication( } /** - * Looks up the latest NIP-82 [SoftwareReleaseEvent] for [app] from - * [LocalCache] and exposes the version string. Recomputes on event identity - * change; relay-driven recompositions of the surrounding feed will pick up - * newer releases via re-keying. + * Latest NIP-82 [SoftwareReleaseEvent] version for [app], kept live. + * + * Releases (kind 30063) are separate events that point back to the app via an + * `i` tag rather than an `a` tag, so they are never indexed as replies to the + * app note and never ping its flows. Instead we register an index-driven + * [LocalCache.observeNotes] observer, so a newer release arriving while the + * card is visible updates the version chip without a manual refresh. + * + * The filter narrows on the release's `i` tag (the app id), not just the + * author, so the observer only ever loads *this* app's releases — an author + * with many apps would otherwise pull every release they ever published into + * the observer's working set. A blind `limit` is deliberately avoided: + * [LocalCache.filter] applies `take(limit)` before sorting by `created_at`, + * so it could drop the very release we are looking for. */ @Composable -fun produceLatestReleaseVersion(app: SoftwareApplicationEvent) = - produceState(initialValue = null, key1 = app.id) { - value = - withContext(Dispatchers.Default) { - findLatestNip82Release(app)?.version() - } - } - -fun findLatestNip82Release(app: SoftwareApplicationEvent): SoftwareReleaseEvent? { - val prefix = "${app.dTag()}@" - val notes = - LocalCache.addressables.filterIntoSet(SoftwareReleaseEvent.KIND, app.pubKey) { _, addr -> - val ev = addr.event ?: return@filterIntoSet false - ev.isNip82SoftwareRelease() && ev.dTag().startsWith(prefix) +fun produceLatestReleaseVersion(app: SoftwareApplicationEvent): State { + val flow = + remember(app.pubKey, app.id) { + val filter = + Filter( + kinds = listOf(SoftwareReleaseEvent.KIND), + authors = listOf(app.pubKey), + tags = mapOf(AppIdTag.TAG_NAME to listOf(app.appId())), + ) + LocalCache + .observeNotes(filter) + .map { notes -> latestNip82Release(notes, app)?.version() } + .distinctUntilChanged() + .flowOn(Dispatchers.Default) } - return notes - .mapNotNull { - when (val ev = it.event) { - is SoftwareReleaseEvent -> ev - null -> null - else -> if (ev.isNip82SoftwareRelease()) ev.asSoftwareRelease() else null - } - }.maxByOrNull { it.createdAt } + return flow.collectAsStateWithLifecycle(initialValue = null) } +fun findLatestNip82Release(app: SoftwareApplicationEvent): SoftwareReleaseEvent? = latestNip82Release(nip82ReleaseNotesFor(app), app) + +/** Picks the newest NIP-82 release for [app] out of an already-narrowed [notes] collection. */ +private fun latestNip82Release( + notes: Collection, + app: SoftwareApplicationEvent, +): SoftwareReleaseEvent? { + val prefix = "${app.dTag()}@" + return notes + .mapNotNull { it.asNip82ReleaseFor(prefix) } + .maxByOrNull { it.createdAt } +} + +/** kind-30063 addressables authored by [app] whose `d` tag is `@`. */ +private fun nip82ReleaseNotesFor(app: SoftwareApplicationEvent): Set { + val prefix = "${app.dTag()}@" + return LocalCache.addressables.filterIntoSet(SoftwareReleaseEvent.KIND, app.pubKey) { _, addr -> + val ev = addr.event ?: return@filterIntoSet false + ev.isNip82SoftwareRelease() && ev.dTag().startsWith(prefix) + } +} + +/** + * Re-reads this note as the NIP-82 release for [prefix] (`@`). kind 30063 + * collides with NIP-51 `ReleaseArtifactSetEvent`, which is what `EventFactory` + * builds, so we re-parse matching tag arrays as the NIP-82 form. + */ +private fun Note.asNip82ReleaseFor(prefix: String): SoftwareReleaseEvent? = + when (val ev = event) { + null -> null + is SoftwareReleaseEvent -> ev.takeIf { it.dTag().startsWith(prefix) } + else -> if (ev.isNip82SoftwareRelease() && ev.dTag().startsWith(prefix)) ev.asSoftwareRelease() else null + } + fun findAllNip82Releases(app: SoftwareApplicationEvent): List { val prefix = "${app.dTag()}@" - val notes = - LocalCache.addressables.filterIntoSet(SoftwareReleaseEvent.KIND, app.pubKey) { _, addr -> - val ev = addr.event ?: return@filterIntoSet false - ev.isNip82SoftwareRelease() && ev.dTag().startsWith(prefix) - } - return notes - .mapNotNull { - when (val ev = it.event) { - is SoftwareReleaseEvent -> ev - null -> null - else -> if (ev.isNip82SoftwareRelease()) ev.asSoftwareRelease() else null - } - }.sortedByDescending { it.createdAt } + return nip82ReleaseNotesFor(app) + .mapNotNull { it.asNip82ReleaseFor(prefix) } + .sortedByDescending { it.createdAt } } @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt index 3089f9ad8f..29bfa64725 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt @@ -35,6 +35,7 @@ import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.ui.feeds.FeedError import com.vitorpamplona.amethyst.ui.feeds.FeedLoaded import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed +import com.vitorpamplona.amethyst.ui.feeds.PrefetchLoadedFeedMedia import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.ui.feeds.StickToTopOnPrepend import com.vitorpamplona.amethyst.ui.feeds.WatchScrollToTop @@ -133,7 +134,10 @@ fun RenderFeedState( when (state) { is FeedState.Empty -> onEmpty() is FeedState.FeedError -> onError(state.errorMessage) - is FeedState.Loaded -> onLoaded(state) + is FeedState.Loaded -> { + PrefetchLoadedFeedMedia(state, listState, accountViewModel) + onLoaded(state) + } is FeedState.Loading -> onLoading() } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index 2666f0a1b6..43c295b649 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn import android.annotation.SuppressLint +import android.app.NotificationManager import android.content.Context import android.os.Handler import android.os.Looper @@ -30,6 +31,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable import androidx.compose.runtime.rememberCoroutineScope +import androidx.core.content.ContextCompat import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope @@ -69,6 +71,7 @@ import com.vitorpamplona.amethyst.service.cashu.melt.MeltProcessor import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver import com.vitorpamplona.amethyst.service.location.LocationState +import com.vitorpamplona.amethyst.service.notifications.NotificationUtils.dismissNotificationForEvent import com.vitorpamplona.amethyst.service.relayClient.reqCommand.RelaySubscriptionsCoordinator import com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc.NWCPaymentFilterAssembler import com.vitorpamplona.amethyst.ui.actions.Dao @@ -134,7 +137,6 @@ import com.vitorpamplona.quartz.nip19Bech32.entities.NPub import com.vitorpamplona.quartz.nip19Bech32.entities.NRelay import com.vitorpamplona.quartz.nip19Bech32.entities.NSec import com.vitorpamplona.quartz.nip28PublicChat.base.IsInPublicChatChannel -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect import com.vitorpamplona.quartz.nip47WalletConnect.rpc.Response @@ -1609,6 +1611,7 @@ class AccountViewModel( fun loadAndMarkAsRead( routeForLastRead: String, createdAt: Long?, + dismissNotificationId: HexKey? = null, ): Boolean { if (createdAt == null) return false @@ -1619,12 +1622,21 @@ class AccountViewModel( if (onIsNew) { viewModelScope.launch(Dispatchers.IO) { account.markAsRead(routeForLastRead, createdAt) + // The user is now looking at this event in-app, so clear any tray + // notification that was posted for it while the app was backgrounded. + dismissNotificationId?.let { dismissTrayNotificationFor(it) } } } return onIsNew } + private fun dismissTrayNotificationFor(eventId: HexKey) { + ContextCompat + .getSystemService(Amethyst.instance.appContext, NotificationManager::class.java) + ?.dismissNotificationForEvent(eventId) + } + fun markAllChatNotesAsRead(notes: List) { viewModelScope.launch(Dispatchers.IO) { for (note in notes) { @@ -1748,7 +1760,6 @@ class AccountViewModel( nostrGroupId: String, url: String, imeta: com.vitorpamplona.quartz.nip92IMeta.IMetaTag, - caption: String? = null, ) { val template = eventTemplate( @@ -1756,9 +1767,6 @@ class AccountViewModel( description = url, ) { imeta(imeta) - if (!caption.isNullOrEmpty()) { - alt(caption) - } } // MIP-03: inner events MUST remain unsigned (no `sig`) so a leaked // plaintext can't be replayed as a valid public kind:9. Authorship diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/apps/recommendations/ProfileAppRecommendationsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/apps/recommendations/ProfileAppRecommendationsScreen.kt index c7d403f383..15403e6a07 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/apps/recommendations/ProfileAppRecommendationsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/apps/recommendations/ProfileAppRecommendationsScreen.kt @@ -31,15 +31,17 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField 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 import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -61,37 +63,57 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNo import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor -import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton +import com.vitorpamplona.amethyst.ui.navigation.topbars.FeedFilterSpinner +import com.vitorpamplona.amethyst.ui.navigation.topbars.ShorterTopAppBar +import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon +import com.vitorpamplona.amethyst.ui.note.ClearTextIcon +import com.vitorpamplona.amethyst.ui.note.SearchIcon import com.vitorpamplona.amethyst.ui.note.types.ByAuthorChip import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.apps.recommendations.datasource.ProfileAppRecommendationsFilterAssemblerSubscription import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.kindDisplayName import com.vitorpamplona.amethyst.ui.stringRes +import com.vitorpamplona.amethyst.ui.theme.Size20Modifier +import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch +import kotlinx.coroutines.flow.flowOn @Composable fun ProfileAppRecommendationsScreen( accountViewModel: AccountViewModel, nav: INav, ) { - val myPubkey = accountViewModel.userProfile().pubkeyHex - // Pull my kind 31989 events plus recent kind 31990 app definitions from // relays so the list below has candidates while this screen is open. ProfileAppRecommendationsFilterAssemblerSubscription(accountViewModel) - // Ticks whenever LocalCache emits a bundle with a new app definition, so - // the candidate snapshot below recomputes. - var appDefinitionsTick by remember { mutableIntStateOf(0) } - LaunchedEffect(myPubkey) { - launch(Dispatchers.IO) { - LocalCache.live.newEventBundles.collect { bundle -> - if (bundle.any { it.event is AppDefinitionEvent }) appDefinitionsTick++ - } + // Kind 31990 app definitions, kept live. observeNotes seeds with the notes + // already cached and re-emits as new definitions are inserted, so the + // candidate list below derives straight from these notes — no manual tick or + // full-cache rescan. + // + // Caveat: observeNotes does NOT re-emit when an already-listed addressable is + // replaced in place, so the list isn't re-filtered/re-sorted on a kind-31990 + // update (a blank app that later gains a name, or a newer createdAt changing + // the tier order). That's acceptable here: membership rarely flips on an + // update, each row's own content stays live via AppRow's observeNoteEvent, and + // the list recomputes anyway as the recommendation/follow lists stream in. + // + // The initial value is the current cache snapshot so the first frame matches + // the seeded emission instead of flashing empty. + val cachedAppDefinitions = + remember { + LocalCache.addressables + .filterIntoSet(AppDefinitionEvent.KIND) { _, _ -> true } + .toList() } - } + val appDefinitionNotes by remember { + LocalCache + .observeNotes(Filter(kinds = listOf(AppDefinitionEvent.KIND))) + .flowOn(Dispatchers.IO) + }.collectAsStateWithLifecycle(initialValue = cachedAppDefinitions) val myRecommendationEvents by accountViewModel.account.appRecommendations.flow .collectAsStateWithLifecycle() @@ -124,10 +146,11 @@ fun ProfileAppRecommendationsScreen( } val apps = - remember(appDefinitionsTick, pinnedRecommended, pinnedFollows) { - LocalCache.addressables - .filterIntoSet(AppDefinitionEvent.KIND) { _, note -> - val event = note.event as? AppDefinitionEvent ?: return@filterIntoSet false + remember(appDefinitionNotes, pinnedRecommended, pinnedFollows) { + appDefinitionNotes + .filterIsInstance() + .filter { note -> + val event = note.event as? AppDefinitionEvent ?: return@filter false // Unnamed apps are poor recommendation candidates; keep them // only when already recommended, so they can be turned off. note.address in pinnedRecommended || @@ -156,9 +179,45 @@ fun ProfileAppRecommendationsScreen( .map { LocalCache.getOrCreateAddressableNote(it) } } + // The shared top-nav feed filter, resolved to an author/tag matcher. Only the + // author dimension is meaningful for app definitions, so the matchAuthor side + // does the work (Follows lists narrow to apps by those authors); the + // hashtag/relay/community variants leave matchAuthor == true and act as no-ops. + // Applied to discovered apps only — apps I already recommend stay listed so I + // can always turn them off. + val navFilter by accountViewModel.account.liveAppRecommendationsFollowLists + .collectAsStateWithLifecycle() + val authorFilteredApps = + remember(apps, navFilter) { + apps.filter { navFilter.matchAuthor(it.address.pubKeyHex) } + } + + // Full candidate list in display order; the search box filters this view. + val allApps = + remember(missingRecommended, authorFilteredApps) { + missingRecommended + authorFilteredApps + } + + var searchQuery by remember { mutableStateOf("") } + + // Matches on the app's name; rows whose definition hasn't arrived yet have no + // name to match, so they only show when the search box is empty. + val visibleApps = + remember(allApps, searchQuery) { + val query = searchQuery.trim() + if (query.isEmpty()) { + allApps + } else { + allApps.filter { note -> + val event = note.event as? AppDefinitionEvent + event?.appMetaData()?.anyName()?.contains(query, ignoreCase = true) == true + } + } + } + Scaffold( topBar = { - TopBarWithBackButton(stringRes(id = R.string.profile_app_recommendations_title), nav) + AppRecommendationsTopBar(accountViewModel, nav) }, ) { pad -> Column(Modifier.padding(pad).fillMaxSize()) { @@ -168,11 +227,53 @@ fun ProfileAppRecommendationsScreen( color = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.padding(horizontal = 20.dp, vertical = 12.dp), ) + + if (allApps.isNotEmpty()) { + OutlinedTextField( + value = searchQuery, + onValueChange = { searchQuery = it }, + modifier = + Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp, vertical = 4.dp), + placeholder = { + Text( + text = stringRes(R.string.profile_app_recommendations_search), + color = MaterialTheme.colorScheme.placeholderText, + ) + }, + leadingIcon = { SearchIcon(modifier = Size20Modifier, MaterialTheme.colorScheme.placeholderText) }, + trailingIcon = { + if (searchQuery.isNotEmpty()) { + IconButton(onClick = { searchQuery = "" }) { + ClearTextIcon() + } + } + }, + singleLine = true, + ) + } + HorizontalDivider() - if (apps.isEmpty() && missingRecommended.isEmpty()) { + if (allApps.isEmpty()) { + // Apps exist in cache but the author filter hid them all, vs. + // nothing discovered yet. + val emptyMessage = + if (apps.isNotEmpty()) { + stringRes(R.string.profile_app_recommendations_filter_empty) + } else { + stringRes(R.string.profile_app_recommendations_empty) + } Text( - text = stringRes(R.string.profile_app_recommendations_empty), + text = emptyMessage, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(20.dp), + ) + } else if (visibleApps.isEmpty()) { + Text( + text = stringRes(R.string.profile_app_recommendations_search_empty), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.padding(20.dp), @@ -180,7 +281,7 @@ fun ProfileAppRecommendationsScreen( } else { LazyColumn(modifier = Modifier.fillMaxSize()) { items( - items = missingRecommended + apps, + items = visibleApps, key = { it.idHex }, ) { appNote -> AppRow( @@ -198,6 +299,37 @@ fun ProfileAppRecommendationsScreen( } } +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun AppRecommendationsTopBar( + accountViewModel: AccountViewModel, + nav: INav, +) { + ShorterTopAppBar( + navigationIcon = { + if (nav.canPop()) { + IconButton(nav::popBack) { + ArrowBackIcon() + } + } + }, + title = { + val listName by accountViewModel.account.settings.defaultAppRecommendationsFollowList + .collectAsStateWithLifecycle() + val options by accountViewModel.feedStates.feedListOptions.kind3GlobalPeople + .collectAsStateWithLifecycle() + + FeedFilterSpinner( + placeholderCode = listName, + explainer = stringRes(R.string.select_list_to_filter), + options = options, + onSelect = accountViewModel.account.settings::changeDefaultAppRecommendationsFollowList, + accountViewModel = accountViewModel, + ) + }, + ) +} + @Composable private fun AppRow( appNote: AddressableNote, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatMessageCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatMessageCompose.kt index 000fbc6ca8..30ca93806a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatMessageCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatMessageCompose.kt @@ -187,7 +187,7 @@ fun NormalChatNote( if (routeForLastRead != null) { LaunchedEffect(key1 = routeForLastRead) { - accountViewModel.loadAndMarkAsRead(routeForLastRead, note.createdAt()) + accountViewModel.loadAndMarkAsRead(routeForLastRead, note.createdAt(), dismissNotificationId = note.idHex) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/CreateGroupScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/CreateGroupScreen.kt index 7178a3e3c9..7a70aef232 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/CreateGroupScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/CreateGroupScreen.kt @@ -41,10 +41,12 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp +import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.topbars.CreatingTopBar import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.quartz.nip01Core.core.toHexKey import com.vitorpamplona.quartz.utils.RandomInstance import kotlinx.coroutines.Dispatchers @@ -87,7 +89,7 @@ fun CreateGroupScreen( Toast .makeText( context, - "Failed to create group: ${e.message}", + stringRes(context, R.string.marmot_failed_to_create_group, e.message), Toast.LENGTH_LONG, ).show() } @@ -119,7 +121,7 @@ fun CreateGroupScreen( .padding(horizontal = 16.dp), ) { Text( - text = "Create Marmot Group", + text = stringRes(R.string.marmot_create_group_title), style = MaterialTheme.typography.headlineSmall, modifier = Modifier.padding(top = 16.dp, bottom = 8.dp), ) @@ -127,13 +129,13 @@ fun CreateGroupScreen( OutlinedTextField( value = groupName, onValueChange = { groupName = it }, - label = { Text("Group Name") }, + label = { Text(stringRes(R.string.marmot_group_name)) }, modifier = Modifier.fillMaxWidth(), singleLine = true, ) Text( - "A new MLS group will be created. You can add members after.", + stringRes(R.string.marmot_create_group_footer), modifier = Modifier.padding(top = 12.dp), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, @@ -169,23 +171,18 @@ private fun MissingKeyPackageRelayListDialog( ) { AlertDialog( onDismissRequest = onCancel, - title = { Text("KeyPackage Relays not set") }, + title = { Text(stringRes(R.string.marmot_keypackage_relays_not_set_title)) }, text = { - Text( - "You don't have a KeyPackage Relay List yet (MIP-00). " + - "This list tells other people where your KeyPackage is " + - "published so they can invite you to group chats.\n\n" + - "Use your current outbox relays for this?", - ) + Text(stringRes(R.string.marmot_keypackage_relays_not_set_message)) }, confirmButton = { TextButton(onClick = onConfirm) { - Text("Use outbox relays") + Text(stringRes(R.string.marmot_use_outbox_relays)) } }, dismissButton = { TextButton(onClick = onDismiss) { - Text("Skip for now") + Text(stringRes(R.string.marmot_skip_for_now)) } }, ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/EditGroupInfoScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/EditGroupInfoScreen.kt index 0f27c6e7e6..1314597009 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/EditGroupInfoScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/EditGroupInfoScreen.kt @@ -46,6 +46,7 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.topbars.ActionTopBar import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.quartz.nip01Core.core.HexKey import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -87,7 +88,7 @@ fun EditGroupInfoScreen( ) launch(Dispatchers.Main) { Toast - .makeText(context, "Group info updated", Toast.LENGTH_SHORT) + .makeText(context, stringRes(context, R.string.marmot_group_info_updated), Toast.LENGTH_SHORT) .show() } nav.popBack() @@ -97,7 +98,7 @@ fun EditGroupInfoScreen( Toast .makeText( context, - "Failed to update: ${e.message}", + stringRes(context, R.string.marmot_failed_to_update, e.message), Toast.LENGTH_LONG, ).show() } @@ -121,8 +122,8 @@ fun EditGroupInfoScreen( OutlinedTextField( value = name, onValueChange = { name = it }, - label = { Text("Group name") }, - placeholder = { Text("Enter group name") }, + label = { Text(stringRes(R.string.marmot_group_name)) }, + placeholder = { Text(stringRes(R.string.marmot_group_name_placeholder)) }, modifier = Modifier.fillMaxWidth(), singleLine = true, enabled = !isSaving, @@ -133,8 +134,8 @@ fun EditGroupInfoScreen( OutlinedTextField( value = description, onValueChange = { description = it }, - label = { Text("Description") }, - placeholder = { Text("Enter group description (optional)") }, + label = { Text(stringRes(R.string.description)) }, + placeholder = { Text(stringRes(R.string.marmot_group_description_placeholder)) }, modifier = Modifier.fillMaxWidth(), minLines = 3, maxLines = 5, @@ -144,7 +145,7 @@ fun EditGroupInfoScreen( Spacer(modifier = Modifier.height(8.dp)) Text( - text = "Changes will be committed to the group via MLS and propagated to all members.", + text = stringRes(R.string.marmot_edit_info_footer), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupChatScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupChatScreen.kt index fe3413d65e..7175395138 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupChatScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupChatScreen.kt @@ -35,8 +35,10 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold @@ -45,6 +47,7 @@ import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.note.NonClickableUserPictures import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.header.DisplayUserSetAsSubject +import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.quartz.nip01Core.core.HexKey @OptIn(ExperimentalMaterial3Api::class) @@ -73,7 +76,7 @@ fun MarmotGroupChatScreen( IconButton(onClick = { nav.popBack() }) { Icon( symbol = MaterialSymbols.AutoMirrored.ArrowBack, - contentDescription = "Back", + contentDescription = stringRes(R.string.back), ) } }, @@ -102,11 +105,11 @@ fun MarmotGroupChatScreen( accountViewModel = accountViewModel, ) } else { - Text("Marmot Group") + Text(stringRes(R.string.marmot_group_default_name)) } if (memberCount > 0) { Text( - text = "$memberCount members", + text = pluralStringResource(R.plurals.marmot_member_count, memberCount, memberCount), style = MaterialTheme.typography.bodySmall, ) } @@ -117,7 +120,7 @@ fun MarmotGroupChatScreen( IconButton(onClick = { nav.nav(Route.MarmotGroupInfo(nostrGroupId)) }) { Icon( symbol = MaterialSymbols.GroupAdd, - contentDescription = "Add Member", + contentDescription = stringRes(R.string.marmot_add_member_action), ) } }, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupChatView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupChatView.kt index 1c4575065d..a45ca0ce25 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupChatView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupChatView.kt @@ -287,7 +287,7 @@ private fun MarmotGroupFileUploadDialog( remember(nostrGroupId) { accountViewModel.account.marmotGroupList.getOrCreateGroup(nostrGroupId) } - Text(chatroom.displayName.value ?: "Marmot Group") + Text(chatroom.displayName.value ?: stringRes(R.string.marmot_group_default_name)) }, upload = { scope.launch(Dispatchers.IO) { @@ -297,7 +297,7 @@ private fun MarmotGroupFileUploadDialog( Toast .makeText( context, - "Not a member of this group", + stringRes(context, R.string.marmot_not_a_member), Toast.LENGTH_SHORT, ).show() } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt index 3d55509bd1..65ccc7dcd9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt @@ -62,10 +62,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalClipboard import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.marmot.GroupMemberInfo @@ -80,6 +82,7 @@ import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.UserSuggestio import com.vitorpamplona.amethyst.ui.note.timeAgo import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.LoadUser +import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.MediumRelayIconModifier import com.vitorpamplona.amethyst.ui.theme.SuggestionListDefaultHeightChat import com.vitorpamplona.amethyst.ui.theme.allGoodColor @@ -137,16 +140,16 @@ fun MarmotGroupInfoScreen( IconButton(onClick = { nav.popBack() }) { Icon( symbol = MaterialSymbols.AutoMirrored.ArrowBack, - contentDescription = "Back", + contentDescription = stringRes(R.string.back), ) } }, - title = { Text("Group Info") }, + title = { Text(stringRes(R.string.marmot_group_info_title)) }, actions = { IconButton(onClick = { nav.nav(Route.MarmotGroupEditInfo(nostrGroupId)) }) { Icon( symbol = MaterialSymbols.Edit, - contentDescription = "Edit Group Info", + contentDescription = stringRes(R.string.marmot_edit_group_info), ) } IconButton( @@ -155,7 +158,7 @@ fun MarmotGroupInfoScreen( ) { Icon( symbol = MaterialSymbols.AutoMirrored.ExitToApp, - contentDescription = "Leave Group", + contentDescription = stringRes(R.string.marmot_leave_group), tint = MaterialTheme.colorScheme.error, ) } @@ -180,7 +183,7 @@ fun MarmotGroupInfoScreen( Row(verticalAlignment = Alignment.CenterVertically) { Column(modifier = Modifier.weight(1f)) { Text( - text = displayName ?: "Group ${nostrGroupId.take(8)}...", + text = displayName ?: stringRes(R.string.marmot_group_fallback_name, nostrGroupId.take(8)), style = MaterialTheme.typography.headlineSmall, fontWeight = FontWeight.Bold, ) @@ -193,7 +196,7 @@ fun MarmotGroupInfoScreen( ) } Text( - text = "${members.size} members", + text = pluralStringResource(R.plurals.marmot_member_count, members.size, members.size), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.padding(top = 4.dp), @@ -226,7 +229,7 @@ fun MarmotGroupInfoScreen( item { Text( - text = "Members", + text = stringRes(R.string.members), style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold, modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), @@ -285,7 +288,7 @@ fun MarmotGroupInfoScreen( onAdd = { user -> isAdding = true isAddError = false - addStatus = "Adding ${user.toBestDisplayName()}..." + addStatus = stringRes(context, R.string.marmot_adding_user, user.toBestDisplayName()) val targetPubkey = user.pubkeyHex val targetName = user.toBestDisplayName() scope.launch(Dispatchers.IO) { @@ -297,11 +300,11 @@ fun MarmotGroupInfoScreen( addSearchInput = "" userSuggestions.reset() } else { - addStatus = "Failed to add $targetName: ${result.removePrefix("Error: ")}" + addStatus = stringRes(context, R.string.marmot_failed_to_add_user, targetName, result.removePrefix("Error: ")) isAddError = true } } catch (e: Exception) { - addStatus = "Failed to add $targetName: ${e.message ?: "unknown error"}" + addStatus = stringRes(context, R.string.marmot_failed_to_add_user, targetName, e.message ?: stringRes(context, R.string.marmot_unknown_error)) isAddError = true } finally { isAdding = false @@ -314,7 +317,7 @@ fun MarmotGroupInfoScreen( if (showLeaveDialog) { LeaveGroupDialog( - groupName = displayName ?: "this group", + groupName = displayName ?: stringRes(R.string.marmot_this_group), onConfirm = { showLeaveDialog = false isLeaving = true @@ -328,7 +331,7 @@ fun MarmotGroupInfoScreen( Toast .makeText( context, - "Failed to leave group: ${e.message}", + stringRes(context, R.string.marmot_failed_to_leave_group, e.message), Toast.LENGTH_LONG, ).show() } @@ -350,7 +353,7 @@ fun MarmotGroupInfoScreen( accountViewModel.removeMarmotGroupMember(nostrGroupId, member.leafIndex) launch(Dispatchers.Main) { Toast - .makeText(context, "Member removed", Toast.LENGTH_SHORT) + .makeText(context, stringRes(context, R.string.marmot_member_removed), Toast.LENGTH_SHORT) .show() } } catch (e: Exception) { @@ -358,7 +361,7 @@ fun MarmotGroupInfoScreen( Toast .makeText( context, - "Failed to remove member: ${e.message}", + stringRes(context, R.string.marmot_failed_to_remove_member, e.message), Toast.LENGTH_LONG, ).show() } @@ -380,7 +383,7 @@ fun MarmotGroupInfoScreen( accountViewModel.grantMarmotGroupAdmin(nostrGroupId, member.pubkey) launch(Dispatchers.Main) { Toast - .makeText(context, "Admin privileges granted", Toast.LENGTH_SHORT) + .makeText(context, stringRes(context, R.string.marmot_admin_granted), Toast.LENGTH_SHORT) .show() } } catch (e: Exception) { @@ -388,7 +391,7 @@ fun MarmotGroupInfoScreen( Toast .makeText( context, - "Failed to grant admin: ${e.message}", + stringRes(context, R.string.marmot_failed_to_grant_admin, e.message), Toast.LENGTH_LONG, ).show() } @@ -410,7 +413,7 @@ fun MarmotGroupInfoScreen( accountViewModel.revokeMarmotGroupAdmin(nostrGroupId, member.pubkey) launch(Dispatchers.Main) { Toast - .makeText(context, "Admin privileges revoked", Toast.LENGTH_SHORT) + .makeText(context, stringRes(context, R.string.marmot_admin_revoked), Toast.LENGTH_SHORT) .show() } } catch (e: Exception) { @@ -418,7 +421,7 @@ fun MarmotGroupInfoScreen( Toast .makeText( context, - "Failed to revoke admin: ${e.message}", + stringRes(context, R.string.marmot_failed_to_revoke_admin, e.message), Toast.LENGTH_LONG, ).show() } @@ -451,7 +454,7 @@ private fun AddMemberInline( modifier = SuggestionListDefaultHeightChat, onEmpty = { Text( - "They must have published a KeyPackage (kind:30443) to be added.", + stringRes(R.string.marmot_keypackage_required), modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, @@ -461,7 +464,7 @@ private fun AddMemberInline( IconButton(onClick = { onAdd(user) }) { Icon( symbol = MaterialSymbols.PersonAdd, - contentDescription = "Add to group", + contentDescription = stringRes(R.string.marmot_add_to_group), tint = MaterialTheme.colorScheme.primary, ) } @@ -487,8 +490,8 @@ private fun AddMemberInline( OutlinedTextField( value = searchInput, onValueChange = onSearchInputChange, - label = { Text("Add member") }, - placeholder = { Text("Name, npub, or NIP-05") }, + label = { Text(stringRes(R.string.marmot_add_member)) }, + placeholder = { Text(stringRes(R.string.marmot_add_member_placeholder)) }, modifier = Modifier .fillMaxWidth() @@ -530,11 +533,13 @@ fun MemberRow( ) Column(modifier = Modifier.weight(1f)) { LoadUser(baseUserHex = member.pubkey, accountViewModel = accountViewModel) { user -> - val displayName = user?.toBestDisplayName() ?: "${member.pubkey.take(16)}..." + val displayName = user?.toBestDisplayName() ?: stringRes(R.string.marmot_user_fallback_name, member.pubkey.take(16)) + val youSuffix = stringRes(R.string.marmot_member_suffix_you) + val adminSuffix = stringRes(R.string.marmot_member_suffix_admin) val suffix = buildString { - if (isMe) append(" (you)") - if (isAdmin) append(" - admin") + if (isMe) append(youSuffix) + if (isAdmin) append(adminSuffix) } Text( text = "$displayName$suffix", @@ -549,7 +554,7 @@ fun MemberRow( IconButton(onClick = onPromoteClick) { Icon( symbol = MaterialSymbols.StarBorder, - contentDescription = "Grant admin privileges", + contentDescription = stringRes(R.string.marmot_grant_admin_privileges), tint = MaterialTheme.colorScheme.primary, ) } @@ -557,7 +562,7 @@ fun MemberRow( IconButton(onClick = onDemoteClick) { Icon( symbol = MaterialSymbols.Star, - contentDescription = "Revoke admin privileges", + contentDescription = stringRes(R.string.marmot_revoke_admin_privileges), tint = MaterialTheme.colorScheme.primary, ) } @@ -566,7 +571,7 @@ fun MemberRow( IconButton(onClick = onRemoveClick) { Icon( symbol = MaterialSymbols.PersonRemove, - contentDescription = "Remove Member", + contentDescription = stringRes(R.string.marmot_remove_member), tint = MaterialTheme.colorScheme.error, ) } @@ -582,18 +587,18 @@ fun LeaveGroupDialog( ) { AlertDialog( onDismissRequest = onDismiss, - title = { Text("Leave Group") }, + title = { Text(stringRes(R.string.marmot_leave_group)) }, text = { - Text("Are you sure you want to leave \"$groupName\"? You will no longer receive messages from this group.") + Text(stringRes(R.string.marmot_leave_group_confirm, groupName)) }, confirmButton = { TextButton(onClick = onConfirm) { - Text("Leave", color = MaterialTheme.colorScheme.error) + Text(stringRes(R.string.leave), color = MaterialTheme.colorScheme.error) } }, dismissButton = { TextButton(onClick = onDismiss) { - Text("Cancel") + Text(stringRes(R.string.cancel)) } }, ) @@ -608,21 +613,21 @@ private fun ConfirmRemoveMemberDialog( ) { AlertDialog( onDismissRequest = onDismiss, - title = { Text("Remove Member") }, + title = { Text(stringRes(R.string.marmot_remove_member)) }, text = { LoadUser(baseUserHex = memberPubkey, accountViewModel = accountViewModel) { user -> - val name = user?.toBestDisplayName() ?: "${memberPubkey.take(16)}..." - Text("Are you sure you want to remove \"$name\" from this group?") + val name = user?.toBestDisplayName() ?: stringRes(R.string.marmot_user_fallback_name, memberPubkey.take(16)) + Text(stringRes(R.string.marmot_remove_member_confirm, name)) } }, confirmButton = { TextButton(onClick = onConfirm) { - Text("Remove", color = MaterialTheme.colorScheme.error) + Text(stringRes(R.string.remove), color = MaterialTheme.colorScheme.error) } }, dismissButton = { TextButton(onClick = onDismiss) { - Text("Cancel") + Text(stringRes(R.string.cancel)) } }, ) @@ -637,24 +642,21 @@ private fun ConfirmGrantAdminDialog( ) { AlertDialog( onDismissRequest = onDismiss, - title = { Text("Grant Admin Privileges") }, + title = { Text(stringRes(R.string.marmot_grant_admin_title)) }, text = { LoadUser(baseUserHex = memberPubkey, accountViewModel = accountViewModel) { user -> - val name = user?.toBestDisplayName() ?: "${memberPubkey.take(16)}..." - Text( - "Make \"$name\" an admin of this group? Admins can add or remove members, " + - "change group info, and grant admin privileges to other members.", - ) + val name = user?.toBestDisplayName() ?: stringRes(R.string.marmot_user_fallback_name, memberPubkey.take(16)) + Text(stringRes(R.string.marmot_grant_admin_confirm, name)) } }, confirmButton = { TextButton(onClick = onConfirm) { - Text("Grant") + Text(stringRes(R.string.marmot_grant)) } }, dismissButton = { TextButton(onClick = onDismiss) { - Text("Cancel") + Text(stringRes(R.string.cancel)) } }, ) @@ -669,21 +671,21 @@ private fun ConfirmRevokeAdminDialog( ) { AlertDialog( onDismissRequest = onDismiss, - title = { Text("Revoke Admin Privileges") }, + title = { Text(stringRes(R.string.marmot_revoke_admin_title)) }, text = { LoadUser(baseUserHex = memberPubkey, accountViewModel = accountViewModel) { user -> - val name = user?.toBestDisplayName() ?: "${memberPubkey.take(16)}..." - Text("Revoke admin privileges from \"$name\"? They will remain a member of the group.") + val name = user?.toBestDisplayName() ?: stringRes(R.string.marmot_user_fallback_name, memberPubkey.take(16)) + Text(stringRes(R.string.marmot_revoke_admin_confirm, name)) } }, confirmButton = { TextButton(onClick = onConfirm) { - Text("Revoke", color = MaterialTheme.colorScheme.error) + Text(stringRes(R.string.marmot_revoke), color = MaterialTheme.colorScheme.error) } }, dismissButton = { TextButton(onClick = onDismiss) { - Text("Cancel") + Text(stringRes(R.string.cancel)) } }, ) @@ -817,7 +819,7 @@ fun RelayHealthSection( Column(modifier = Modifier.fillMaxWidth()) { Text( - text = "Relays", + text = stringRes(R.string.marmot_relays_header), style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold, modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), @@ -854,9 +856,9 @@ private fun RelayHealthRow( } val subtitle = if (lastSeen == null) { - "no events yet" + stringRes(R.string.marmot_relay_no_events) } else { - "last event${timeAgo(lastSeen, context)}" + stringRes(R.string.marmot_relay_last_event, timeAgo(lastSeen, context)) } Row( modifier = diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupListScreen.kt index 1a4201cdb4..a1c57b1f7a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupListScreen.kt @@ -53,12 +53,14 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.marmotGroups.MarmotGroupChatroom @@ -68,6 +70,7 @@ import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.note.NonClickableUserPictures import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.header.DisplayUserSetAsSubject +import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.quartz.nip01Core.core.HexKey @OptIn(ExperimentalMaterial3Api::class) @@ -110,17 +113,17 @@ fun MarmotGroupListScreen( IconButton(onClick = { nav.popBack() }) { Icon( symbol = MaterialSymbols.AutoMirrored.ArrowBack, - contentDescription = "Back", + contentDescription = stringRes(R.string.back), ) } }, - title = { Text("Marmot Groups") }, + title = { Text(stringRes(R.string.marmot_groups_title)) }, ) }, floatingActionButton = { FabBottomBarPadded(nav) { FloatingActionButton(onClick = { nav.nav(Route.CreateMarmotGroup) }, shape = CircleShape) { - Icon(MaterialSymbols.Add, contentDescription = "Create Group") + Icon(MaterialSymbols.Add, contentDescription = stringRes(R.string.marmot_create_group)) } } }, @@ -132,7 +135,12 @@ fun MarmotGroupListScreen( onClick = { selectedTab = 0 }, text = { Text( - text = if (knownGroups.isEmpty()) "Known" else "Known (${knownGroups.size})", + text = + if (knownGroups.isEmpty()) { + stringRes(R.string.marmot_tab_known) + } else { + stringRes(R.string.marmot_tab_known_count, knownGroups.size) + }, ) }, ) @@ -141,7 +149,12 @@ fun MarmotGroupListScreen( onClick = { selectedTab = 1 }, text = { Text( - text = if (newRequestGroups.isEmpty()) "New Requests" else "New Requests (${newRequestGroups.size})", + text = + if (newRequestGroups.isEmpty()) { + stringRes(R.string.marmot_tab_new_requests) + } else { + stringRes(R.string.marmot_tab_new_requests_count, newRequestGroups.size) + }, ) }, ) @@ -157,16 +170,21 @@ fun MarmotGroupListScreen( ) { Column(horizontalAlignment = Alignment.CenterHorizontally) { Text( - text = if (selectedTab == 0) "No groups yet" else "No invitations", + text = + if (selectedTab == 0) { + stringRes(R.string.marmot_no_groups) + } else { + stringRes(R.string.marmot_no_invitations) + }, style = MaterialTheme.typography.titleMedium, textAlign = TextAlign.Center, ) Text( text = if (selectedTab == 0) { - "Create a group or accept an invitation." + stringRes(R.string.marmot_no_groups_desc) } else { - "When someone adds you to a group it will show up here until you reply." + stringRes(R.string.marmot_no_invitations_desc) }, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, @@ -266,7 +284,7 @@ fun MarmotGroupListItem( ) } else { Text( - text = "Group ${groupId.take(8)}...", + text = stringRes(R.string.marmot_group_fallback_name, groupId.take(8)), style = MaterialTheme.typography.titleSmall, fontWeight = if (unread > 0) FontWeight.Bold else FontWeight.Normal, maxLines = 1, @@ -284,7 +302,7 @@ fun MarmotGroupListItem( ) } else { Text( - text = "No messages yet", + text = stringRes(R.string.marmot_no_messages_yet), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.padding(top = 2.dp), @@ -311,7 +329,7 @@ fun MarmotGroupListItem( } } else { Text( - text = "${chatroom.messages.size} msgs", + text = pluralStringResource(R.plurals.marmot_message_count, chatroom.messages.size, chatroom.messages.size), style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.onSurfaceVariant, ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/send/MarmotFileSender.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/send/MarmotFileSender.kt index b16d142265..bf512b716d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/send/MarmotFileSender.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/send/MarmotFileSender.kt @@ -44,13 +44,13 @@ class MarmotFileSender( dimensions = upload.dimensions, blurhash = upload.blurhash, thumbhash = upload.thumbhash, + alt = upload.caption, ) accountViewModel.sendMarmotGroupMediaMessage( nostrGroupId = nostrGroupId, url = upload.url, imeta = imeta, - caption = upload.caption, ) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/upload/ChatFileSender.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/upload/ChatFileSender.kt index b621b520fa..531dec2695 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/upload/ChatFileSender.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/upload/ChatFileSender.kt @@ -66,10 +66,11 @@ class ChatFileSender( blurhash = result.fileHeader.blurHash?.blurhash, thumbhash = result.fileHeader.thumbHash?.thumbhash, ) { + // NIP-94 accessibility description of the file (kept; the deprecated + // generic NIP-31 boilerplate alt is not written). if (!caption.isNullOrEmpty()) { alt(caption) } - contentWarningReason?.let { contentWarning(it) } }, ) @@ -89,9 +90,6 @@ class ChatFileSender( ChatMessageEvent.build(result.url, toUsers) { references(listOf(result.url)) - if (!caption.isNullOrEmpty()) { - alt(caption) - } contentWarningReason?.let { contentWarning(it) } imetas(iMetaAttachments.filterIsIn(setOf(result.url))) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt index ac83a79bd9..4a728b5981 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt @@ -61,6 +61,7 @@ import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.ui.feeds.FeedError import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed import com.vitorpamplona.amethyst.ui.feeds.PagerStateKeys +import com.vitorpamplona.amethyst.ui.feeds.PrefetchLoadedFeedMedia import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableGridFeedContentState @@ -476,6 +477,8 @@ private fun DiscoverFeedLoaded( ) { val items by loaded.feed.collectAsStateWithLifecycle() + PrefetchLoadedFeedMedia(loaded, listState, accountViewModel) + LazyColumn( contentPadding = rememberFeedContentPadding(FeedPadding), state = listState, @@ -511,6 +514,8 @@ private fun DiscoverFeedColumnsLoaded( ) { val items by loaded.feed.collectAsStateWithLifecycle() + PrefetchLoadedFeedMedia(loaded, listState, accountViewModel) + LazyVerticalGrid( columns = GridCells.Fixed(2), contentPadding = rememberFeedContentPadding(FeedPadding), diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/DvmContentDiscoveryScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/DvmContentDiscoveryScreen.kt index 02b4cdc9ce..bf971317fa 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/DvmContentDiscoveryScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/DvmContentDiscoveryScreen.kt @@ -441,9 +441,9 @@ fun DvmPaymentActions( } if (amountInInvoice != null) { - Text(text = "Pay $amountInInvoice sats to the DVM") + Text(text = stringRes(R.string.dvm_pay_amount_to_dvm, amountInInvoice.toString())) } else { - Text(text = "Pay Invoice from the DVM") + Text(text = stringRes(R.string.dvm_pay_invoice_from_dvm)) } } } else if (amount != null) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/hashtag/HashtagFeedLoaded.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/hashtag/HashtagFeedLoaded.kt index 62aeae683b..f28e224d53 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/hashtag/HashtagFeedLoaded.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/hashtag/HashtagFeedLoaded.kt @@ -42,6 +42,7 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.ui.feeds.PrefetchLoadedFeedMedia import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.note.NoteCompose @@ -71,6 +72,8 @@ fun HashtagFeedLoaded( ) { val items by loaded.feed.collectAsStateWithLifecycle() + PrefetchLoadedFeedMedia(loaded, listState, accountViewModel) + LazyColumn( contentPadding = rememberFeedContentPadding(FeedPadding), state = listState, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt index 5eeec24635..96590b55e1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt @@ -45,6 +45,7 @@ import com.vitorpamplona.amethyst.model.BooleanType import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User +import com.vitorpamplona.amethyst.model.accountsCache.AccountCacheState import com.vitorpamplona.amethyst.service.ai.MockWritingAssistant import com.vitorpamplona.amethyst.service.ai.WritingAssistant import com.vitorpamplona.amethyst.service.ai.WritingAssistantFactory @@ -113,6 +114,7 @@ import com.vitorpamplona.quartz.nip10Notes.tags.prepareETagsAsReplyTo import com.vitorpamplona.quartz.nip18Reposts.quotes.quotes import com.vitorpamplona.quartz.nip18Reposts.quotes.taggedQuoteIds import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip22Comments.notify import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrlTag import com.vitorpamplona.quartz.nip30CustomEmoji.emojis @@ -132,6 +134,7 @@ import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefiniti import com.vitorpamplona.quartz.nip88Polls.poll.PollEvent import com.vitorpamplona.quartz.nip88Polls.poll.tags.OptionTag import com.vitorpamplona.quartz.nip88Polls.poll.tags.PollType +import com.vitorpamplona.quartz.nip89AppHandlers.clientTag.isClient import com.vitorpamplona.quartz.nip92IMeta.IMetaTagBuilder import com.vitorpamplona.quartz.nip92IMeta.imetas import com.vitorpamplona.quartz.nip94FileMetadata.alt @@ -1087,6 +1090,38 @@ open class ShortNotePostViewModel : contentWarningReason?.let { contentWarning(it) } localExpirationDate?.let { expiration(it) } + emojis(emojis) + imetas(usedAttachments) + } + } else if (shouldReplyAsComment()) { + // NIP-22: replies to a brand-new Amethyst kind-1 thread root are sent as + // kind 1111 Comments instead of kind 1 replies. + val eventHint = originalNote?.toEventHint() ?: return null + + CommentEvent.replyBuilder(tagger.message, eventHint) { + tagger.pTags?.let { userList -> + val tags = + userList.map { + val tag = it.toPTag() + if (tag.relayHint == null) { + tag.copy(relayHint = LocalCache.relayHints.hintsForKey(it.pubkeyHex).firstOrNull()) + } else { + tag + } + } + notify(tags) + } + + hashtags(findHashtags(tagger.message)) + references(findURLs(tagger.message)) + quotes(findNostrUris(tagger.message)) + + geoHash?.let { geohash(it) } + localZapRaiserAmount?.let { zapraiser(it) } + zapReceiver?.let { zapSplits(it) } + contentWarningReason?.let { contentWarning(it) } + localExpirationDate?.let { expiration(it) } + emojis(emojis) imetas(usedAttachments) } @@ -1149,6 +1184,19 @@ open class ShortNotePostViewModel : } } + /** + * NIP-22: a reply should be a kind 1111 Comment (instead of a kind 1 reply) when + * the note being replied to is a kind 1 [TextNoteEvent], is the root of a new + * thread, and was itself posted from Amethyst. Forks keep using kind 1. + */ + private fun shouldReplyAsComment(): Boolean { + if (forkedFromNote != null) return false + val replyingToEvent = originalNote?.event ?: return false + return replyingToEvent is TextNoteEvent && + replyingToEvent.isNewThread() && + replyingToEvent.isClient(AccountCacheState.CLIENT_TAG_NAME) + } + fun findEmoji( message: String, myEmojiSet: List?, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/CardFeedContentState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/CardFeedContentState.kt index 15292532f9..0bbf0d54b2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/CardFeedContentState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/CardFeedContentState.kt @@ -63,7 +63,6 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import java.time.Instant import java.time.ZoneId -import java.time.format.DateTimeFormatter @Stable class CardFeedContentState( @@ -266,7 +265,19 @@ class CardFeedContentState( } } - val sdf = DateTimeFormatter.ofPattern("yyyy-MM-dd") // SimpleDateFormat() + // Notifications are bucketed per calendar day. Computing the day key as a + // raw epoch-day Long (instead of formatting a "yyyy-MM-dd" String per event) + // gives identical buckets and chronological ordering while avoiding a + // DateTimeFormatter + ZonedDateTime + String allocation for every single + // reaction/zap/repost — a meaningful GC saving on full feed conversions. + val zone = ZoneId.systemDefault() + + fun epochDay(createdAt: Long?): Long = + Instant + .ofEpochSecond(createdAt ?: 0L) + .atZone(zone) + .toLocalDate() + .toEpochDay() val allBaseNotes = zapsPerEvent.keys + boostsPerEvent.keys + reactionsPerEvent.keys + nutzapsPerEvent.keys val multiCards = @@ -278,21 +289,16 @@ class CardFeedContentState( val singleList = (boostsInCard + zapsInCard.map { it.response } + reactionsInCard + nutzapsInCard).groupBy { - sdf.format( - Instant - .ofEpochSecond(it.createdAt() ?: 0L) - .atZone(ZoneId.systemDefault()) - .toLocalDateTime(), - ) + epochDay(it.createdAt()) } val days = singleList.keys.sortedBy { it } days - .mapNotNull { string -> + .mapNotNull { day -> val sortedList = singleList - .get(string) + .get(day) ?.sortedWith(compareByDescending { it.createdAt() }.thenBy { it.idHex }) sortedList?.chunked(30)?.map { chunk -> @@ -312,12 +318,7 @@ class CardFeedContentState( .map { user -> val byDay = user.value.groupBy { - sdf.format( - Instant - .ofEpochSecond(it.createdAt() ?: 0L) - .atZone(ZoneId.systemDefault()) - .toLocalDateTime(), - ) + epochDay(it.createdAt()) } byDay.values.map { zaps -> @@ -338,12 +339,7 @@ class CardFeedContentState( .map { user -> val byDay = user.value.groupBy { - sdf.format( - Instant - .ofEpochSecond(it.createdAt() ?: 0L) - .atZone(ZoneId.systemDefault()) - .toLocalDateTime(), - ) + epochDay(it.createdAt()) } byDay.values.map { nutzaps -> diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/NotificationScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/NotificationScreen.kt index 1f179678fe..b3e6823b45 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/NotificationScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/NotificationScreen.kt @@ -313,8 +313,11 @@ fun WatchAccountForNotifications( ) { val listState by accountViewModel.account.liveNotificationFollowLists.collectAsStateWithLifecycle() + val showMessages by + accountViewModel.account.settings.showMessagesInNotifications + .collectAsStateWithLifecycle() - LaunchedEffect(accountViewModel, listState) { + LaunchedEffect(accountViewModel, listState, showMessages) { notifFeedContentState.checkKeysInvalidateDataAndSendToTop() } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationFeedFilter.kt index a0fc6989ec..5e2d20ddd8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationFeedFilter.kt @@ -147,6 +147,51 @@ class NotificationFeedFilter( VoiceReplyEvent.KIND, ) + ADDRESSABLE_KINDS + // How deep to walk a public chat reply chain looking for one of the + // user's own messages. Bounds the cost on very long threads; the + // visited-set guards against malformed cyclic replyTo links. + private const val PUBLIC_CHAT_ANCESTOR_SCAN_LIMIT = 30 + + /** + * Public chats (NIP-28, kind 42) routinely reply to a user without + * adding a `p` tag, so the normal mention gate ([Event.isTaggedUser]) + * misses them. Treats a channel message as "for me" when one of my own + * messages appears in its reply chain — a direct reply to my message + * (the common case: "the previous message was mine") or a later message + * in a thread I'm already part of (an "active thread"). A kind-42 + * `replyTo` holds only the immediate parent, so the chain is walked + * hop-by-hop through each cached ancestor. + * + * Cache-only (reads [Note.replyTo] + author, never the account), so the + * push dispatcher and the in-app feed can both relax their p-tag gate + * with it without loading the account or decrypting anything. + */ + fun isNotifiablePublicChatReply( + note: Note, + authorHex: HexKey, + ): Boolean { + if (note.event !is ChannelMessageEvent) return false + // Top-level channel posts have no parent to reply to — bail before + // allocating the walk's scratch structures (the common case). + val parents = note.replyTo + if (parents.isNullOrEmpty()) return false + + var scanned = 0 + val seen = HashSet() + val toVisit = ArrayDeque(parents) + + while (toVisit.isNotEmpty() && scanned < PUBLIC_CHAT_ANCESTOR_SCAN_LIMIT) { + val ancestor = toVisit.removeFirst() + if (!seen.add(ancestor.idHex)) continue + scanned++ + + if (ancestor.author?.pubkeyHex == authorHex) return true + ancestor.replyTo?.let { toVisit.addAll(it) } + } + + return false + } + // Shared with EventNotificationConsumer so push notifications and the // in-app feed apply the same per-kind "is this event for me" rule. fun tagsAnEventByUser( @@ -155,6 +200,11 @@ class NotificationFeedFilter( ): Boolean { val event = note.event + // Public chat replies into my messages, even without a p-tag. + if (isNotifiablePublicChatReply(note, authorHex)) { + return true + } + if (event is GitIssueEvent || event is GitPatchEvent) { return true } @@ -246,7 +296,7 @@ class NotificationFeedFilter( } } - override fun feedKey(): String = account.userProfile().pubkeyHex + "-" + followList().code + override fun feedKey(): String = account.userProfile().pubkeyHex + "-" + followList().code + "-" + account.settings.showMessagesInNotifications.value fun followList(): TopFilter = modeOverride ?: account.settings.defaultNotificationFollowList.value @@ -299,6 +349,10 @@ class NotificationFeedFilter( ): Boolean { val loggedInUserHex = account.userProfile().pubkeyHex + // When the user opts out of seeing Messages on the Notification tab, drop + // direct/group message events (DMs and Marmot group chats) entirely. + val showMessages = account.settings.showMessagesInNotifications.value + // Marmot group messages are only acceptable if the gathering chatroom is // actually in the current account's group list. Notes are stored in the // global LocalCache and accumulate a gatherer reference from every @@ -308,6 +362,7 @@ class NotificationFeedFilter( // instance held by this account's list. val marmotGatherers = it.inGatherers?.filterIsInstance() if (!marmotGatherers.isNullOrEmpty()) { + if (!showMessages) return false val inCurrentAccount = marmotGatherers.any { room -> account.marmotGroupList.rooms.get(room.nostrGroupId) === room @@ -317,6 +372,16 @@ class NotificationFeedFilter( } val noteEvent = it.event + + if (!showMessages && + ( + noteEvent is ChatMessageEvent || + noteEvent is ChatMessageEncryptedFileHeaderEvent || + noteEvent is PrivateDmEvent + ) + ) { + return false + } val notifAuthor = if (noteEvent is LnZapEvent) { val zapRequest = noteEvent.zapRequest @@ -355,10 +420,17 @@ class NotificationFeedFilter( // follow/list modes) also applies the per-kind relevance heuristics. val isRawGlobal = followList() is TopFilter.Global + // The p-tag gate is OR'd with isNotifiablePublicChatReply so channel + // replies into my messages still notify without a p-tag. Kept inline + // (not a pre-computed val) so the cheap kind check short-circuits ahead + // of the tag scan + reply walk, which is also why the cheaper tag scan + // is ordered first within the OR. In Global mode this is the only + // relevance check (tagsAnEventByUser is skipped below); it still scopes + // to genuine replies, so unrelated channel chatter never leaks through. return noteEvent?.kind in NOTIFICATION_KINDS && (noteEvent is LnZapEvent || notifAuthor != loggedInUserHex) && (isChessEvent || filterParams.isGlobal() || notifAuthor == null || filterParams.isAuthorInFollows(notifAuthor)) && - noteEvent?.isTaggedUser(loggedInUserHex) ?: false && + (noteEvent?.isTaggedUser(loggedInUserHex) == true || isNotifiablePublicChatReply(it, loggedInUserHex)) && (filterParams.isHiddenList || notifAuthor == null || !account.isHidden(notifAuthor)) && (noteEvent !is PrivateDmEvent || !account.isDecryptedContentHidden(noteEvent)) && (isRawGlobal || tagsAnEventByUser(it, loggedInUserHex)) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/products/ProductsFeedLoaded.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/products/ProductsFeedLoaded.kt index 4d50129921..bc9ffc5181 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/products/ProductsFeedLoaded.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/products/ProductsFeedLoaded.kt @@ -39,6 +39,7 @@ import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.ui.feeds.FeedError import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed +import com.vitorpamplona.amethyst.ui.feeds.PrefetchLoadedFeedMedia import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -97,6 +98,8 @@ private fun ProductsFeedColumnsLoaded( ) { val items by loaded.feed.collectAsStateWithLifecycle() + PrefetchLoadedFeedMedia(loaded, listState, accountViewModel) + LazyVerticalGrid( columns = GridCells.Fixed(2), contentPadding = rememberFeedContentPadding(FeedPadding), diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/ProfileGalleryFeed.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/ProfileGalleryFeed.kt index cc80416fb1..b41c1f3fcf 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/ProfileGalleryFeed.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/ProfileGalleryFeed.kt @@ -38,6 +38,7 @@ import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.ui.feeds.FeedError import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed +import com.vitorpamplona.amethyst.ui.feeds.PrefetchLoadedFeedMedia import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.screen.FeedViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -91,6 +92,8 @@ private fun GalleryFeedLoaded( ) { val items by loaded.feed.collectAsStateWithLifecycle() + PrefetchLoadedFeedMedia(loaded, listState, accountViewModel) + val ratio = if (accountViewModel.settings.modernGalleryStyle()) { 0.8f diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/newthreads/TabNotesNewThreads.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/newthreads/TabNotesNewThreads.kt index 5353327843..70cc25c600 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/newthreads/TabNotesNewThreads.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/newthreads/TabNotesNewThreads.kt @@ -39,6 +39,7 @@ import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.ui.feeds.FeedError import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed +import com.vitorpamplona.amethyst.ui.feeds.PrefetchLoadedFeedMedia import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.ui.feeds.StickToTopOnPrepend import com.vitorpamplona.amethyst.ui.feeds.WatchScrollToTop @@ -96,6 +97,7 @@ fun TabNotesNewThreads( } is FeedState.Loaded -> { + PrefetchLoadedFeedMedia(state, listState, accountViewModel) FeedLoadedWithPinnedNotes( pinnedFeedState = pinnedFeedState as? FeedState.Loaded, loaded = state, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/NotificationSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/NotificationSettingsScreen.kt index b2914644d3..d0b82a09e6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/NotificationSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/NotificationSettingsScreen.kt @@ -115,6 +115,8 @@ private fun DeliverySection(accountViewModel: AccountViewModel) { private fun DisplaySection(accountViewModel: AccountViewModel) { val splitByFollows by accountViewModel.account.settings.splitNotificationsEnabled .collectAsStateWithLifecycle() + val showMessages by accountViewModel.account.settings.showMessagesInNotifications + .collectAsStateWithLifecycle() SettingsSection(R.string.notification_settings_section_display) { SettingsSwitchTile( @@ -124,6 +126,14 @@ private fun DisplaySection(accountViewModel: AccountViewModel) { checked = splitByFollows, onCheckedChange = { accountViewModel.account.settings.toggleSplitNotificationsEnabled() }, ) + SettingsDivider() + SettingsSwitchTile( + icon = MaterialSymbols.Mail, + title = R.string.show_messages_in_notifications_setting_title, + description = R.string.show_messages_in_notifications_setting_description, + checked = showMessages, + onCheckedChange = { accountViewModel.account.settings.toggleShowMessagesInNotifications() }, + ) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/OtsSettingsSection.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/OtsSettingsSection.kt index b123e9d524..c233fa52fb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/OtsSettingsSection.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/OtsSettingsSection.kt @@ -55,9 +55,11 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp +import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.model.nip03Timestamp.OtsSettings +import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.quartz.nip03Timestamp.okhttp.OkHttpBitcoinExplorer /** @@ -121,7 +123,7 @@ fun OtsSettingsSection( modifier = Modifier.size(16.dp), ) Spacer(Modifier.width(4.dp)) - Text("Reset to auto-select") + Text(stringRes(R.string.ots_reset_to_auto_select)) } } } @@ -269,7 +271,7 @@ private fun CustomExplorerInput( input = it validationError = null }, - label = { Text("Explorer API base URL") }, + label = { Text(stringRes(R.string.ots_explorer_api_label)) }, placeholder = { Text("https://mempool.space/api/") }, singleLine = true, isError = validationError != null, @@ -286,7 +288,7 @@ private fun CustomExplorerInput( }) { Icon( MaterialSymbols.Clear, - contentDescription = "Clear", + contentDescription = stringRes(R.string.clear), modifier = Modifier.size(18.dp), ) } @@ -312,7 +314,7 @@ private fun CustomExplorerInput( onClick = { trySave() }, modifier = Modifier.padding(top = 6.dp), ) { - Text("Save") + Text(stringRes(R.string.save)) } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletViewModel.kt index 0d0cd0ce79..d04c5bf64f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletViewModel.kt @@ -500,8 +500,13 @@ class CashuWalletViewModel : ViewModel() { ops.publishWalletEvents( mints = mints, p2pkPrivkeyHex = privkey, + // Advertise our NIP-65 inbox relays as the nutzap relays, + // so senders publish kind:9321 where we read incoming + // events (NIP-65 outbox model). The kind:10019 default + // copies the inbox relay list, not outbox; the wallet + // still subscribes to a wider inbox + DM + tags set. nutzapRelays = - acc.outboxRelays.flow.value + acc.notificationRelays.flow.value .toList(), ) _createState.value = CashuWalletCreateState.Success diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/OnchainSection.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/OnchainSection.kt index c7b87a65b2..bb564f030f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/OnchainSection.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/OnchainSection.kt @@ -372,7 +372,7 @@ private fun ActionRow( modifier = Modifier.size(14.dp), ) Spacer(modifier = Modifier.width(4.dp)) - Text("Copy", style = MaterialTheme.typography.bodySmall) + Text(stringRes(R.string.copy), style = MaterialTheme.typography.bodySmall) } Spacer(modifier = Modifier.weight(1f)) @@ -393,7 +393,7 @@ private fun ActionRow( modifier = Modifier.size(14.dp), ) Spacer(modifier = Modifier.width(4.dp)) - Text("Send", style = MaterialTheme.typography.bodySmall, fontWeight = FontWeight.SemiBold) + Text(stringRes(R.string.send), style = MaterialTheme.typography.bodySmall, fontWeight = FontWeight.SemiBold) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/ExerciseTemplateDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/ExerciseTemplateDisplay.kt new file mode 100644 index 0000000000..dd0abbe74a --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/ExerciseTemplateDisplay.kt @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.ui.screen.loggedIn.workouts + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import com.vitorpamplona.amethyst.commons.icons.symbols.Icon +import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbol +import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols +import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists +import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.ui.components.SensitivityWarning +import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer +import com.vitorpamplona.amethyst.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.experimental.fitness.workout.ExerciseTemplateEvent +import com.vitorpamplona.quartz.experimental.fitness.workout.slugToTitle + +/** Icon for the equipment of a kind-33401 exercise template. */ +private fun equipmentSymbol(equipment: String?): MaterialSymbol = + when (equipment?.lowercase()) { + "cardio" -> MaterialSymbols.DirectionsRun + else -> MaterialSymbols.FitnessCenter + } + +/** Renders a kind-33401 exercise template (POWR / NIP-101e): title, equipment/difficulty, instructions. */ +@Composable +fun ExerciseTemplateDisplay( + baseNote: Note, + backgroundColor: MutableState, + canPreview: Boolean, + quotesLeft: Int, + accountViewModel: AccountViewModel, + nav: INav, +) { + val event = (baseNote.event as? ExerciseTemplateEvent) ?: return + + val title = remember(event) { event.title() ?: event.dTag().ifBlank { null }?.let(::slugToTitle) } + val equipment = remember(event) { event.equipment() } + val difficulty = remember(event) { event.difficulty() } + val subtitle = remember(event) { listOfNotNull(equipment, difficulty).joinToString(" · ") { it.replaceFirstChar(Char::uppercaseChar) } } + + Column(modifier = Modifier.fillMaxWidth().padding(horizontal = 10.dp, vertical = 5.dp)) { + Row(verticalAlignment = Alignment.CenterVertically) { + Box( + modifier = + Modifier + .size(40.dp) + .clip(CircleShape) + .background(MaterialTheme.colorScheme.primary.copy(alpha = 0.12f)), + contentAlignment = Alignment.Center, + ) { + Icon( + symbol = equipmentSymbol(equipment), + contentDescription = title, + modifier = Modifier.size(24.dp), + tint = MaterialTheme.colorScheme.primary, + ) + } + + Spacer(modifier = Modifier.width(10.dp)) + + Column(modifier = Modifier.weight(1f)) { + Text( + text = title ?: subtitle.ifEmpty { "" }, + fontWeight = FontWeight.Bold, + style = MaterialTheme.typography.titleMedium, + ) + if (subtitle.isNotEmpty()) { + Text( + text = subtitle, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.placeholderText, + ) + } + } + } + + // Form instructions / notes, through the same kind-1 rich-text pipeline. + val notes = event.content.trim() + if (notes.isNotEmpty()) { + val callbackUri = remember(baseNote) { baseNote.toNostrUri() } + val tags = remember(baseNote) { event.tags.toImmutableListOfLists() } + SensitivityWarning(note = baseNote, accountViewModel = accountViewModel) { + TranslatableRichTextViewer( + content = notes, + canPreview = canPreview, + quotesLeft = quotesLeft, + modifier = Modifier.fillMaxWidth().padding(top = 12.dp), + tags = tags, + backgroundColor = backgroundColor, + id = baseNote.idHex, + callbackUri = callbackUri, + accountViewModel = accountViewModel, + nav = nav, + ) + } + } + } +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/WorkoutDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/WorkoutDisplay.kt index e8a9cda509..985948e8f0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/WorkoutDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/WorkoutDisplay.kt @@ -37,6 +37,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.runtime.MutableState +import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -50,18 +51,23 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbol import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteEvent import com.vitorpamplona.amethyst.ui.components.SensitivityWarning import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.quartz.experimental.fitness.workout.ExerciseGroup +import com.vitorpamplona.quartz.experimental.fitness.workout.ExerciseTemplateEvent import com.vitorpamplona.quartz.experimental.fitness.workout.WorkoutRecordEvent import com.vitorpamplona.quartz.experimental.fitness.workout.tags.DistanceTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.DurationTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.Elevation import com.vitorpamplona.quartz.experimental.fitness.workout.tags.ExerciseType import com.vitorpamplona.quartz.experimental.fitness.workout.tags.WeightTag +import com.vitorpamplona.quartz.nip01Core.core.Address import kotlin.math.abs import kotlin.math.round @@ -78,6 +84,9 @@ fun ExerciseType?.symbol(): MaterialSymbol = ExerciseType.MEDITATION -> MaterialSymbols.SelfImprovement ExerciseType.DIET -> MaterialSymbols.Restaurant ExerciseType.FASTING -> MaterialSymbols.Timer + ExerciseType.CIRCUIT -> MaterialSymbols.FitnessCenter + ExerciseType.EMOM -> MaterialSymbols.FitnessCenter + ExerciseType.AMRAP -> MaterialSymbols.FitnessCenter null -> MaterialSymbols.DirectionsRun } @@ -94,6 +103,9 @@ fun ExerciseType.labelRes(): Int = ExerciseType.MEDITATION -> R.string.exercise_meditation ExerciseType.DIET -> R.string.exercise_diet ExerciseType.FASTING -> R.string.exercise_fasting + ExerciseType.CIRCUIT -> R.string.exercise_circuit + ExerciseType.EMOM -> R.string.exercise_emom + ExerciseType.AMRAP -> R.string.exercise_amrap } private fun Double.trimmed(): String = if (this % 1.0 == 0.0 && abs(this) < 1e15) toLong().toString() else toString() @@ -148,12 +160,44 @@ private fun WeightTag.toDisplay(miles: Boolean): WeightTag = WeightTag(round(toKilograms() * 10.0) / 10.0, WeightTag.KILOGRAMS) } +/** Renders a kilogram weight (POWR's native unit) in the viewer's preferred unit, e.g. `84 kg` or `185 lbs`. */ +private fun formatWeightKg( + kg: Double, + miles: Boolean, +): String { + val display = WeightTag(kg, WeightTag.KILOGRAMS).toDisplay(miles) + return "${display.value.trimmed()} ${display.unit}" +} + +/** One readable line summarizing the sets logged for a single exercise. */ +private fun ExerciseGroup.summaryLine(miles: Boolean): String { + val descriptors = + sets.map { set -> + val reps = set.reps + val kg = set.weightKg?.takeIf { it > 0.0 } + when { + kg != null && reps != null -> "$reps × ${formatWeightKg(kg, miles)}" + reps != null -> "$reps reps" + kg != null -> formatWeightKg(kg, miles) + else -> "—" + } + } + if (descriptors.isEmpty()) return "" + // Collapse identical sets (e.g. 3 sets of 8 × 84 kg) into "3 × 8 × 84 kg". + return if (descriptors.size > 1 && descriptors.distinct().size == 1) { + "${descriptors.size} × ${descriptors.first()}" + } else { + descriptors.joinToString(", ") + } +} + /** One-shot snapshot of the parsed workout tags, so the feed doesn't re-scan the tag array on every recomposition. */ @Immutable class WorkoutInfo( val title: String?, val type: ExerciseType?, val exerciseRaw: String?, + val typeRaw: String?, val source: String?, val durationSeconds: Long?, val distance: DistanceTag?, @@ -166,6 +210,8 @@ class WorkoutInfo( val sets: Int?, val reps: Int?, val weight: WeightTag?, + // POWR / NIP-101e strength dialect: per-exercise logged sets (weights are in kilograms). + val exerciseGroups: List, ) { /** Rewrites the unit-bearing metrics into the viewer's preferred system (miles/feet/lbs vs km/m/kg). */ fun inUnits(miles: Boolean) = @@ -173,6 +219,7 @@ class WorkoutInfo( title = title, type = type, exerciseRaw = exerciseRaw, + typeRaw = typeRaw, source = source, durationSeconds = durationSeconds, distance = distance?.toDisplay(miles), @@ -185,16 +232,19 @@ class WorkoutInfo( sets = sets, reps = reps, weight = weight?.toDisplay(miles), + // Kept in kilograms; the breakdown converts per the viewer's unit at render time. + exerciseGroups = exerciseGroups, ) companion object { fun from(event: WorkoutRecordEvent) = WorkoutInfo( title = event.title(), - type = event.exerciseType(), + type = event.activityType(), exerciseRaw = event.exercise(), - source = event.workoutSource(), - durationSeconds = event.durationSeconds(), + typeRaw = event.workoutTypeCode(), + source = event.workoutSource() ?: event.client(), + durationSeconds = event.effectiveDurationSeconds(), distance = event.distance(), elevationGain = event.elevationGain(), elevationLoss = event.elevationLoss(), @@ -205,6 +255,7 @@ class WorkoutInfo( sets = event.sets(), reps = event.reps(), weight = event.weight(), + exerciseGroups = event.exerciseGroups(), ) } } @@ -232,7 +283,11 @@ fun WorkoutDisplay( val miles = remember { phonePrefersMiles() } val info = remember(baseNote, miles) { WorkoutInfo.from(event).inUnits(miles) } - val typeLabel = info.type?.let { stringRes(it.labelRes()) } ?: info.exerciseRaw ?: stringRes(R.string.workout) + val typeLabel = + info.type?.let { stringRes(it.labelRes()) } + ?: info.exerciseRaw + ?: info.typeRaw?.replaceFirstChar { it.uppercaseChar() } + ?: stringRes(R.string.workout) val duration = info.durationSeconds val distance = info.distance @@ -250,6 +305,7 @@ fun WorkoutDisplay( buildSecondaryStats( info = info, heroKind = heroKind, + miles = miles, durationLabel = stringRes(R.string.workout_duration), distanceLabel = stringRes(R.string.workout_distance), paceLabel = stringRes(R.string.workout_pace), @@ -263,6 +319,8 @@ fun WorkoutDisplay( setsLabel = stringRes(R.string.workout_sets), repsLabel = stringRes(R.string.workout_reps), weightLabel = stringRes(R.string.workout_weight), + exercisesLabel = stringRes(R.string.workout_exercises), + volumeLabel = stringRes(R.string.workout_volume), ) Column(modifier = Modifier.fillMaxWidth().padding(horizontal = 10.dp, vertical = 5.dp)) { @@ -318,6 +376,10 @@ fun WorkoutDisplay( WorkoutStatsGrid(secondaryStats) + if (info.exerciseGroups.isNotEmpty()) { + ExerciseBreakdown(info.exerciseGroups, miles, accountViewModel) + } + // Route the note (event content) through the same kind-1 pipeline: rich text with // links/mentions/hashtags, embeds, sensitivity warning and inline translations. val notes = event.content.trim() @@ -346,6 +408,7 @@ fun WorkoutDisplay( private fun buildSecondaryStats( info: WorkoutInfo, heroKind: HeroKind, + miles: Boolean, durationLabel: String, distanceLabel: String, paceLabel: String, @@ -359,11 +422,21 @@ private fun buildSecondaryStats( setsLabel: String, repsLabel: String, weightLabel: String, + exercisesLabel: String, + volumeLabel: String, ): List { val duration = info.durationSeconds val distance = info.distance return buildList { + // POWR / NIP-101e strength workouts: aggregate the per-set exercise tags. + val groups = info.exerciseGroups + if (groups.isNotEmpty()) { + add(Stat("${groups.size}", exercisesLabel)) + add(Stat("${groups.sumOf { it.sets.size }}", setsLabel)) + val volumeKg = groups.mapNotNull { it.totalVolumeKg() }.takeIf { it.isNotEmpty() }?.sum() + volumeKg?.let { add(Stat(formatWeightKg(it, miles), volumeLabel)) } + } if (heroKind != HeroKind.DURATION) { duration?.let { add(Stat(DurationTag.formatTime(it), durationLabel)) } } @@ -454,6 +527,72 @@ private fun WorkoutStatsGrid( } } +/** Per-exercise breakdown for POWR / NIP-101e strength workouts: exercise name + its logged sets. */ +@Composable +private fun ExerciseBreakdown( + groups: List, + miles: Boolean, + accountViewModel: AccountViewModel, +) { + Column( + modifier = Modifier.fillMaxWidth().padding(top = 12.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + groups.forEach { group -> + ExerciseRow(group, miles, accountViewModel) + } + } +} + +@Composable +private fun ExerciseRow( + group: ExerciseGroup, + miles: Boolean, + accountViewModel: AccountViewModel, +) { + val fallback = group.displayName() ?: "—" + val address = remember(group.reference) { Address.parse(group.reference) } + + if (address == null) { + ExerciseRowContent(fallback, group.summaryLine(miles)) + return + } + + // Resolve the kind-33401 template to show its real title; falls back to the slug + // until the template is fetched (the workout event's relay hints drive the fetch). + LoadAddressableNote(address, accountViewModel) { templateNote -> + val name = + if (templateNote != null) { + val templateEvent by observeNoteEvent(templateNote, accountViewModel) + templateEvent?.title() ?: fallback + } else { + fallback + } + ExerciseRowContent(name, group.summaryLine(miles)) + } +} + +@Composable +private fun ExerciseRowContent( + name: String, + summary: String, +) { + Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.Top) { + Text( + text = name, + style = MaterialTheme.typography.bodyMedium, + fontWeight = FontWeight.Medium, + modifier = Modifier.weight(1f), + ) + Spacer(modifier = Modifier.width(8.dp)) + Text( + text = summary, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.placeholderText, + ) + } +} + /** Small chip showing how the workout was recorded (e.g. GPS, RUNSTR, HEALTHKIT, MANUAL). */ @Composable private fun WorkoutSourceBadge(source: String) { diff --git a/amethyst/src/main/res/values-ar-rSA/strings.xml b/amethyst/src/main/res/values-ar-rSA/strings.xml index 0ad76e64a5..5b291fc736 100644 --- a/amethyst/src/main/res/values-ar-rSA/strings.xml +++ b/amethyst/src/main/res/values-ar-rSA/strings.xml @@ -19,8 +19,6 @@ أنتحال تصرف غير قانوني أخرى - غير معروف - أيقونة المرحل كاتب غير معروف نسخ النص نسخ المفتاح العام @@ -31,12 +29,9 @@ الإبلاغ عن إزعاج / احتيال الإبلاغ عن انتحال الشخصية - الإبلاغ عن المحتوى الصريح / الفاضح الإبلاغ عن سلوك غير قانوني الإبلاغ عن برمجيات خبيثة - إبلاغ المشرفين برمجية خبيثة - مشرف قم بتسجيل الدخول باستخدام مفتاح خاص لتتمكن من الرد قم بتسجيل الدخول باستخدام مفتاح خاص لتتمكن من تعزيز المشاركات تسجيل الدخول باستخدام مفتاح خاص لإبداء الإعجاب بالمنشورات @@ -47,7 +42,6 @@ قم بتسجيل الدخول باستخدام مفتاحك السري لتتمكن من إخفاء الكلمة أو الجملة قم بتسجيل الدخول باستخدام مفتاحك السري لتتمكن من إظهار الكلمة أو الجملة زاب - مشاهدة العد تعزيز معزز معدلة @@ -60,9 +54,7 @@ إضافة "الرد على" " و " - "في القناة " لافتة الملف الشخصي - تم الدفع بنجاح خطأ أثناء تحليل رسالة الخطأ "المتابعون" "متابِعاً" @@ -83,9 +75,7 @@ رسالتي المخفية بادئة مرئية إضافة إلى المنشور - "خطأ في تحليل المعاينة لـ %1$s : %2$s" "معاينة صورة البطاقة لـ %1$s" - قناة جديدة اسم القناة مجموعتي الرائعة رابط الصورة @@ -96,33 +86,18 @@ حفظ إنشاء إلغاء - فشل تحميل الصورة - عنوان الخادم (Relay Adress) - المنشورات - بايتات الأخطاء - اخطأ الاتصال في هذه الجلسة - المنشورات الرئيسية - الرسائل الخاصة - الرسائل العامة - الموجز العام - البحث أضف Relay - الإسم إسم العرض إسم العرض الخاص بي اسمي المميز مرحبا بك! اسم المستخدم - اسم المستخدم الخاص بي ْعَنِّي رابط الصورة الزمزية رابط الشعار رابط الموقع الضمائر - LN عنوان - LN رابط (قديم) - حفظه في معرض الصور تم حفظ الصورة في المعرض بدأ تنزيل الفيديو… بدأ تنزيل الوسائط… @@ -130,11 +105,8 @@ تم حفظ الفيديو في الجهاز فشل حفظ الفيديو تحميل الصورة - جاري التحميل… لا يمتلك المستخدم عنوان (Lightning Address) لاستقبال sats "الرد هنا…" - نسخ معرف الملاحظة إلى الحافظة للمشاركة - انسخ معرف القناة (ملاحظة) إلى الحافظة تعديل البيانات الوصفية للقناة إنضمام معروف @@ -146,18 +118,14 @@ الردود الخاص بك الألبوم - "المتابَعون" "التقارير" المزيد من الخيارات "Relays" الموقع Lightning عنوان نسخ معرف Nsec (كلمة المرور الخاصة بك) إلى الحافظة للنسخ الاحتياطي - نسخ المفتاح الخاص إلى الحافظة إظهار رمز QR المفتاح الخاص إظهار رمز QR المفتاح الخاص المشفر - نسخ المفتاح العام إلى الحافظة للمشاركة - انسخ المفتاح العام (NPub) إلى الحافظة إرسال رسالة مباشرة القيام بتحرير metadata للمستخدم متابعة @@ -186,8 +154,6 @@ كيف ينبغي أن ندعوك؟ ليس لديك حساب؟ هل لديك حساب nostr بالفعل؟ - أنشئ حسابًا جديدًا - إنشاء مفتاح جديد بإنتظار التحديثات جاري تحميل الحساب @@ -197,12 +163,6 @@ لا توجد إشعارات حتى الآن. لا توجد ملاحظات. تحديث - انشئ - مع وصف - و صورة - تم تغيير اسم الدردشة إلى - الوصف الى - و الصورة الى مغادرة الغاء المتابعة تم انشاء القناة @@ -228,7 +188,6 @@ الألفاظ النابية / خطاب كراهية أبلغ عن كلام يحض على الكراهية الإبلاغ عن عُري / إباحي - آخرون ضع علامة على جميع الرسائل/الاشعارات المعروفة كمقروء ضع علامة على جميع الرسائل/الاشعارات الجديدة كمقروء ضع علامة على جميع الرسائل/الاشعارات كمقروء @@ -247,15 +206,12 @@ إنسخ مفتاحي السري تشفير و نسخ المفتاح الخاص فشلت المصادقة - خطأ - "تم إنشاؤه بواسطة %1$s" "صورة شارة مكافئة ل %1$s" لقد حصلت على شارة جائزة جديدة شارة الجائزة منحت إلى تم نسخ نص الملاحظة/المنشور إلى الحافظة تم نسخ عنوان @npub المؤلف إلى الحافظة تم نسخ رمز الملاحظة/المنشور (note ID) إلى الحافظة - تحديد نص "<استحالة فك تشفير الرسالة الخاصة> \n\n أنت الآن في محادثة خاصة/مشفرة بين %1$s و %2$s ." إضافة حساب جديد @@ -263,8 +219,6 @@ اختر حساب إضافة حساب جديد تنشيط الحساب - يحتوي على مفتاح خاص - قراءة فقط، لا يوجد مفتاح خاص رجوع اختر شارك رابط المتصفح @@ -282,14 +236,12 @@ حذف حظر التبليغ - حذف لا تظهر مرة أخرى رسائل مزعجة أو رسائل خداع سلوك بغيض انتحال الشخصية محتوى دموي أو خادش للحياء تصرف غير قانوني - برمجية خبيثة حظر المستخدم سوف يخفي محتواه في التطبيق الخاص بك. ملاحظاتك لا تزال قابلة للعرض علناً، بما في ذلك للأشخاص الذين تقوم بحظرهم. يتم إدراج المستخدمين المحظورين على شاشة مرشحات الأمان (Security Filters screen). الإبلاغ عن إساءة الإستخدام @@ -309,27 +261,13 @@ إضافة إلى المفضلات العامة إزالة من المفضلات الخاصة إزالة من المفضلات العامة - خدمة Wallet Connect - السماح لمفتاحك السري بدفع ال zaps بدون الحاجة الى لخروج من التطبيق (دع مفتاحك السري ٱمن و استخدم خادم خاص إن امكن) - خادم Wallet Connect - كلمة سر خدمة Wallet Connect - إظهار كلمة السر - المفتاح السري بصيغة nsec أو hex - نشر الاستطلاع - الحقول المطلوبة: - مستلمين الزاب - وصف الاستطلاع الأساسي… الخيار %s وصف خيار الاستطلاع - حقل اختياري الحد الأدنى الحد الاقصى توافق الآراء - إغلاق بعد - أيام تعذر التصويت تم إغلاق الاستطلاع لأي تصويت جديد - عدد الزاب يسمح بصوت واحد فقط لكل مستخدم في هذا النوع من الاستطلاع "البحث عن الحدث %1$s" أضف رسالة عامة @@ -363,17 +301,9 @@ لا يوجد أثر في نوستر، فقط على شبكة الLightning خادم الملفات اختر خادم لرفع الملف به - user@ او Lnaddres خوادم الوسائط - المرحلات الخاصة بك (NIP-95) - الملفات مُستضافة في مرحلاتك. الـNIP جديد، تأكد من دعمهم له - إعداد Tor/Orbot - الاتصال من خلال إعدادات Orbot الخاص بك - قطع الاتصال بTor/Orbot؟ - سيتم نقل بياناتك على الفور في الشبكة المعتادة نعم لا - قائمة المتابعة جميع المتابعات العالمي قائمة الحسابات المكتومة @@ -410,8 +340,6 @@ إخفاء عنوان الـIP من جميع الإتصالات خصصه بنفسك رقم المنفذ غير صالح - أستخدام Orbot - قطع إتصال Tor/Orbot الرسائل الخاصة التنبيه عند وصول رسالة خاصة تم استلام الزاب @@ -421,20 +349,9 @@ ل %1$s تنبيه: - الانضمام إلى المحادثة - معرف المستخدم أو المجموعة - npub, nevent أو hex - إنشاء - إنضمام اليوم تحذير من المحتوى هذا المنشور يحتوي على محتوى حساس، قد يجده البعض مزعج - إخفاء المحتوى الحساس دائماً - إظهار المحتوى الحساس دائماً - إظهار تحذيرات المحتوى دائمًا - التطبيقات الموصى بها : - تصفية الرسائل المزعجة من الغرباء - تنبيه عندما تكون منشورتك قد تم التبليغ عنها رمز رد فعل جديد لم يتم تحديد أي نوع من ردود الفعل. اضغط مطولاً للتغيير إضافة هدف الساتوشي المراد جمعه. سوف يظهر العملاء هذا كشريط تقدم لتحفيز التبرعات @@ -443,34 +360,22 @@ الكتابة للخادم عدد البايتات الذي تم إرساله إلى هذا المرحل عدد البايتات الذي تم أستقباله من هذا المرحل - حدث خطأ أثناء محاولة الحصول على معلومات الخادم من %1$s المالك الاصدار البرنامج جهة الاتصال الNIPs المدعومة - رسوم القبول رابط الدفع الحدود الدول اللغات - الوسوم سياسات النشر الأخطاء والإشعارات من هذا المرحل - طول الرسالة - الإشتراكات - الفلاتر - طول معرّف الاشتراك الحد الأدنى لل prefix الحد الأقصى لوسوم الحدث - طول المحتوى الحد الأدنى لل PoW - المصادقة - الدفع استـرداد - إرسال إلى محفظة زاب تسخ الtoken - نسخ الtoken من المحفظة مباشر غير متصل انتهى @@ -490,7 +395,6 @@ (translated) row titles. Marked translatable="false" so protocol terms (blossom, nsec, negentropy, …) stay searchable in every locale and aren't sent to translators. --> دائماً - الواي فاي فقط ابداً النظام فاتح @@ -502,7 +406,6 @@ تشغيل الفيديو معاينة الرابط اختر نمط المنشور - تحميل الصورة المستخدمون المزعجون الصوت مكتوم. انقر لإلغاء كتم الصوت الصوت مفعل. انقر لكتم الصوت @@ -510,16 +413,9 @@ تم التحقق من عنوان نوستر فشل التحقق من عنوان نوستر التحقق من عنوان نوستر - تحديد/إلغاء تحديد الكل الافتراضي اعادة الوضع الافتراضى - اختر مرحل للإستمرار عرض الموقع كـ - ميزة جديدة - يتطلب تنشيط هذا الوضع من Amethyst إرسال رسالة خاصة من نوع NIP-17 -(GiftWrapped, Sealed Direct and group Messages) . -إضافة NIP-17 لا تزال جديدة ومعظم العملاء لم يدعموها بعد. تأكد من أن المستلم يستخدم عميل متوافق. - تفعيل عام خاص إلى @@ -535,47 +431,25 @@ تحميل الصور و الصور المتحركة تلقائياً تشغيل الفيديوهات و الصور المتحركة تلقائياً إظهار معاينات الروابط - متى يتم تحميل الصور نسخ إلى الحافظة نسخ npub إلى الحافظة مشاركة أو حفظ نسخ عنوان الرابط إلى الحافظة انسخ معرف النص (ID) إلى الحافظة أنشئ في - القواعد تسجيل الدخول باستخدام Amber تحديث الحالة - خطأ أثناء تحليل رسالة المشكل تُحسب الاصوات بكمية الزاب، يمكنك وضع حد أعلى لتجنب انحياز التصويت وحد ادنى لتجنب المزعجين. يمكنك استخدام نفس الكمية للحدين للتأكد من ان جميع الاصوات متساوية. لا تضع أي حدود لإستقبال أي كمية. رسالة إلى المستخدم موافق - فشل الوصول إلى -%1$s: %2$s - فشل في تجميع رابط NIP-11 لـ %1$s: %2$s - فشل الوصول إلى %1$s: %2$s - فشل تحليل الرد من %1$s: %2$s - المرحل رفض الطلب %1$s: %2$s - فشل الوصول إلى %1$s: %2$s - فشل تحليل مخرجات %1$s: %2$s - فشل %1$s مع الرمز %2$s - نشط لـ: - الصفحة الرئيسية - المحادثات الخاصة - الدردشات - العالمي - البحث تقسيم و إعادة توجيه الزاب سوف يقسمون ويوجهون العملاء الداعمين الزاب للمستخدمين بدلاً منك البحث و إضافة مستخدم اسم المستخدم أو إسم العرض - النسبة المئوية - تقسيم الزاب مع - تحويل الزاب إلى تم الدفع المحفظة %1$s خطأ في فتح تطبيق الموقِّع (signer app) لم يتم العثور على الموقّع، تأكد مما إذا لم يتم إلغاء تثبيت تثبيته - تم رفض تطبيق التوقيع تأكد من أن تطبيق الموقِّع قد أذن بهذه المعاملة الكلمات المخفية إخفاء كلمة أو جملة جديدة @@ -584,15 +458,10 @@ حدد خيارا تعذر دفع الفاتورة لا يمكن السحب - خطأ في تحليل رابط إتصال NIP-47. تحقق مما إذا كان صحيح مع موفر المحفظة الخاص بك: %1$s. الخطأ: %2$s - خطأ في تحليل رابط إتصال NIP-47. تحقق مما إذا كان صحيح مع موفر المحفظة الخاص بك: %1$s. %1$s sats أرسلت الى محفظتك (الرسوم: sats %2$s ) تعذر جلب الinvoice من خوادم المستلم موفر wallet connect الخاص بك أعاد الخطأ التالي: %1$s - لا يمكن الاتصال بTor - تعذر تحميل مستندات المرحل - تعذر جلب الinvoice من %1$s مبلغ الinvoice غير صحيح (sats %1$s ) من %2$s. كان يجب أن يكون %3$s مستخدم في وضع القراءة فقط لا توجد اعدادات لردود الفعل @@ -634,10 +503,8 @@ خطأ في التحميل: %1$s تسجيل الدخول بواسطة رمز الQR الصفحة الرئيسية - البحث الرسائل - مرشحات الأمان منشور جديد منشور جديد للمجتمع فتح جميع ردود الفعل على هذا المنشور @@ -647,13 +514,9 @@ تغيير ردود الفعل السريعة المرحل %1$s توسعة قائمة المرحلات - منتقي قائمة المرحلات مرحلات الرسائل الخاصة - مرحلات: %1$s - أستخدام المرحلات العادية أعد مرحلات رسائلك الخاصة هذا الإعداد يوضح للعملاء أين يرسلون الرسائل الخاصة لك، بدونه قد تفقد بعضهم. - الخيارات الجيدة هي:\n - inbox.nostr.wine (مدفوع)\n - auth.nostr1.com (مجاني)\n - you.nostr1.com (مرحلات خاصة - مدفوع) الخيارات الجيدة هي:\n - auth.nostr1.com (مجاني)\n - inbox.nostr.wine (مدفوع)\n - relay.0xchat.com (مجاني) اختر من واحد إلى ثلاث مرحلات لاستقبال رسائلك الخاصة بهم. مرحلات الرسائل الخاصة يجب أن تستقبل الرسائل من أي شخص وتسمح لك فقط بقراءتهم. الإعداد الآن @@ -679,4 +542,5 @@ + diff --git a/amethyst/src/main/res/values-bn-rBD/strings.xml b/amethyst/src/main/res/values-bn-rBD/strings.xml index 8c09ccf88c..56ff9e92a7 100644 --- a/amethyst/src/main/res/values-bn-rBD/strings.xml +++ b/amethyst/src/main/res/values-bn-rBD/strings.xml @@ -24,8 +24,6 @@ অন্যান্য হয়রানি Violence - অচেনা - রিলে আইকন অজ্ঞাত-পরিচয় লেখক টেক্সটটি কপি করুন লেখক আইডি কপি করুন @@ -38,12 +36,9 @@ স্প্যাম/প্রতারণার অভিযোগ করুন ছদ্মবেশ ধারণের অভিযোগ করুন - খোলামেলা আধেয় হিসেবে অভিযোগ করুন বেআইনী আচরণের অভিযোগ করুন ম্যালওয়্যার রিপোর্ট করুন - রিপোর্ট মোড ম্যালওয়্যার - মোড প্রতিউত্তর দিতে ব্যক্তিগত চাবি দিয়ে লগ ইন করুন পোস্টগুলি বুস্ট করতে ব্যক্তিগত চাবি দিয়ে লগ ইন করুন পোস্টগুলি লাইক করতে ব্যক্তিগত চাবি দিয়ে লগ ইন করুন @@ -54,7 +49,6 @@ পোস্টগুলি বুস্ট করতে ব্যক্তিগত চাবি দিয়ে লগ ইন করুন পোস্টগুলি বুস্ট করতে ব্যক্তিগত চাবি দিয়ে লগ ইন করুন জ্যাপস - পরিমাণ দেখুন বুস্ট বুস্ট করা হয়েছে সম্পাদিত @@ -65,9 +59,7 @@ যুক্ত করুন "এই ব্যক্তির প্রতিউত্তর দিচ্ছেন " " এবং " - "চ্যানেলের ভেতর " প্রোফাইলের ব্যানার - সফলভাবে মূল্য পরিশোধিত হয়েছে " অনুসরণ" " অনুসারী" "%1$s অনুসরণ" @@ -85,9 +77,7 @@ স্যাট পাঠান সিক্রেট ইমোজি মেকার 😎 - "এই দুইয়ের পূর্বরূপ দেখানো যাচ্ছে না %1$s : %2$s" "%1$s এর জন্য কার্ড ইমেজের পূর্বরূপ দেখুন" - নতুন চ্যানেল চ্যানেলের নাম আমার অসাধারণ দল ছবির Url @@ -98,38 +88,20 @@ সংরক্ষণ করুন তৈরি করুন বাতিল করুন - ছবিটি সফলভাবে আপলোড করা যায় নি - রিলে-ঠিকানা - পোস্টগুলি - বাইটস ত্রুটিসমূহ - নীড়পাতা - ব্যক্তিগত বার্তাসমূহ - সার্বজনীন কথোপকথন - বৈশ্বিক পাতা - অনুসন্ধান পাতা - একজন ব্যবহারকারী যোগ করুন একটি রিলে যুক্ত করুন - নাম প্রদর্শিত নাম আমার প্রদর্শিত নাম ইউজারনেম - আমার ইউজারনেম আমার সম্পর্কে অবতারের URL ব্যানারের URL ওয়েবসাইটের URL - বিজলি-ঠিকানা - বিজলি URL (অপ্রচলিত) - গ্যালারিতে সংরক্ষণ করুন ছবিটি গ্যালারিতে সংরক্ষণ করা হয়েছে ছবিটি সফলভাবে সংরক্ষণ করা যায় নি ছবিটি আপলোড করুন - আপলোড করা হচ্ছে… স্যাট গ্রহণের জন্য ব্যবহারকারীর কোনো বিজলি-ঠিকানা দেওয়া নেই "এখানে প্রতিউত্তর দিন.. " - নস্টারে শেয়ারের জন্য নোট আইডিটি ক্লিপবোর্ডে কপি করা হয় - চ্যানেল আইডি (নোট) ক্লিপবোর্ডে কপি করুন চ্যানেলের মেটাডেটা সম্পাদনা করে যুক্ত হোন জ্ঞাত @@ -139,16 +111,12 @@ কথোপকথন নোটস প্রতিউত্তরসমূহ - "অনুসারী" "অভিযোগসমূহ" আরও বিকল্প " রিলেগুলি" ওয়েবসাইট বিজলি-ঠিকানা ব্যাকআপের জন্য আপনার Nsec আইডি (তথা পাসওয়ার্ড) ক্লিপবোর্ডে কপি করে - আপনার ব্যক্তিগত চাবিটি ক্লিপবোর্ডে কপি করুন - অন্যদের সাথে শেয়ারের জন্য আপনার গণ চাবি ক্লিপবোর্ডে কপি করে - গণ চাবি (Npub) ক্লিপবোর্ডে কপি করুন একটি সরাসরি-বার্তা পাঠান ব্যবহারকারীর মেটাডেটা সম্পাদনা করে অনুসরণ করুন @@ -176,8 +144,6 @@ অ্যাকাউন্ট খুলুন একটি Nostr অ্যাকাউন্ট নেই? ইতিমধ্যে একটি Nostr অ্যাকাউন্ট আছে? - একটি নতুন অ্যাকাউন্ট তৈরি করুন - একটি নতুন চাবি তৈরি করুন পাতাটি লোড করা হচ্ছে @@ -185,12 +151,6 @@ আবার চেষ্টা করুন পাতাটি খালি রিফ্রেশ করুন - তৈরি করা হয়েছে - এর বিবরণ সহ - এবং ছবি - চ্যাটের নাম পরিবর্তন করুন - বিবরণ - এবং ছবি ছেড়ে দিন আনফলো করুন চ্যানেলটি তৈরি করা হয়েছে @@ -214,7 +174,6 @@ অশ্লীলতা / বিদ্বেষপূর্ণ বক্তব্য বিদ্বেষপূর্ণ বক্তব্য হিসেবে অভিযোগ জানান নগ্নতা / পর্ন হিসেবে অভিযোগ জানান - অন্যান্য পরিচিত সবগুলোকে পঠিত হিসেবে চিহ্নিত করুন নতুন সবগুলোকে পঠিত হিসেবে চিহ্নিত করুন সবগুলোকে পঠিত হিসেবে চিহ্নিত করুন @@ -234,23 +193,18 @@ এনক্রিপ্ট এবং আমার গোপন কী অনুলিপি প্রমাণীকরণ ব্যর্থ হয়েছে। বায়োমেট্রিক্স এই ফোনের মালিককে প্রমাণ করতে ব্যর্থ হয়েছে৷ - ত্রুটি - "%1$s দ্বারা নির্মিত" "%1$s -এর জন্য ব্যাজ পুরষ্কারের ছবি" আপনি একটি নতুন ব্যাজ পুরষ্কার পেয়েছেন ব্যাজ পুরস্কারটি পাচ্ছে নোটের রচনাটি ক্লিপবোর্ডে কপি করা হয়েছে রচয়িতার @npub ক্লিপবোর্ডে কপি করুন নোট আইডিটি (@note1) ক্লিপবোর্ডে কপি করা হয়েছে - রচনাটি নির্বাচন করুন "<Unable to decrypt private message>\n\nআপনাকে %1$s এবং %2$s এর মধ্যে একটি ব্যক্তিগত/এনক্রিপ্টেড কথোপকথনে উদ্ধৃত করা হয়েছে৷" নতুন অ্যাকাউন্ট যুক্ত করুন অ্যাকাউন্টগুলি অ্যাকাউন্ট নির্বাচন করুন নতুন অ্যাকাউন্ট যুক্ত করুন অ্যাকাউন্ট সক্রিয় করুন - ব্যক্তিগত চাবি আছে - শুধুমাত্র পাঠযোগ্য, ব্যক্তিগত চাবি নেই পিছে যান নির্বাচন করুন ব্রাউজারের লিংক শেয়ার করুন @@ -267,7 +221,6 @@ মুছে ফেলুন ব্লক করুন অভিযোগ করুন - মুছে ফেলুন আর দেখাবেন না স্প্যাম অথবা প্রতারণা অশ্লীলতা বা বিদ্বেষপূর্ণ আচরণ @@ -294,28 +247,13 @@ সর্বজনীন বুকমার্ক থেকে সরিয়ে দিন পাবলিক প্রবন্ধ পাবলিক প্রবন্ধ(%1$s) - ওয়ালেট সংযোগের পরিষেবা - অ্যাপ থেকে বের না হয়েই জ্যাপ প্রদান করতে একটি নস্টার-সিক্রেট অনুমোদন করা হয়ে থাকে। এই নস্টার-সিক্রেটটি নিরাপদে রাখুন এবং সম্ভব হলে একটি ব্যক্তিগত রিলে ব্যবহার করুন - ওয়ালেট সংযোগের গণ চাবি - ওয়ালেট সংযোগের রিলে - ওয়ালেট সংযোগের সিক্রেট - গোপন চাবি দেখান - nsec / hex ব্যক্তিগত চাবি প্রতিশ্রুত পরিমাণ স্যাট দ্বারা জানান - একটি পোল পেশ করুন - প্রয়োজনীয় ক্ষেত্রসমূহ: - জ্যাপ প্রাপকেরা - পোলের প্রাথমিক বিবরণ… বিকল্প %s পোলের বিবিধ বিকল্পের বিবরণ - ঐচ্ছিক ক্ষেত্র: ন্যূনতম জ্যাপ সর্বোচ্চ জ্যাপ ঐক্যমত (০–১০০)% - এই সময় পর বন্ধ করুন - দিনগুলি - পরিমাণটি জ্যাপ করুন এই জাতীয় পোলে একজন ব্যবহারকারী শুধুমাত্র একটি করেই ভোট দিতে পারবেন "ইভেন্ট খোঁজা হচ্ছে %1$s" একটি সর্বজনীন বার্তা পাঠান @@ -343,36 +281,16 @@ নন-জ্যাপ নস্টারে কোনো সন্ধান নেই, কেবল বিজলিতে আছে ফাইল সার্ভার - বিজলি-ঠিকানা বা @ব্যবহারকারী ডিফল্ট তালিকা ব্যবহার করুন শুরু হয়নি - আপনার রিলেগুলি (NIP-95) - ফাইলগুলো আপনার রিলে দ্বারা গৃহীত হয়। নতুন NIP: তারা এটি সমর্থন করে কিনা দেখে নিন - Tor/Orbot সেটআপ করুন - আপনার Orbot সেটআপের মাধ্যমে সংযুক্ত হোন - Orbot/Tor থেকে সংযোগ বিচ্ছিন্ন করতে চান? - আপনার ডেটা অবিলম্বে নিয়মিত নেটওয়ার্কে স্থানান্তর করা হবে হ্যাঁ না - অনুসরণ তালিকা অনুসৃত সকলেরা বৈশ্বিক নিঃশব্দ তালিকা - সর্বজনীন - ব্যক্তিগত - ## Tor এর মাধ্যমে Orbot এর সাথে সংযুক্ত হোন - \n\n১. [Orbot] নামান (https://play.google.com/store/apps/details?id=org.torproject.android) - \n২. Orbot চালু করুন - \n৩. Orbot এ ঢুকে Socks পোর্টটি খেয়াল করুন। এটি ৯০৫০ তে নির্দিষ্ট করা থাকে - \n৪. প্রয়োজনে Orbot এ পোর্টটি বদলে দিন - \n৫. স্ক্রিনের Socks পোর্টটি প্রস্তুত করুন - \n৬. Orbot কে প্রক্সি হিসেবে ব্যবহার করতে Activate বোতামটি চাপুন - Orbot এর Socks পোর্ট পছন্দমতন পোর্ট নম্বরটি অকার্যকর - Orbot ব্যবহার করুন - Tor/Orbot থেকে সংযোগ বিচ্ছিন্ন করুন ব্যক্তিগত বার্তাসমূহ যখন একটি ব্যক্তিগত বার্তা আসে তখন আপনাকে অবহিত করে জ্যাপ গৃহীত হয়েছে @@ -382,20 +300,9 @@ %1$s এর জন্য অবহিত করুন: - আলোচনায় যুক্ত হোন - ব্যবহারকারী কিংবা গ্রুপের আইডি - npub, nevent অথবা hex - তৈরি করুন - যুক্ত হোন আজ আধেয় বিষয়ক সতর্কতা এই পোস্টে সংবেদনশীল উপাদান রয়েছে যা কারো জন্য আপত্তিকর কিংবা সমস্যাজনক হতে পারে - সংবেদনশীল আধেয় সবসময় আড়ালে রাখুন - সংবেদনশীল বিষয়বস্তু সবসময় খোলামেলা দেখান - সবসময় আধেয় বিষয়ক সতর্কতা দেখান - প্রস্তাবিত: - অপরিচিতদের কাছ থেকে স্প্যাম ফিল্টার করুন - কোনো পোস্টে আপনার অনুসরীদের থেকে অভিযোগ থাকলে অবহিত হোন প্রতিক্রিয়ার নতুন প্রতীক প্রতিক্রিয়ার কোনো ধরন বেছে নেওয়া হয়নি। পরিবর্তন করতে দীর্ঘক্ষণ চাপুন জ্যাপরেইজার @@ -404,33 +311,22 @@ জ্যাপরাইজার %1$s তে আছে। %2$s স্যাট লক্ষ্যমাত্রা রিলে থেকে পড়ুন রিলেতে লিখুন - %1$s থেকে রিলের তথ্যের জন্য চেষ্টা করার সময় একটি ত্রুটি ঘটেছে৷ মালিক সংস্করণ সফটওয়্যার যোগাযোগ সমর্থিত NIP গুলো - প্রবেশমূল্য মূল্যপরিশোধের URL সীমাবদ্ধতা দেশসমূহ ভাষাসমূহ - ট্যাগগুলি আধেয় পেশ করার নীতি - বার্তার ব্যাপ্তি - সকল সদস্যতা - ফিল্টারগুলি - সদস্যতা আইডির ব্যাপ্তি ন্যূনতম উপসর্গ সর্বাধিক ইভেন্ট ট্যাগ - আধেয়র ব্যাপ্তি ন্যূনতম PoW - অনুমোদন - মূল্যপরিশোধ ক্যাশু টোকেন খালাস করুন কোনো বিজলি-ঠিকানা সেট করা নেই - টোকেনটি ক্লিপবোর্ডে কপি করা হয়েছে লাইভ অফলাইন সমাপ্ত @@ -452,7 +348,6 @@ (translated) row titles. Marked translatable="false" so protocol terms (blossom, nsec, negentropy, …) stay searchable in every locale and aren't sent to translators. --> সবসময় - শুধুমাত্র ওয়াইফাইতে কখনো না সিস্টেম উজ্জ্বল @@ -465,7 +360,6 @@ URL-এর পূর্বরূপ ইমারসিভ স্ক্রোলিং পোস্ট শৈলী চয়ন করুন - ছবিটি লোড করুন স্প্যামাররা মৌন করে রাখা। এটি তুলে নিতে ক্লিক করুন শব্দ চালু আছে। মৌন করতে ক্লিক করুন @@ -473,17 +367,10 @@ নস্টার ঠিকানাটি যাচাই করা হয়েছে নস্টার ঠিকানাটি যাচাই করা যায় নি নস্টার ঠিকানাটি পরীক্ষা করে দেখা হচ্ছে - সবগুলিকে নির্বাচন/অনির্বাচন করুন পূর্ব-নির্ধারিত - চালিয়ে যেতে একটি রিলে নির্বাচন করুন - জ্যাপটি পাঠান: - সহায়তাকারী ক্লায়েন্টরা আপনার পরিবর্তে নিচের বিজলি-ঠিকানায় বা ব্যবহারকারীর প্রোফাইলে জ্যাপ পাঠাবে আপনার অবস্থান এভাবে প্রকাশ করুন পোস্টে আপনার অবস্থানের একটি জিওহ্যাশ যোগ করে। জনসাধারণ জানবে যে আপনি বর্তমান অবস্থান থেকে ৫ কিলোমিটার (৩ মাইল) এর মধ্যে আছেন আপনার পেশকৃত আধেয় দেখানোর আগে সংবেদনশীল আধেয়-সতর্কতা জারি করে। এটি সেসকল আধেয়র জন্য আদর্শ যেখানে NSFW উপাদান কিংবা এমনকিছু থাকতে পারে যা কারো কারো জন্য আপত্তিকর কিংবা সমস্যাজনক মনে হতে পারে। - নতুন ফিচার - এই মোড সক্রিয় করার জন্য অ্যামেথিস্টকে একটি NIP-17 বার্তা পাঠাতে হবে। (GiftWrapped, সিল করা সরাসরি এবং দলগত বার্তা)। NIP-17 নতুন এবং বেশিরভাগ ক্লায়েন্ট এখনও এটি বাস্তবায়ন করেনি। নিশ্চিত করুন যে প্রাপক একটি সামঞ্জস্যপূর্ণ ক্লায়েন্ট ব্যবহার করছে। - সক্রিয় করুন সর্বজনীন ব্যক্তিগত প্রতি @@ -499,48 +386,29 @@ স্বয়ংক্রিয়ভাবে ছবি এবং GIF লোড করুন স্বয়ংক্রিয়ভাবে ভিডিও এবং GIF চালু করুন URL এর পূর্বরূপ দেখান - কখন ছবি লোড করতে হবে URL ক্লিপবোর্ডে কপি করুন নোট আইডি ক্লিপবোর্ডে কপি করুন যেখানে নির্মিত - নিয়ম Amber দিয়ে লগইন করুন আপনার স্ট্যাটাস আপডেট করুন জ্যাপের পরিমাণ দ্বারা ভোটসংখ্যা গোণা হয়। আপনি স্প্যামার এড়াতে একটি সর্বনিম্ন পরিমাণ এবং একটি বড়ো জ্যাপার দ্বারা পোল দখল এড়াতে সর্বোচ্চ পরিমাণ স্যাট নির্ধারণ করতে পারেন। প্রতিটি ভোটের মূল্য একই পরিমাণে রয়েছে তা নিশ্চিত করতে উভয় ক্ষেত্রেই একই পরিমাণ ব্যবহার করুন। যেকোনো পরিমাণ গ্রহণ করতে এটি খালি ছেড়ে দিন। জ্যাপ পাঠানো যায় নি ব্যবহারকারীকে বার্তা দিন ঠিক আছে - %1$s: %2$s পৌঁছাতে ব্যর্থ - %1$s: %2$s পৌঁছাতে ব্যর্থ - %1$s: %2$s থেকে ফলাফল পার্স করা যায় নি - %1$s কোড দিয়ে ব্যর্থ হয়েছে %2$s - এর জন্য সক্রিয় করুন: - নীড় - বার্তাসমূহ - আলাপচারিতা - বৈশ্বিক - অনুসন্ধান করুন জ্যাপগুলি ভাগ করুন এবং পাঠান সমর্থিত ক্লায়েন্টরা জ্যাপ ভাগ করবে এবং আপনার পরিবর্তে এখানে সংযুক্ত ব্যবহারকারীদেরকে পাঠাবে ব্যবহারকারীদের অনুসন্ধান করুন এবং যুক্ত করুন ইউজারনেম কিংবা প্রদর্শিত নাম দিন %1$s ব্যবহারকারীর স্যাট গ্রহণের উপযোগী কোনো বিজলি ঠিকানা সেট করা নেই - শতাংশ - ২৫ - এর সাথে জ্যাপ ভাগ করা হচ্ছে - একে জ্যাপ পাঠানো হচ্ছে - বিজলি-ওয়ালেট পাওয়া যায় নি পরিশোধিত ওয়ালেট %1$s স্বাক্ষরের অ্যাপ খোলা যাচ্ছে না - স্বাক্ষরের অনুরোধ প্রত্যাখ্যান করা হয়েছে কোন প্রতিক্রিয়া সেটআপ একটি নির্বাচন করুন UnifiedPush অ্যাপ কোনটি নয় বিক্রেতাকে একটি বার্তা পাঠান হাই %1$s, এটা কি এখনও পাওয়া যায়? হাই, এটা কি এখনও পাওয়া যায়? - একটি পণ্য বিক্রি করুন শিরোনাম iPhone 13 শর্ত @@ -560,12 +428,10 @@ দপ্তর খাদ্য নীড় - অনুসন্ধান করুন আবিস্কার বার্তা অবহিতকরন - নিরাপত্তা-ফিল্টার নতুন পোস্ট উত্তর বুস্ট বা উদ্ধৃতি @@ -591,4 +457,5 @@ + diff --git a/amethyst/src/main/res/values-ca-rES/strings.xml b/amethyst/src/main/res/values-ca-rES/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-ca-rES/strings.xml +++ b/amethyst/src/main/res/values-ca-rES/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-cs-rCZ/strings.xml b/amethyst/src/main/res/values-cs-rCZ/strings.xml index a6c906453f..91754bf5ac 100644 --- a/amethyst/src/main/res/values-cs-rCZ/strings.xml +++ b/amethyst/src/main/res/values-cs-rCZ/strings.xml @@ -36,8 +36,6 @@ Jiný Obtěžování Násilí - Neznámý - Ikona předávání Neznámý autor Kopírovat text Kopírovat ID autora @@ -52,12 +50,9 @@ Nahlásit spam / podvod Nahlásit zneužívání identity - Nahlásit explicitní obsah Nahlásit nezákonné jednání Nahlásit malware - Nahlásit mód Malware - Mód Pro odpověď se přihlaste s privátním klíčem Pro zvýšení příspěvků se přihlaste s privátním klíčem Přihlásit se pomocí soukromého klíče pro označení příspěvků jako líbivé @@ -71,17 +66,14 @@ Přihlaste se pomocí soukromého klíče, abyste mohli zrušit sledování Používáte veřejný klíč a veřejné klíče jsou pouze pro čtení. Přihlaste se pomocí soukromého klíče, abyste mohli skrýt slovo nebo větu Používáte veřejný klíč a veřejné klíče jsou pouze pro čtení. Přihlaste se pomocí soukromého klíče, abyste mohli zobrazit slovo nebo větu - Používáte veřejný klíč, který je pouze pro čtení. Přihlaste se pomocí soukromého klíče, abyste mohli měnit nastavení Používáte veřejný klíč, který je pouze pro čtení. Přihlaste se pomocí soukromého klíče, abyste mohli nahrávat Používáte veřejný klíč, který je pouze pro čtení. Přihlaste se pomocí soukromého klíče, abyste mohli podepisovat události Neautorizované dešifrování Podepisovatel neautorizoval dešifrování potřebné k provedení této operace. Aktivujte dešifrování NIP-44 ve své aplikaci pro podepisování a zkuste to znovu Podepisovatel nenalezen Byla aplikace pro podepisování odinstalována? Zkontrolujte, zda je aplikace nainstalována a obsahuje tento účet. Odhlaste se a přihlaste znovu, pokud se aplikace změnila. - Podepisovatel se choval neočekávaně Externí podepisovatel vrátil data, která jsou pro daný požadavek neobvyklá. Může se jednat o chybu v Amethystu nebo v podepisovateli. Zapy - Počet zobrazení Zvýšení zvýšeno upraveno @@ -94,9 +86,7 @@ Přidat "odpovídá na " " a " - "v kanálu " Banner profilu - Platba úspěšná Chyba při zpracování chybové zprávy " Sleduje" " Sledující" @@ -169,7 +159,6 @@ Nedostatečný zůstatek v mintu, který tento příjemce přijímá. Nejprve dobijte svou Cashu peněženku. K útratě pro tohoto příjemce: %1$s sats Síťový poplatek - vaše peněženková aplikace Transakce: %1$s Bleskové tipy Poznámka pro příjemce @@ -183,16 +172,13 @@ Viditelná předpona 😎 Přidat k příspěvku - "Chyba při zpracování náhledu pro %1$s : %2$s" "Náhled obrázku karty pro %1$s" Článek - Nový kanál Název kanálu Má skvělá skupina URL obrázku Adresa URL obrázku (volitelné) Popis - Popis nebyl nalezen "O nás…" Co vás napadá? Napište zprávu… @@ -202,42 +188,25 @@ Vytvořit Přejmenovat Zrušit - Selhalo nahrávání obrázku - Adresa relé - Příspěvky - Byty Chyba Chyby Procento úspěšných připojení k relé - Počet chyb připojení v této relaci - Domovský kanál - Kanál soukromých zpráv - Kanál veřejného chatu - Globální kanál - Kanál vyhledávání Vyhledat a přidat uživatele - Přidat uživatele Přidat přeposílání - Jméno - Jméno (pro @tagování) Moje @tag jméno Zobrazované jméno Moje zobrazované jméno Ostrich McAwesome Vítejte Ostrich! Uživatelské jméno - Moje uživatelské jméno O mně URL avatara URL banneru URL webové stránky Zájmena - LN adresa - LN URL (zastaralé) Zdrojová relé mohou být zastaralá Upozornění na zastaralá relé Uložit do telefonu - Uložit do galerie Obrázek uložen do galerie Stahování videa bylo zahájeno… Stahování médií bylo zahájeno… @@ -254,15 +223,12 @@ Pořiďte fotografii Nahrát video Nahrajte zprávu - Nahrajte zprávu Stiskněte a podržte pro nahrání zprávy Znovu nahrát Nahrávání Nahrávání %1$s - Nahrávání… Chyba nahrávání Nepodařilo se nahrát hlasovou zprávu - Neočekávaný stav nahrávání NIP-95 zatím není pro hlasové zprávy podporován Nahrávání hlasu selhalo: %1$s Žádný @@ -274,8 +240,6 @@ Uživatel nemá nastavenou LN adresu pro přijímání sats "Odpověď zde…" V tomto chatu - Zkopíruje ID poznámky do schránky pro sdílení - Zkopírovat ID kanálu (poznámka) do schránky Upravit metadata kanálu Připojit se Známé @@ -289,7 +253,6 @@ Odpovědi Vaše Galerie - "Sleduje" "Zprávy" "%1$s Reportů" Více možností @@ -297,11 +260,8 @@ Webová stránka Lightning adresa Zkopíruje Nsec ID (vaše heslo) do schránky pro zálohování - Zkopírovat tajný klíč do schránky Zobrazit QR kód privátního klíče Zobrazit šifrovaný QR kód soukromého klíče - Zkopíruje veřejný klíč do schránky pro sdílení - Zkopírovat veřejný klíč (NPub) do schránky Poslat přímou zprávu Upravit uživatelova metadata Sledovat @@ -330,8 +290,6 @@ Jak bychom vám měli říkat? Nemáte Nostr účet? Máte již Nostr účet? - Vytvořit nový účet - Vygenerovat nový klíč Načítání zdroje Načítání účtu šifrované @@ -347,13 +305,7 @@ Otevřená anketa Zdroj je prázdný. Obnovit - vytvořeno - s popisem - a obrázkem - změnil název chatu na Nový chatový profil: - popis na - a obrázek na Opustit Přestat sledovat Kanál vytvořen @@ -390,7 +342,6 @@ Nostr Adresa nikdy nyní - sekundy h m d @@ -398,7 +349,6 @@ Neslušnost / Nenávistná řeč Nahlásit nenávistnou řeč Nahlásit nahotu / pornografii - jiné Označit všechny známé jako přečtené Označit všechny nové jako přečtené Označit všechny jako přečtené @@ -417,8 +367,6 @@ Autentizace se nezdařila Biometrické údaje se nepodařilo ověřit vlastníka tohoto telefonu Biometrické údaje se nepodařilo ověřit vlastníka tohoto telefonu. Chyba: %1$s - Chyba - "Vytvořeno uživatelem %1$s" "Obrázek ocenění od %1$s" Obrázek ocenění Obdrželi jste nové ocenění @@ -426,7 +374,6 @@ Text poznámky zkopírován do schránky Uživatelovo ID (@npub) zkopírováno do schránky ID poznámky (@note1) zkopírováno do schránky - Vybrat text "<Nelze dešifrovat soukromou zprávu>\n\nByl jste zmíněn v soukromé/zašifrované konverzaci mezi %1$s a %2$s." Přidat nový účet Účty @@ -438,8 +385,6 @@ Vybrat účet Přidat nový účet Aktivní účet - Má soukromý klíč - Pouze veřejný klíč, žádný soukromý klíč Zpět Vybrat Sdílet odkaz prohlížeče @@ -463,14 +408,12 @@ Ztlumit vlákno Zrušit ztlumení vlákna Nahlásit - Smazat Nepředvádět znovu Spam nebo podvody Sprostota nebo nenávistné chování Zákeřná zneužití Nahota nebo grafický obsah Nelegální chování - Malware Blokování uživatele skryje jejich obsah ve vaší aplikaci. Vaše poznámky jsou stále veřejně viditelné, včetně osob, které blokujete. Blokovaní uživatelé jsou uvedeni na obrazovce s bezpečnostními filtry. Nahlásit zneužití @@ -498,7 +441,6 @@ Vyberte naplánovaný čas Naplánovat na… Publikováno za %1$s - Mělo být před %1$s Čas Naplánovat příspěvek Zrušit plánování @@ -583,7 +525,6 @@ Autor Žádosti Schválení - Žádné komunity neodpovídají tomuto filtru. Ověřitelná pravidla (volitelné) Publikuje strojově čitelný dokument s pravidly (NIP-9B) společně s komunitou. Klienti, kteří jej podporují, blokují příspěvky, které neodpovídají, ještě před odesláním. Povolené typy událostí @@ -612,26 +553,15 @@ Přidat WoT bránu Globální maximální velikost události (volitelné) Bajty — pro globálně neomezenou hodnotu nech prázdné. - Obdržené - Moje - Udělené - Objevit Nový odznak - Upravit odznak Udělit odznak Přijmout Odmítnout Odebrat z profilu - ID odznaku (d-tag) - statecnost, prispevatel-2025… Název Čitelný název odznaku Popis Proč je tento odznak udělen? - URL obrázku (1024×1024) - https://example.com/badge.png - URL náhledu (volitelné) - https://example.com/badge-thumb.png Nahrát obrázek Vyberte čtvercový obrázek, který bude reprezentovat váš odznak. Načítání odznaku… @@ -640,7 +570,6 @@ Odebrat Odznak bez názvu Uděleno %1$d - Obdrželi jste odznak Profilové odznaky Odznaky · %1$d Vyberte, které z odznaků, které jste obdrželi, se zobrazí na vašem profilu. @@ -686,10 +615,6 @@ Sdílejte své tréninky Nechte Amethyst číst dokončené tréninky z Health Connect (Samsung Health, Google Fit, Fitbit, Garmin…) a navrhnout příspěvek. Připojit - Zjištěn nový trénink - Sdílet - Zavřít - %1$s tep/min Z Health Connect Běh Chůze @@ -703,7 +628,6 @@ Dieta Půst Aplikace - Aplikace Zdroj: %1$s v%1$s Stáhnout @@ -712,12 +636,10 @@ Témata Odkazy Nejnovější verze - Komentáře Buďte první, kdo přidá komentář. od Zobrazit starší verze Skrýt starší verze - Kalendáře Krátká videa Veřejné chaty Seznamy sledování @@ -727,18 +649,14 @@ Nest Pódium Čekání na řečníky… - Publikum Přihlásit se Dát ruku dolů Připojit zvuk - Odpojit Ztlumit Zrušit ztlumení - Připojování… Hledání místnosti Otevírání spojení Vyjednávání zvuku - Zvuk připojen Opětovné připojování… Poslechnout nahrávku Zprávu se nepodařilo odeslat @@ -746,9 +664,7 @@ Zavřít tuto místnost? Všichni účastníci budou odpojeni. Místnost se v kanálu zobrazí jako ZAVŘENÁ. Zavřít místnost - Vyberte čas v budoucnosti. Zvuk selhal: %1$s - Zvuk pro tuto místnost není k dispozici Mluvit Opustit pódium Ztlumit mikrofon @@ -756,7 +672,6 @@ Začíná vysílání… Vysílání selhalo: %1$s Ztlumení selhalo: %1$s - Pro mluvení v této místnosti je vyžadován přístup k mikrofonu. Otevřít nastavení Nests Přehrává zvuk, dokud je místnost otevřená. @@ -767,7 +682,6 @@ Připojit se k nestu Hostitel Otevřít - Nedávný chat V místnosti právě nikdo není. %1$d poslouchá Hostitel @@ -797,8 +711,6 @@ Publikum Ruce V publiku zatím nikdo není. - Odeslat - Něco napište… Zatím žádné zprávy. Buďte první. Reagovat Upravit místnost @@ -832,7 +744,6 @@ Akce selhala Akci nelze připravit. Sdílet místnost - Minimalizovat Minimalizovat a poslouchat dál Zvuk byl odpojen Načítání místnosti… @@ -865,7 +776,6 @@ Vyberte, na které MoQ hostitelské servery Amethyst publikuje vaše nesty. První položka se použije jako výchozí při vytváření nového prostoru. Vaše servery Uloženo jako nahraditelná událost typu kind-10112, aby ostatní klienti mohli číst vaše preference. - Přidat nest server URL relay (WebTransport) URL pro autentizaci (JWT mint) Přidat @@ -878,13 +788,11 @@ Odebrat server Zatím žádné servery. Přidejte server níže nebo vyberte z doporučených. Videa - Články Hudba Playlisty Epizody Podcasty Zobrazit epizody - Epizody Zatím nenalezeny žádné epizody %1$d epizoda @@ -898,9 +806,6 @@ Název stopy Interpret Jméno interpreta - URL zvuku - https://… .mp3 - URL obrázku obalu (volitelné) Album (volitelné) Délka v sekundách (volitelné) Text nebo kredity (volitelné) @@ -910,7 +815,6 @@ Přidat do playlistu Zatím nemáte žádné playlisty. Pomocí pole výše si nějaký vytvořte. Spravovat všechny playlisty - Nový playlist Název playlistu Vytvořit (playlist bez názvu) @@ -948,9 +852,6 @@ Smazat seznam záložek Zobrazit příspěvky Zobrazit články - Zobrazit odkazy - Zobrazit hashtagy - Zatím nemáte žádné seznamy záložek. Klepnutím na tlačítko dole vytvoříte nový. Sady zájmů Zatím nemáte žádné sady zájmů. Klepnutím na tlačítko níže vytvoříte novou. Nová sada zájmů @@ -969,7 +870,6 @@ Soukromé příspěvky(%1$s) Veřejné příspěvky Veřejné příspěvky(%1$s) - Soukromé články Soukromé články(%1$s) Veřejné články Veřejné články(%1$s) @@ -996,16 +896,6 @@ Metadata seznamů záložek může na Nostr vidět kdokoli. Šifrovaní jsou pouze vaši soukromí členové. Přesunout mezi veřejné Přesunout mezi soukromé - Služba Wallet Connect - Autorizuje Nostr Secret k provedení platby zapsům, aniž byste opustili aplikaci. Uchovávejte tajemství v bezpečí a pokud je to možné, používejte soukromý přepojovač. - Veřejný klíč Wallet Connect - Relé Wallet Connect - Tajemství Wallet Connect - Zobrazit tajný klíč - nsec / hex soukromý klíč - Připojeno - Nepřipojeno - Pokročilé: zadejte podrobnosti připojení ručně Rychlé částky Zap Zobrazí se při stisknutí tlačítka zap. Klepnutím na částku ji odeberete. Pokud ponecháte prázdné, otevře se pokaždé dialog pro zadání částky. Odeslat on-chain @@ -1037,14 +927,8 @@ Připojit peněženku Zobrazit kanál relé Částka záruky v sats - Zveřejnit hlasování - Povinná pole: - Příjemci zapsů - Hlavní popis hlasování… - Možnost Možnost %s Popis možnosti hlasování - Volitelná pole: Minimální zaps Maximální zaps Konsensus @@ -1053,11 +937,8 @@ Více možností Datum a čas ukončení ankety Anketa končí za %1$s - Uzavřít po - dnech Nebylo možné hlasovat Hlasování je uzavřeno pro nové hlasy - Částka zapsu U tohoto typu hlasování je povolen pouze jeden hlas na uživatele "Hledá se událost %1$s" Odeslat Zap @@ -1093,11 +974,8 @@ Né Zap Žádná stopa v Nostr, pouze v Lightning Anonymní - Odeslat jako novou jednorázovou identitu. Váš účet nebude s touto odpovědí spojen. - Tato odpověď bude odeslána z nové anonymní identity Souborový server Zvolte server pro nahrání tohoto souboru - LnAddress nebo @Uživatel Media Servery Nastavte preferované servery pro nahrávání médií. Použít lokální Blossom cache @@ -1106,10 +984,8 @@ Lokální cache nebyla na portu 24242 nalezena. Cachovat pouze profilové obrázky Omezit lokální cache pouze na profilové obrázky. Obrázky a videa z feedu budou stahovány přímo z původních serverů. - Nemáte nastaveny žádné servery NIP-96. Můžete použít Amethystův seznam nebo přidat některý níže ↓ Nemáte nastaveny žádné Blossom servery. Můžete použít Amethystův seznam, nebo přidat některý níže ↓ Doporučené média servery - Integrované mediální servery Výchozí seznam Amethysty. Můžete je přidat jednotlivě nebo přidat seznam. Použít výchozí seznam Přidat server médií @@ -1132,36 +1008,21 @@ Hashování Hotovo Chyba - Vaše relé (NIP-95) - Soubory jsou hostovány vašimi relé. Nový NIP: zkontrolujte, zda je podporují Nastavení ochrany soukromí - Nastavení Tor/Orbot - Připojit se přes váš Orbot Upravit Nastavení Tor - Odpojit se od Orbotu/Toru? - Vaše data budou okamžitě přenesena do běžné sítě Ano Ne - Seznam sledovaných Všechna sledování Všech Uživatelů Sledování Výchozí seznam sledování - Sleduje přes proxy Kolem mě Globální Kurátorováno - Šachy Moje Seznam ztlumení Seznamy sledování Toto jsou follow seznamy určené pro vaše vlastní použití. Můžete sledovat uživatele soukromě nebo veřejně. - Označené záložky - Obecné záložky - Veřejné - Soukromé - Smíšené - Zdá se, že zatím nemáte žádné sady sledování.\nKlepněte níže pro obnovení nebo použijte tlačítko přidat k vytvoření nové. Nový Přidat autora do seznamu sledování Přidat nebo odebrat uživatele ze seznamů, nebo vytvořit nový seznam s tímto uživatelem. @@ -1170,23 +1031,9 @@ %1$s je soukromý člen Přidat jako veřejného člena Přidat jako soukromého člena - Veřejní členové - Soukromí členové - Veřejné profily - Soukromé profily - člen - členové - Žádní členové Prázdné - %1$s není v tomto seznamu %1$s není členem Vaše seznamy a %1$s - Vaše seznamy - Nebyly nalezeny žádné seznamy sledování, nebo žádné nemáte. Klepněte níže pro obnovení, nebo použijte menu pro vytvoření nového. - Došlo k problému při načítání: %1$s - Vytvořit nový seznam - Vytvořit nový seznam %1$s s uživatelem - Vytvoří %1$s sadu sledování a přidá do ní %2$s. Nový seznam sledování Nová sada doporučení Kopírovat/Klonovat seznam sledování @@ -1206,14 +1053,6 @@ Přejmenováváte z na.. Výchozí port je 9050 - ## Připojte se přes Tor s Orbotem - \n\n1. Nainstalujte [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Spusťte Orbot - \n3. V Orbotu zkontrolujte port pro Socks. Výchozí hodnota je 9050 - \n4. Pokud je to nutné, změňte port v Orbotu - \n5. Nastavte port Socks v této obrazovce - \n6. Stiskněte tlačítko Aktivovat Tor - Port Orbot Socks Aktivní Tor Engine Použijte interní verzi nebo Orbot @@ -1255,8 +1094,6 @@ Skryjte svou IP ve všech připojeních Vytvořte si vlastní Neplatné číslo portu - Použít Orbot - Odpojit Tor/Orbot Soukromé zprávy Upozorní vás, když dorazí soukromá zpráva Přijaté zapsy @@ -1313,12 +1150,8 @@ Bluetooth Hlasový hovor Videohovor - Čekání na připojení ostatních\u2026 Přidat účastníka Hledat uživatele\u2026 - Nepodařilo se zahájit hovor - Nepodařilo se přijmout hovor - Nepodařilo se vytvořit relaci hovoru Vyžadováno oprávnění Amethyst potřebuje přístup k mikrofonu, aby mohl zahájit hlasový hovor. Povolte jej v nastavení aplikace. Amethyst potřebuje přístup ke kameře a mikrofonu, aby mohl zahájit videohovor. Povolte je v nastavení aplikace. @@ -1352,24 +1185,13 @@ Android může omezit připojení k relayím na pozadí. Vypněte optimalizaci baterie pro Amethyst, aby byla oznámení spolehlivá. Opravit Upozornit: - Připojit se ke konverzaci - ID uživatele nebo skupiny - npub, nevent nebo hex - Vytvořit - Připojit se Dnes Upozornění na obsah Upozornění: %1$s Tento příspěvek obsahuje citlivý obsah, který může být pro některé lidi urážlivý nebo rušivý - Vždy skrýt citlivý obsah - Vždy zobrazit citlivý obsah - Vždy zobrazovat upozornění na obsah Skrýt Ukázat Varovat - Doporučuje: - Filtrovat spam od cizinců - Varovat, když příspěvky obsahují hlášení od vašich sledovaných osob Filtrovat spam Skryje příspěvky od cizinců, které byly přesně stejné 5 a více krát Přidávat klientský tag do mých událostí @@ -1401,22 +1223,17 @@ Množství bajtů, které bylo odesláno na toto relé, včetně filtrů a událostí Množství bajtů, které bylo přijato z tohoto relé, včetně filtrů a událostí Uložené události - Při pokusu o získání informací z Relay se vyskytla chyba z %1$s Vlastník Používáno Servisní klíč - Spuštěno %1$s - Spuštěno %1$s (%2$s) Verze Programové vybavení Kontakt Podporované NIPs Podporované GRASPy - Vstupné Vstup Předplatné Publikování - Platby %1$s URL plateb Cílové publikum Zásady & odkazy @@ -1424,7 +1241,6 @@ Omezení Země Jazyky - Tagy Témata Všechny země Všechny jazyky @@ -1439,64 +1255,48 @@ Otevření Čtení Zápis - RTT Síť Typ Podporované NIP Požadavky - Poslední kontrola %1$d ms Přijímané druhy Poloha Aktivní odběry - Čekající události k odeslání REQ odběry (%1$d) COUNT odběry (%1$d) Události k odeslání (%1$d) - Pro tento relay nejsou žádné aktivní odběry %1$d autorů %1$d ID od %1$s do %1$s limit %1$d - Délka zprávy - Předplatné - Filtry - Délka ID předplatného Min. předpona Max. značek události - Délka obsahu Max. délka obsahu Zahazuje starší než Přijímá až %1$s v budoucnu před %1$s - %1$s nul %1$s bitů Uchovávání událostí Velikost obsahu Připojení Řízení přístupu Min. obtížnost PoW - Ověření Vyžaduje se autentizace - Platba Vyžaduje se platba Max. délka zprávy Max. odběrů Max. filtrů na odběr Max. limit (vracené události) - Výchozí limit (vracené události) Max. délka SubID Cashu Token Mint: %1$s Vyměnit - Poslat do Zap peněženky - Otevřít v Cashu Wallet Kopírovat token Otevřít v jiné aplikaci Není nastavena žádná Lightning adresa - Token zkopírován do schránky ŽIVĚ OFFLINE UKONČENO @@ -1547,7 +1347,6 @@ Stav Marmot byl resetován. Nepodařilo se resetovat stav Marmot: %1$s Vždy - Pouze Wi-Fi Neomezená WiFi Nikdy Kompletní @@ -1572,7 +1371,6 @@ Zvolte styl příspěvku Styl galerie profilu Zvolte styl galerie - Načíst obrázek Spamovací uživatelé Ztlumené. Klikněte pro odztlumení Zvuk zapnutý. Klikněte pro ztlumení @@ -1584,18 +1382,13 @@ Adresa Nostr byla ověřena Ověření adresy Nostr se nezdařilo Kontrola adresy Nostr - Vybrat/Zrušit vše Výchozí Obnovit výchozí nastavení - Vyberte relé pro pokračování - Přeposílat Zapy na: - Podporující klienti budou přeposílat Zapy na níže uvedenou LN adresu nebo uživatelský profil místo vaší Zveřejnit polohu jako Přidá Geohash vaší polohy do příspěvku. Veřejnost bude vědět, že se nacházíte do 5 km od aktuální polohy Lokace-Exkluzívní příspěvek Uvidí to pouze následovníci umístění. Tvoji obecní následovníci to neuvidí. Hashtag-exkluzivní příspěvek - Uvidí to pouze následovníci hashtagu. Tvůj všeobecní následovníci to neuvidí. Komentář k webové stránce Komentář k externímu zdroji %1$d min čtení @@ -1620,20 +1413,14 @@ Nahrát zvukový soubor Vyberte MP3, WAV nebo FLAC. Při uložení bude nahrán na váš mediální server. Zvukový soubor připraven k nahrání - Nahrávání… Nahrávání obalu a zvuku a publikování. Bude pokračovat, i když opustíte obrazovku. - Nahrávání selhalo: %1$s Načítání umístění Žádná lokace oprávnění Přidat varování o citlivém obsahu před zobrazením vašeho obsahu. Toto je ideální pro obsah NSFW (nebezpečné pro práci) nebo obsah, který někteří lidé mohou považovat za urážlivý nebo znepokojující Důvod (volitelné) - Nová funkce - Aktivace tohoto režimu vyžaduje od Amethystu odeslání zprávy NIP-17 (GiftWrapped, Zapečetěné přímé a skupinové zprávy). NIP-17 je nový a většina klientů ho zatím neimplementovala. Ujistěte se, že příjemce používá kompatibilního klienta. - Aktivovat Veřejné Skupina Nová veřejná nebo soukromá skupina - Relé Soukromé Pro Předmět @@ -1645,9 +1432,6 @@ Vysvětlení členům Změna názvu pro nové cíle. Vložit ze schránky - Neplatné NIP-47 URI - URI %1$s není platné přihlašovací URI NIP-47. - Připojit novou NWC peněženku Peněženka nebyla nalezená Amethyst nenašel žádné aplikace peněženek, které podporují Nostr Wallet Connect (NWC). \n\nCo můžete udělat: @@ -1663,7 +1447,6 @@ Automaticky přehrávat videa a GIFy Automaticky přehrávat videa, když jsou viditelná na obrazovce Zobrazit náhledy URL - Kdy načíst obrázek Kopírovat zásobník Kopírovat do schránky Zkopírováno do schránky @@ -1679,43 +1462,21 @@ Média přidána Média přidána do vaší profilové galerie Vytvořeno - Pravidla - O nás Pokyny Moderátoři Přihlásit se pomocí Amber Aktualizovat svůj stav - Chyba při zpracování chybové zprávy Hlasy jsou váženy podle hodnoty zapu. Můžete nastavit minimální částku, abyste se vyhnuli spammerům, a maximální částku, abyste zabránili velkým zapperům, kteří by mohli ovládnout hlasování. Použijte stejnou částku v obou polích, aby byla hodnota každého hlasu stejná. Nechte prázdné pro přijetí libovolné částky. Nelze odeslat zap Poslat zprávu uživateli Zpráva %1$s OK - Nepodařilo se dosáhnout %1$s: %2$s - Nepodařilo se sestavit adresu URL NIP-11 pro %1$s: %2$s - Nepodařilo se dosáhnout %1$s: %2$s - Nepodařilo se zpracovat odpověď od %1$s: %2$s - Relé odmítlo požadavek %1$s: %2$s - Nepodařilo se dosáhnout %1$s: %2$s - Nepodařilo se zpracovat výsledek z %1$s: %2$s - %1$s selhalo s kódem %2$s - Aktivní pro: - Domů - Zprávy - Chaty - Celosvětové - Hledání Rozdělit a přeposlat Zaps Podporované klienty budou Zapy rozdělovat a přeposílat uživatelům přidaným zde místo vám Hledat a přidat uživatele Uživatelské jméno nebo zobrazované jméno Chybí nastavení blesku Uživatel %1$s nemá nastavenou bleskovou adresu pro přijímání satoshi - Procenta - 25 - Rozdělování Zapů s - Přeposílání Zapů na - Bleskové peněženky nenalezený Zaplaceno Peněženka %1$s Chyba při otevírání aplikace pro podpis @@ -1724,7 +1485,6 @@ Tento kodek nebo formát není na tomto zařízení podporován (%1$s). Zkuste jej otevřít v prohlížeči. Otevřít v prohlížeči Požadavek na podpis byl zamítnut - Žádost o podpis byla zamítnuta Ujistěte se, že podepisující aplikace autorizovala tuto transakci Nebyly nalezeny žádné peněženky pro platbu bleskové faktury (Chyba: %1$s). Prosím, nainstalujte si bleskovou peněženku pro použití Zapů Nebyly nalezeny žádné peněženky pro platbu bleskové faktury. Prosím, nainstalujte si bleskovou peněženku pro použití Zapů @@ -1740,40 +1500,23 @@ Zvolte možnost Nelze zaplatit fakturu Nepodařilo se vybrat - Nepodařilo se nastavit Wallet Connect - Chyba při analýze připojení NIP-47. Zkontrolujte, zda je to správné u poskytovatele peněženky: %1$s. Chyba: %2$s - Chyba při analýze připojení NIP-47. Zkontrolujte, zda je to správné u poskytovatele peněženky: %1$s. Nepodařilo se použít Cashu Mint poskytl následující chybovou zprávu: %1$s - Tokeny Cashu již byly utraceny. Obdrženo Cashu %1$s sats bylo odesláno do vaší peněženky. (Poplatek: %2$s sats) V systému nebyla nalezena žádná kompatibilní peněženka Cashu Nebylo možné načíst fakturu ze serverů příjemce Poskytovatel připojení vaší peněženky vrátil následující chybu: %1$s - Nepodařilo se připojit k Tor Tor se nepřipojuje Amethystu se nepodařilo dokončit připojení k síti Tor. Chcete použít běžné připojení (bez Toru), aby se feed mohl načíst? Tuto volbu si zapamatujeme na hodinu a poté znovu zkusíme Tor. Použít běžné připojení Pokračovat v čekání - Stáhnout relé dokument není k dispozici Nepodařilo se sestavit LNUrl z Lightning adresy \"%1$s\". Zkontrolujte nastavení uživatele - Služba blesku příjemce v %1$s není k dispozici. Byla vypočtena z adresy blesku \"%2$s\". Chyba: %3$s. Zkontrolujte, zda je server aktivní a zda je adresa blesku správná - Nepodařilo se vyřešit %1$s. Zkontrolujte, zda jste připojeni, zda je server aktivní a zda je adresa %2$s správná - Nepodařilo se vyřešit %1$s. Zkontrolujte, zda jste připojeni, zda je server aktivní a zda je adresa %2$s správná.\n\nVýjimka byla: %3$s - Nepodařilo se načíst fakturu z %1$s Nelze získat fakturu z %1$s: %2$s - Chyba při analýze JSON z Lightning adresy. Zkontrolujte uživatelovo bleskové nastavení Chyba při analýze JSON z %1$s. Zkontrolujte uživatelské bleskové nastavení - URL adresa zpětného volání nebyla nalezena v konfiguraci serveru pro bleskovou adresu uživatele Adresa URL zpětného volání nebyla nalezena v odpovědi %1$s - Chyba při analýze JSON z načtení faktur v Lightning adrese. Zkontrolujte uživatelské nastavení - Chyba při analýze JSON z načtení faktury %1$s. Zkontrolujte uživatelské bleskové nastavení Nesprávná částka faktury(%1$s sats) od %2$s. Měla by být %3$s Nepodařilo se vytvořit bleskovou fakturu před odesláním zap. Blesková peněženka příjemce odeslala následující chybu: %1$s - Nelze vytvořit bleskovou fakturu. Zpráva od %1$s: %2$s - Nepodařilo se vytvořit bleskovou fakturu před odesláním zap. Prvek pr nebyl nalezen v výsledném JSON. - Nelze vytvořit bleskovou fakturu z %1$s: Prvek pr nebyl nalezen ve výsledném JSON. Uživatel pouze pro čtení Žádné nastavení reakcí Oznámení @@ -1799,13 +1542,11 @@ Poslat prodejci zprávu Ahoj %1$s, je to stále k dispozici? Ahoj, je to stále k dispozici? - Prodat předmět Název iPhone 13 Stav Kategorie Cena (v Sats) - 1000 Místo Město, stát, země Nový @@ -1834,20 +1575,13 @@ Ostatní Nepodařilo se nahrát média Nepodařilo se otevřít komprimovaný soubor - Chyba při komprimování média: %1$s Chyba při nahrávání: %1$s Server po nahrání neposkytl URL Nepodařilo se stáhnout nahraná média ze serveru Nelze zkontrolovat stažený soubor po nahrání: %1$s - Nelze připravit místní soubor k nahrání: %1$s Nepodařilo se dosáhnout %1$s: %2$s - Nahrání selhalo: %1$s Smazání selhalo: %1$s Média je příliš velká pro NIP-95 - Nelze načíst náhled - Nelze připravit informace v záhlaví: %1$s - Komprese zrušena - Komprese se nepodařilo vrátit soubor Šifrovat soubory Šifrovat soubory před nahráním pro ochranu soukromí. Některé servery nemusí přijímat šifrované soubory na bezplatných účtech. Šifrované nahrávání selhalo @@ -1874,27 +1608,18 @@ Nelze odstranit metadata z AVIF: %1$s Upravit koncept Přihlášení pomocí QR kódu - Trasa Domů - Hledat Objevit Zprávy Upozornění - Globální Krátké - Obrázky - Tréninky Kalendáře Seznamy kalendářů Šachy Peněženka - Zůstatek Odeslat Přijmout Transakce - Žádná peněženka není připojena - Nastavte připojení Nostr Wallet Connect (NWC) v nastavení zapů, abyste mohli peněženku používat. - Nastavit peněženku sats Vložte fakturu BOLT-11 Zaplatit @@ -1922,8 +1647,6 @@ Tímto bude připojení peněženky odebráno. Později ji můžete vždy přidat zpět. Název peněženky Moje peněženka - Vaše peněženky - Spravovat peněženky Žádné peněženky nejsou připojeny Připojte jednu nebo více NWC peněženek pro odesílání a přijímání plateb. Přidat NWC připojení @@ -1942,12 +1665,9 @@ URL mintu Odebrat mint Historie - Upravit peněženku Klíč pro nutzap (pokročilé) Samostatný soukromý klíč používaný pouze k příjmu nutzapů NIP-61. Není to klíč vaší identity Nostr. Vygenerovat nový klíč - Zneplatní všechny čekající nutzapy uzamčené ke stávajícímu klíči. - Ponechat stávající klíč Soukromý klíč P2PK (hex) Upravit peněženku Cashu Uložit změny @@ -1967,7 +1687,6 @@ Oblíbené minty Odpovídající minty - Doporučit tento mint Přijmout Poslat LN Poslat token @@ -2027,10 +1746,6 @@ Uložit Přejmenovat Přejmenovat peněženku - Upravit - Neplatné URI NWC připojení - Posunout nahoru - Posunout dolů On-chain transakce Pro tento účet není k dispozici žádná on-chain adresa. Není nakonfigurován žádný on-chain backend. @@ -2115,17 +1830,13 @@ Platba odeslána (zveřejněno %1$d z %2$d potvrzení), ale další potvrzení se nepodařilo zveřejnit Platba odeslána (zveřejněno %1$d z %2$d potvrzení), ale další potvrzení se nepodařilo zveřejnit - Bezpečnostní filtry Importovat sledované Nový příspěvek Nové Shorts: obrázky nebo videa Nová poznámka komunity Nový produkt - Nový geoexkluzivní příspěvek Nový článek Nová anketa - Nová zap anketa - Nová běžná anketa Nový obrázek Nová událost kalendáře Upravit událost kalendáře @@ -2140,8 +1851,6 @@ Den Nadcházející Minulé - Z vybraného kanálu zatím nejsou žádné nadcházející ani minulé události. - Zatím žádné kalendářové seznamy. Váš kalendář je prázdný Události sdílené lidmi, které sledujete, se zobrazí zde. Klepnutím na tlačítko + vytvořte vlastní. Zatím žádné seznamy @@ -2168,8 +1877,6 @@ Další týden Předchozí den Další den - V tento den nejsou žádné události - Žádné události Pokračuje Den %1$d z %2$d Přidat do kalendáře v telefonu @@ -2235,7 +1942,6 @@ Vybraný obrázek se nepodařilo nahrát. Zkuste to znovu nebo vložte URL. Účastníci (%1$d) Hledat jméno, npub nebo nip-05 - Zadejte platný npub… nebo 64znakový hex pubkey. Odebrat účastníka Připomenutí kalendáře Posílat připomenutí @@ -2258,10 +1964,7 @@ Detail události Nové krátké video Nové dlouhé video - Název Shrnutí (volitelné) - URL obrázku obálky (volitelné) - Napište svůj článek v markdownu… Náhled Upravit Přidat úvodní obrázek @@ -2345,18 +2048,14 @@ Relé %1$s Rozbalit seznam relací Volby poznámky - Výběr seznamu relé Anketa Vypnout anketu Bitcoinová faktura Zrušit Bitcoinovou fakturu - Zrušit prodej položky Zap-sběr Zrušit Zap-zběrku Místo Odstranit umístění - Zap splits - Zrušit rozdělení Zap Přidat upozornění na obsah Odstranit upozornění na obsah Přidat datum vypršení @@ -2371,11 +2070,8 @@ Neplatná adresa Amethyst obdržel URI k otevření, ale tento URI byl neplatný: %1$s Relé DM Schránky - Relé: %1$s - Používání běžných relé Nastavte svá relé soukromé schránky Toto nastavení umožňuje všem vědět, která relé použít při posílání zpráv vám. Bez nich můžete některé zprávy zmeškat. - Dobré možnosti jsou:\n - inbox.nostr.wine (placené)\n - you.nostr1.com (osobní relé - placené) Dobré možnosti jsou:\n - auth.nostr1.com (zdarma)\n - inbox.nostr.wine (placeno)\n - relay.0xchat.com (zdarma) Vložte 1–3 relé, která budou sloužit jako vaše soukromá schránka. Relé DM schránky by měla přijímat jakékoli zprávy od kohokoli, ale pouze vám umožnit jejich stahování. Nastavit nyní @@ -2395,7 +2091,6 @@ Vytvoření seznamu relayů určených pro přijímání oznámení je zásadní pro váš zážitek z Nostr. Vložte 1–3 relaye, které přijímají oznámení pro vás. Ujistěte se, že nevyžadují platbu ani web of trust od odesílatele, jinak budete dostávat oznámení pouze od plátců nebo dlouhodobých uživatelů. Dobré možnosti jsou:\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social - Nahrát v DM Nastavení relé Přeřadit relé Veřejná domácí relé @@ -2412,12 +2107,8 @@ Relays, kde jsou publikovány vaše MLS KeyPackages (MIP-00). Ostatní uživatelé je stahují, aby vás mohli pozvat do Marmot skupinových chatů. Vložte 1–3 relays, které přijímají KeyPackage události od vás a umožňují veřejné čtení. Soukromá relé Vložte mezi 1–3 relé pro ukládání událostí nikoho jiného, jako jsou koncepty a/nebo nastavení aplikace. V ideálním případě jsou tato relé buď lokální, nebo vyžadují autentizaci před stažením obsahu každého uživatele. - Obecná relé - Amethyst používá tato relé ke stahování příspěvků pro vás. Připojené přenašeče Aktuální seznam používaných přenašečů - Doporučené relé - Pro příjem příspěvků od uvedených uživatelů přidejte následující relé do seznamu obecných relat. Vyhledávací relé Seznam relé, která se používají k vyhledávání a označování uživatelů. Označování a vyhledávání nebude fungovat, pokud nejsou k dispozici žádné možnosti. Lokální relé @@ -2452,11 +2143,8 @@ Tato verze byla představena pro vás: Verze %1$s Děkujeme! - Maximální limit Omezené zápisy Rozštěpováno od - FORK - Git repositář: %1$s Internet: Klon: Otevřeno @@ -2481,20 +2169,13 @@ Upravit článek Upravit příspěvek Návrh na vylepšení vašeho příspěvku - Souhrn změn - Rychlé opravy… Přijmout návrhy Spustit video ve vyskakovacím okně Stáhnout - Text písně zapnuto - Text písně vypnuto - Zapečetěná zpráva vypnuta. Klikněte pro zapnutí zapečetěné zprávy - Zapečetěná zpráva zapnuta. Klikněte pro vypnutí zapečetěné zprávy Odeslat Přehrát uživatelské jméno jako audio Připínáček Skenovat QR kód - Přejít na poskytovatele peněženky třetí strany Alby Vyberte datum Není možné odpovědět na koncept Není možné citovat koncept @@ -2536,23 +2217,18 @@ Nedostatečné úložiště - Server nemá dostatek úložiště, aby úspěšně zpracoval požadavek Detekována smyčka - Server detekuje nekonečnou smyčku při zpracování požadavku Vyžadováno ověření sítě - Klient musí být autentizován, aby získal přístup k síti - NIP-96 Servery - Přidejte tolik serverů, kolik chcete. Můžete si vybrat, které použít později při nahrávání obrázku Blossom Servery Přidejte tolik serverů, kolik chcete. Můžete si vybrat, které použít později při nahrávání obrázku Přidat NIP-96 server Přidat Blossom Server Vymazat vše Opravdu chcete odstranit všechny koncepty? - Zásobník: Torrent soubor Stáhnout Nepodařilo se otevřít soubor Pro otevření a stažení souboru nejsou nainstalovány žádné torrent aplikace. Událost nemá dostatek informací pro vytvoření magnet odkazu - Moje seznamy/sady Moje seznamy - Uživatelé Vyberte seznam pro filtrování kanálu Kanály Hashtagy @@ -2583,7 +2259,6 @@ Soukromá zpráva Veřejná zpráva Relé chatu - Relé, ke kterému se všichni uživatelé tohoto chatu připojují Sdílet obrázek… Nelze sdílet obrázek, zkuste to prosím později… Sdílet video… @@ -2630,7 +2305,6 @@ Chcete poslat poslední záznam o pádu do Amethystu v soukromé zprávě? Žádné osobní údaje nebudou sdíleny Odeslat Tato zpráva zmizí za %1$s - Tato zpráva zmizí za %1$d dní Vybrat podepisovatele Již v seznamu Soukromí členové @@ -2652,7 +2326,6 @@ Název sady Nový název sady Popis sady - Nový popis sady Broadcast seznamu Broadcast sady doporučení Smazat seznam @@ -2666,13 +2339,9 @@ Sbalit Rozbalit Opakovat selhané (%1$d) - +%1$d dalších odesílání - " (%1$d probíhá)" - %1$d/%2$d relayů Časový limit vypršel Opakuje se… Opakovat - Zobrazit Zavřít %1$d/%2$d Odesílání @@ -2698,7 +2367,6 @@ Restartovat Přijmout Odmítnout - Nová hra Nová šachová hra Načítání hry… Hra nenalezena @@ -2853,23 +2521,13 @@ Profil, ze kterého importovat hledání jména, npub1…, alice@example.com Podporuje npub, NIP-05, hex a Namecoin (.bit / d/ / id/) - Vyhledat seznam sledovaných Tip Nalezeno účtů: %1$d Vybráno: %1$d - Přeloženo přes Namecoin - Nyní sledujete %1$d účtů - Váš feed je připraven. - Přeskočit - Hledat jiný Sledovat %1$d účtů - Importovat více - Pokračovat Prozatím přeskočit - Překládám %1$s… Načítám seznam sledovaných… Žádní sledovaní nenalezeni - Sleduji %1$d účtů… "Zadejte profil přítele nebo lídra komunity. Můžete použít jejich npub, NIP-05 adresu nebo Namecoin jméno jako alice@example.bit nebo id/alice pro identity ověřené blockchainem." Vybrat vše %1$d%% dostupnost @@ -2877,7 +2535,6 @@ Otestovat připojení Testování serverů… Připojeno - Selhalo Výsledky testu Diagnostika Poslední test @@ -2890,9 +2547,6 @@ Důvěřovat Odmítnout Synchronizace relé - Synchronizace relé - Znovu publikujte své události na všech známých relé, aby byly vaše relé pro odchozí, příchozí a DM zprávy aktuální. Vyžaduje Wi-Fi — může spotřebovat velké množství dat. - Otevřít synchronizaci relé… Co toto provede Tento nástroj prohledá všechna relé, která vaše aplikace viděla, a přerozdělí vaše události na správná místa určení: Stáhne všechny události, které jste vytvořili, a odešle je na vaše odchozí relé. @@ -2902,14 +2556,9 @@ Použít mobilní data? Spustit synchronizaci Spustit přesto (mobilní data) - Pozastavit - Pokračovat - Začít znovu Zrušit Relé: %1$d / %2$d Přerozděleno událostí: %1$d nových z %2$d odeslaných a %3$d přijatých - Synchronizace pozastavena - Dokončeno %1$d z %2$d relé — dosud přerozděleno %3$d událostí. Klepněte na Pokračovat. Synchronizace dokončena Předáno %1$d událostí na cílová relé z %2$d přijatých. %1$d událostí přijato jako nové cílovými relé. @@ -2924,16 +2573,13 @@ odesláno %1$s přijato %1$s nových %1$s - žádné události Průzkumník Bitcoin (OTS) - události události od vás události pro vás vyhledatelné události DMs profily odchozí seznamy - nastavení relé Naposledy viděn před %1$s Naposledy viděn %1$s (před %2$s) Naposledy viděn právě teď @@ -3007,7 +2653,6 @@ Hledání zařízení ve vaší Wi-Fi… HLS nahrávání - Publikujte multi-rozlišení HLS na váš media server Vyberte video Vaše video bude přepsáno do více rozlišení, aby si diváci užili plynulé přehrávání na jakémkoli připojení. Změnit @@ -3022,10 +2667,6 @@ H.265 není na tomto zařízení dostupný — používá se H.264. Rozlišení Zdrojové rozlišení: %1$d×%2$d - Bude vytvořeno: %1$s - (%1$s přeskočeno — nad zdrojem) - %1$d kbps - nad zdrojem — bude přeskočeno Publikovat HD video Publikování „%1$s“… Překódování %1$s @@ -3037,7 +2678,6 @@ Video publikováno Vaše HD video je publikováno na Nostr. Něco se pokazilo - Zobrazit poznámku Hotovo Zkusit znovu Akce balíčku @@ -3052,30 +2692,21 @@ Atestace Platná Neplatná - Přijata - Zamítnuta Ověřování - Ověřena Odvolána Platná od %1$s Platná do %1$s Žádost o atestaci - Žádost o atestaci události Doporučení atestátora Doporučen pro druhy: Odbornost atestátora - Odborník na ověřování druhů: %1$s - Potvrzuje Žádosti o atestaci pro Časové rozmezí Od Do Nyní Vždy - Poslední synchronizace: %1$s - Od poslední synchronizace Webové záložky - Zatím žádné webové záložky. Klepněte na + pro přidání. Přidat webovou záložku Upravit webovou záložku URL @@ -3118,13 +2749,10 @@ https://example.com/image.jpg URL webu (volitelné) https://example.com - Termín (volitelný) Nastavit termín Nový cíl - Vytvořit cíl Žádost o zmizení Požádejte relé o trvalé smazání všech vašich dat do vybraného data. Tato akce je založena na NIP-62 a v některých jurisdikcích je právně závazná. - Vybrat relé Cílové relé VŠECHNA RELÉ Toto požádá VŠECHNA relé o smazání všeho spojeného s vaším klíčem do vybraného data. Tato událost bude vysílána co nejšířeji. Tuto akci nelze vrátit zpět. @@ -3140,7 +2768,6 @@ Vybrat datum Vybrat čas Historie zmizení - Obnovit Toto jsou vaše minulé události Žádost o zmizení nalezené na připojených relé. Relé označená v těchto událostech by neměla uchovávat žádná vaše data z doby před datem události. Nebyly nalezeny žádné žádosti o zmizení Zatím jste neodeslali žádné události Žádost o zmizení. @@ -3183,7 +2810,6 @@ Zakázat událost Povolit druh Blokovat IP - Veřejný klíč (hex) ID události (hex) Číslo druhu IP adresa @@ -3194,7 +2820,6 @@ Název relé Popis relé URL ikony relé - Spravovat relé Spravovat Členové Členové %1$s @@ -3265,7 +2890,6 @@ Akce emoji balíčku Moje emoji balíčky Emoji - Procházet sady emoji Soukromé Soukromé emoji Veřejná emoji jsou viditelná pro všechny a objeví se ve vaší nabídce reakcí a v automatickém doplňování \":\", když je tento balíček ve vašem seznamu emoji. @@ -3290,4 +2914,10 @@ Nowhere Drop Nowhere Umění Nowhere Fórum + + Služba blesku příjemce v %1$s není k dispozici. Byla vypočtena z adresy blesku \"%2$s\". Chyba: %3$s. Zkontrolujte, zda je server aktivní a zda je adresa blesku správná + Nepodařilo se vyřešit %1$s. Zkontrolujte, zda jste připojeni, zda je server aktivní a zda je adresa %2$s správná.\n\nVýjimka byla: %3$s + Chyba při analýze JSON z načtení faktury %1$s. Zkontrolujte uživatelské bleskové nastavení + Nelze vytvořit bleskovou fakturu. Zpráva od %1$s: %2$s + Nelze vytvořit bleskovou fakturu z %1$s: Prvek pr nebyl nalezen ve výsledném JSON. diff --git a/amethyst/src/main/res/values-cs/strings.xml b/amethyst/src/main/res/values-cs/strings.xml index d77c6e526d..6f8943f5ec 100644 --- a/amethyst/src/main/res/values-cs/strings.xml +++ b/amethyst/src/main/res/values-cs/strings.xml @@ -21,8 +21,6 @@ Nezákonné jednání Jiný Obtěžování - Neznámý - Ikona předávání Neznámý autor Kopírovat text Kopírovat ID autora @@ -36,12 +34,9 @@ Nahlásit spam / podvod Nahlásit zneužívání identity - Nahlásit explicitní obsah Nahlásit nezákonné jednání Nahlásit malware - Nahlásit mód Malware - Mód Pro odpověď se přihlaste s privátním klíčem Pro zvýšení příspěvků se přihlaste s privátním klíčem Přihlásit se pomocí soukromého klíče pro označení příspěvků jako líbivé @@ -52,7 +47,6 @@ Používáte veřejný klíč a veřejné klíče jsou pouze pro čtení. Přihlaste se pomocí soukromého klíče, abyste mohli skrýt slovo nebo větu Používáte veřejný klíč a veřejné klíče jsou pouze pro čtení. Přihlaste se pomocí soukromého klíče, abyste mohli zobrazit slovo nebo větu Zapy - Počet zobrazení Zvýšení zvýšeno upraveno @@ -65,9 +59,7 @@ Přidat "odpovídá na " " a " - "v kanálu " Banner profilu - Platba úspěšná Chyba při zpracování chybové zprávy " Sleduje" " Sledující" @@ -89,9 +81,7 @@ Viditelná předpona 😎 Přidat k příspěvku - "Chyba při zpracování náhledu pro %1$s : %2$s" "Náhled obrázku karty pro %1$s" - Nový kanál Název kanálu Má skvělá skupina URL obrázku @@ -102,33 +92,18 @@ Uložit Vytvořit Zrušit - Selhalo nahrávání obrázku - Adresa relé - Příspěvky - Byty Chyby - Počet chyb připojení v této relaci - Domovský kanál - Kanál soukromých zpráv - Kanál veřejného chatu - Globální kanál - Kanál vyhledávání Přidat přeposílání - Jméno Zobrazované jméno Moje zobrazované jméno Ostrich McAwesome Vítejte Ostrich! Uživatelské jméno - Moje uživatelské jméno O mně URL avatara URL banneru URL webové stránky Zájmena - LN adresa - LN URL (zastaralé) - Uložit do galerie Obrázek uložen do galerie Stahování videa bylo zahájeno… Stahování médií bylo zahájeno… @@ -136,11 +111,8 @@ Video uloženo do video galerie telefonu Nepodařilo se uložit video Nahrát obrázek - Nahrávání… Uživatel nemá nastavenou LN adresu pro přijímání sats "Odpověď zde…" - Zkopíruje ID poznámky do schránky pro sdílení - Zkopírovat ID kanálu (poznámka) do schránky Upravit metadata kanálu Připojit se Známé @@ -152,18 +124,14 @@ Odpovědi Vaše Galerie - "Sleduje" "Zprávy" Více možností " Přeposílání" Webová stránka Lightning adresa Zkopíruje Nsec ID (vaše heslo) do schránky pro zálohování - Zkopírovat tajný klíč do schránky Zobrazit QR kód privátního klíče Zobrazit šifrovaný QR kód soukromého klíče - Zkopíruje veřejný klíč do schránky pro sdílení - Zkopírovat veřejný klíč (NPub) do schránky Poslat přímou zprávu Upravit uživatelova metadata Sledovat @@ -192,8 +160,6 @@ Jak bychom vám měli říkat? Nemáte Nostr účet? Máte již Nostr účet? - Vytvořit nový účet - Vygenerovat nový klíč Načítání zdroje Načítání účtu "Chyba při načítání odpovědí: " @@ -201,12 +167,6 @@ Zatím žádná oznámení. Zdroj je prázdný. Obnovit - vytvořeno - s popisem - a obrázkem - změnil název chatu na - popis na - a obrázek na Opustit Přestat sledovat Kanál vytvořen @@ -239,7 +199,6 @@ Neslušnost / Nenávistná řeč Nahlásit nenávistnou řeč Nahlásit nahotu / pornografii - jiné Označit všechny známé jako přečtené Označit všechny nové jako přečtené Označit všechny jako přečtené @@ -258,23 +217,18 @@ Autentizace se nezdařila Biometrické údaje se nepodařilo ověřit vlastníka tohoto telefonu Biometrické údaje se nepodařilo ověřit vlastníka tohoto telefonu. Chyba: %1$s - Chyba - "Vytvořeno uživatelem %1$s" "Obrázek ocenění od %1$s" Obdrželi jste nové ocenění Ocenění uděleno uživateli Text poznámky zkopírován do schránky Uživatelovo ID (@npub) zkopírováno do schránky ID poznámky (@note1) zkopírováno do schránky - Vybrat text "<Nelze dešifrovat soukromou zprávu>\n\nByl jste zmíněn v soukromé/zašifrované konverzaci mezi %1$s a %2$s." Přidat nový účet Účty Vybrat účet Přidat nový účet Aktivní účet - Má soukromý klíč - Pouze veřejný klíč, žádný soukromý klíč Zpět Vybrat Sdílet odkaz prohlížeče @@ -292,14 +246,12 @@ Smazat Blokovat Nahlásit - Smazat Nepředvádět znovu Spam nebo podvody Sprostota nebo nenávistné chování Zákeřná zneužití Nahota nebo grafický obsah Nelegální chování - Malware Blokování uživatele skryje jejich obsah ve vaší aplikaci. Vaše poznámky jsou stále veřejně viditelné, včetně osob, které blokujete. Blokovaní uživatelé jsou uvedeni na obrazovce s bezpečnostními filtry. Nahlásit zneužití @@ -319,30 +271,15 @@ Přidat do veřejných záložek Odebrat ze soukromých záložek Odebrat z veřejných záložek - Služba Wallet Connect - Autorizuje Nostr Secret k provedení platby zapsům, aniž byste opustili aplikaci. Uchovávejte tajemství v bezpečí a pokud je to možné, používejte soukromý přepojovač. - Veřejný klíč Wallet Connect - Relé Wallet Connect - Tajemství Wallet Connect - Zobrazit tajný klíč - nsec / hex soukromý klíč Částka záruky v sats - Zveřejnit hlasování - Povinná pole: - Příjemci zapsů - Hlavní popis hlasování… Možnost %s Popis možnosti hlasování - Volitelná pole: Minimální zaps Maximální zaps Konsensus (0–100)% - Uzavřít po - dnech Nebylo možné hlasovat Hlasování je uzavřeno pro nové hlasy - Částka zapsu U tohoto typu hlasování je povolen pouze jeden hlas na uživatele "Hledá se událost %1$s" Přidat veřejnou zprávu @@ -376,12 +313,9 @@ Žádná stopa v Nostr, pouze v Lightning Souborový server Zvolte server pro nahrání tohoto souboru - LnAddress nebo @Uživatel Media Servery Nastavte preferované servery pro nahrávání médií. - Nemáte nastaveny žádné servery NIP-96. Můžete použít Amethystův seznam nebo přidat některý níže ↓ Nemáte nastaveny žádné Blossom servery. Můžete použít Amethystův seznam, nebo přidat některý níže ↓ - Integrované mediální servery Výchozí seznam Amethysty. Můžete je přidat jednotlivě nebo přidat seznam. Použít výchozí seznam Přidat server médií @@ -394,31 +328,16 @@ Hashování Hotovo Chyba - Vaše relé (NIP-95) - Soubory jsou hostovány vašimi relé. Nový NIP: zkontrolujte, zda je podporují Nastavení ochrany soukromí - Nastavení Tor/Orbot - Připojit se přes váš Orbot Upravit Nastavení Tor - Odpojit se od Orbotu/Toru? - Vaše data budou okamžitě přenesena do běžné sítě Ano Ne - Seznam sledovaných Všechna sledování Kolem mě Globální Seznam ztlumení Výchozí port je 9050 - ## Připojte se přes Tor s Orbotem - \n\n1. Nainstalujte [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Spusťte Orbot - \n3. V Orbotu zkontrolujte port pro Socks. Výchozí hodnota je 9050 - \n4. Pokud je to nutné, změňte port v Orbotu - \n5. Nastavte port Socks v této obrazovce - \n6. Stiskněte tlačítko Aktivovat Tor - Port Orbot Socks Aktivní Tor Engine Použijte interní verzi nebo Orbot @@ -460,8 +379,6 @@ Skryjte svou IP ve všech připojeních Vytvořte si vlastní Neplatné číslo portu - Použít Orbot - Odpojit Tor/Orbot Soukromé zprávy Upozorní vás, když dorazí soukromá zpráva Přijaté zapsy @@ -470,20 +387,9 @@ Od %1$s pro %1$s Upozornit: - Připojit se ke konverzaci - ID uživatele nebo skupiny - npub, nevent nebo hex - Vytvořit - Připojit se Dnes Upozornění na obsah Tento příspěvek obsahuje citlivý obsah, který může být pro některé lidi urážlivý nebo rušivý - Vždy skrýt citlivý obsah - Vždy zobrazit citlivý obsah - Vždy zobrazovat upozornění na obsah - Doporučuje: - Filtrovat spam od cizinců - Varovat, když příspěvky obsahují hlášení od vašich sledovaných osob Nový symbol reakce Nebyly vybrány žádné typy reakcí. Dlouhým stiskem změňte Zap-sběr @@ -494,37 +400,24 @@ Zapisovat do Relay Množství bajtů, které bylo odesláno na toto relé, včetně filtrů a událostí Množství bajtů, které bylo přijato z tohoto relé, včetně filtrů a událostí - Při pokusu o získání informací z Relay se vyskytla chyba z %1$s Vlastník Verze Programové vybavení Kontakt Podporované NIPs - Vstupné URL plateb Omezení Země Jazyky - Tagy Politika příspěvků Chyby a upozornění z tohoto relé - Délka zprávy - Předplatné - Filtry - Délka ID předplatného Minimální předpona Maximální počet značek události - Délka obsahu Minimální PoW - Ověření - Platba Cashu Token Vyměnit - Poslat do Zap peněženky - Otevřít v Cashu Wallet Kopírovat token Není nastavena žádná Lightning adresa - Token zkopírován do schránky ŽIVĚ OFFLINE UKONČENO @@ -544,7 +437,6 @@ Nastavení aplikace Nastavení Vždy - Pouze Wi-Fi Neomezená WiFi Nikdy Hotovo @@ -568,7 +460,6 @@ Zvolte styl příspěvku Styl galerie profilu Zvolte styl galerie - Načíst obrázek Spamovací uživatelé Ztlumené. Klikněte pro odztlumení Zvuk zapnutý. Klikněte pro ztlumení @@ -576,12 +467,8 @@ Adresa Nostr byla ověřena Ověření adresy Nostr se nezdařilo Kontrola adresy Nostr - Vybrat/Zrušit vše Výchozí Obnovit výchozí nastavení - Vyberte relé pro pokračování - Přeposílat Zapy na: - Podporující klienti budou přeposílat Zapy na níže uvedenou LN adresu nebo uživatelský profil místo vaší Zveřejnit polohu jako Přidá Geohash vaší polohy do příspěvku. Veřejnost bude vědět, že se nacházíte do 5 km od aktuální polohy Lokace-Exkluzívní příspěvek @@ -589,9 +476,6 @@ Načítání umístění Žádná lokace oprávnění Přidat varování o citlivém obsahu před zobrazením vašeho obsahu. Toto je ideální pro obsah NSFW (nebezpečné pro práci) nebo obsah, který někteří lidé mohou považovat za urážlivý nebo znepokojující - Nová funkce - Aktivace tohoto režimu vyžaduje od Amethystu odeslání zprávy NIP-17 (GiftWrapped, Zapečetěné přímé a skupinové zprávy). NIP-17 je nový a většina klientů ho zatím neimplementovala. Ujistěte se, že příjemce používá kompatibilního klienta. - Aktivovat Veřejné Nová veřejná nebo soukromá skupina Soukromé @@ -608,7 +492,6 @@ Automaticky načítat obrázky a GIFy Automaticky přehrávat videa a GIFy Zobrazit náhledy URL - Kdy načíst obrázek Kopírovat zásobník Kopírovat do schránky Kopírovat npub do schránky @@ -619,45 +502,23 @@ Média přidána Média přidána do vaší profilové galerie Vytvořeno - Pravidla Přihlásit se pomocí Amber Aktualizovat svůj stav - Chyba při zpracování chybové zprávy Hlasy jsou váženy podle hodnoty zapu. Můžete nastavit minimální částku, abyste se vyhnuli spammerům, a maximální částku, abyste zabránili velkým zapperům, kteří by mohli ovládnout hlasování. Použijte stejnou částku v obou polích, aby byla hodnota každého hlasu stejná. Nechte prázdné pro přijetí libovolné částky. Nelze odeslat zap Poslat zprávu uživateli Zpráva %1$s OK - Nepodařilo se dosáhnout %1$s: %2$s - Nepodařilo se sestavit adresu URL NIP-11 pro %1$s: %2$s - Nepodařilo se dosáhnout %1$s: %2$s - Nepodařilo se zpracovat odpověď od %1$s: %2$s - Relé odmítlo požadavek %1$s: %2$s - Nepodařilo se dosáhnout %1$s: %2$s - Nepodařilo se zpracovat výsledek z %1$s: %2$s - %1$s selhalo s kódem %2$s - Aktivní pro: - Domů - Zprávy - Chaty - Celosvětové - Hledání Rozdělit a přeposlat Zaps Podporované klienty budou Zapy rozdělovat a přeposílat uživatelům přidaným zde místo vám Hledat a přidat uživatele Uživatelské jméno nebo zobrazované jméno Chybí nastavení blesku Uživatel %1$s nemá nastavenou bleskovou adresu pro přijímání satoshi - Procenta - 25 - Rozdělování Zapů s - Přeposílání Zapů na - Bleskové peněženky nenalezený Zaplaceno Peněženka %1$s Chyba při otevírání aplikace pro podpis Signner aplikace nebyla nalezena. Zkontrolujte, zda aplikace nebyla odinstalována - Žádost o podpis byla zamítnuta Ujistěte se, že podepisující aplikace autorizovala tuto transakci Nebyly nalezeny žádné peněženky pro platbu bleskové faktury (Chyba: %1$s). Prosím, nainstalujte si bleskovou peněženku pro použití Zapů Nebyly nalezeny žádné peněženky pro platbu bleskové faktury. Prosím, nainstalujte si bleskovou peněženku pro použití Zapů @@ -668,36 +529,19 @@ Zvolte možnost Nelze zaplatit fakturu Nepodařilo se vybrat - Nepodařilo se nastavit Wallet Connect - Chyba při analýze připojení NIP-47. Zkontrolujte, zda je to správné u poskytovatele peněženky: %1$s. Chyba: %2$s - Chyba při analýze připojení NIP-47. Zkontrolujte, zda je to správné u poskytovatele peněženky: %1$s. Nepodařilo se použít Cashu Mint poskytl následující chybovou zprávu: %1$s - Tokeny Cashu již byly utraceny. Obdrženo Cashu %1$s sats bylo odesláno do vaší peněženky. (Poplatek: %2$s sats) V systému nebyla nalezena žádná kompatibilní peněženka Cashu Nebylo možné načíst fakturu ze serverů příjemce Poskytovatel připojení vaší peněženky vrátil následující chybu: %1$s - Nepodařilo se připojit k Tor - Stáhnout relé dokument není k dispozici Nepodařilo se sestavit LNUrl z Lightning adresy \"%1$s\". Zkontrolujte nastavení uživatele - Služba blesku příjemce v %1$s není k dispozici. Byla vypočtena z adresy blesku \"%2$s\". Chyba: %3$s. Zkontrolujte, zda je server aktivní a zda je adresa blesku správná - Nepodařilo se vyřešit %1$s. Zkontrolujte, zda jste připojeni, zda je server aktivní a zda je adresa %2$s správná - Nepodařilo se vyřešit %1$s. Zkontrolujte, zda jste připojeni, zda je server aktivní a zda je adresa %2$s správná.\n\nVýjimka byla: %3$s - Nepodařilo se načíst fakturu z %1$s Nelze získat fakturu z %1$s: %2$s - Chyba při analýze JSON z Lightning adresy. Zkontrolujte uživatelovo bleskové nastavení Chyba při analýze JSON z %1$s. Zkontrolujte uživatelské bleskové nastavení - URL adresa zpětného volání nebyla nalezena v konfiguraci serveru pro bleskovou adresu uživatele Adresa URL zpětného volání nebyla nalezena v odpovědi %1$s - Chyba při analýze JSON z načtení faktur v Lightning adrese. Zkontrolujte uživatelské nastavení - Chyba při analýze JSON z načtení faktury %1$s. Zkontrolujte uživatelské bleskové nastavení Nesprávná částka faktury (%1$s sats) od %2$s. Měla by být %3$s Nepodařilo se vytvořit bleskovou fakturu před odesláním zap. Blesková peněženka příjemce odeslala následující chybu: %1$s - Nelze vytvořit bleskovou fakturu. Zpráva od %1$s: %2$s - Nepodařilo se vytvořit bleskovou fakturu před odesláním zap. Prvek pr nebyl nalezen v výsledném JSON. - Nelze vytvořit bleskovou fakturu z %1$s: Prvek pr nebyl nalezen ve výsledném JSON. Uživatel pouze pro čtení Žádné nastavení reakcí Vyberte distributor push oznámení @@ -715,13 +559,11 @@ Poslat prodejci zprávu Ahoj %1$s, je to stále k dispozici? Ahoj, je to stále k dispozici? - Prodat předmět Název iPhone 13 Stav Kategorie Cena (v Sats) - 1000 Místo Město, stát, země Nový @@ -750,20 +592,13 @@ Ostatní Nepodařilo se nahrát média Nepodařilo se otevřít komprimovaný soubor - Chyba při komprimování média: %1$s Chyba při nahrávání: %1$s Server po nahrání neposkytl URL Nepodařilo se stáhnout nahraná média ze serveru Nelze zkontrolovat stažený soubor po nahrání: %1$s - Nelze připravit místní soubor k nahrání: %1$s Nepodařilo se dosáhnout %1$s: %2$s - Nahrání selhalo: %1$s Smazání selhalo: %1$s Média je příliš velká pro NIP-95 - Nelze načíst náhled - Nelze připravit informace v záhlaví: %1$s - Komprese zrušena - Komprese se nepodařilo vrátit soubor Kvalita médií Vyberte Nízkou kvalitu pro kompresi médií na menší soubor s nižší kvalitou, Vysokou kvalitu pro kompresi na větší soubor s vyšší kvalitou, nebo \"Bez komprese\" pro nahrání médií bez komprese. Nízká @@ -772,15 +607,11 @@ Bez komprese Upravit koncept Přihlášení pomocí QR kódu - Trasa Domů - Hledat Objevit Zprávy Upozornění - Globální Krátké - Bezpečnostní filtry Nový příspěvek Nové Shorts: obrázky nebo videa Nová poznámka komunity @@ -795,29 +626,22 @@ Relé %1$s Rozbalit seznam relací Volby poznámky - Výběr seznamu relé Anketa Vypnout anketu Bitcoinová faktura Zrušit Bitcoinovou fakturu - Zrušit prodej položky Zap-sběr Zrušit Zap-zběrku Místo Odstranit umístění - Zap splits - Zrušit rozdělení Zap Přidat upozornění na obsah Odstranit upozornění na obsah Zobrazit npub jako QR kód Neplatná adresa Amethyst obdržel URI k otevření, ale tento URI byl neplatný: %1$s Relé DM Schránky - Relé: %1$s - Používání běžných relé Nastavte svá relé soukromé schránky Toto nastavení umožňuje všem vědět, která relé použít při posílání zpráv vám. Bez nich můžete některé zprávy zmeškat. - Dobré možnosti jsou:\n - inbox.nostr.wine (placené)\n - you.nostr1.com (osobní relé - placené) Dobré možnosti jsou:\n - auth.nostr1.com (zdarma)\n - inbox.nostr.wine (placeno)\n - relay.0xchat.com (zdarma) Vložte 1–3 relé, která budou sloužit jako vaše soukromá schránka. Relé DM schránky by měla přijímat jakékoli zprávy od kohokoli, ale pouze vám umožnit jejich stahování. Nastavit nyní @@ -826,7 +650,6 @@ Vytvoření seznamu relé speciálně navržených pro vyhledávání a označování uživatelů zlepší tyto výsledky. Vložte mezi 1–3 relé, která chcete použít při vyhledávání obsahu nebo označování uživatelů. Ujistěte se, že vaše vybraná relé implementují NIP-50 Dobré možnosti jsou:\n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com - Nahrát v DM Nastavení relé Veřejná domácí relé Tento typ relé ukládá veškerý váš obsah. Amethyst sem pošle vaše příspěvky a ostatní použijí tato relé, aby našli váš obsah. Vložte mezi 1–3 relé. Mohou to být osobní relé, placená relé nebo veřejná relé. @@ -836,10 +659,6 @@ Vložte mezi 1–3 relé, která budou sloužit jako vaše soukromá schránka. Ostatní použijí tato relé k posílání DM zpráv vám. DM schránka relé by měla přijímat jakékoli zprávy od kohokoli, ale pouze vám umožnit jejich stahování. Dobré možnosti jsou:\n - inbox.nostr.wine (placené)\n - you.nostr1.com (osobní relé - placené) Soukromá relé Vložte mezi 1–3 relé pro ukládání událostí nikoho jiného, jako jsou koncepty a/nebo nastavení aplikace. V ideálním případě jsou tato relé buď lokální, nebo vyžadují autentizaci před stažením obsahu každého uživatele. - Obecná relé - Amethyst používá tato relé ke stahování příspěvků pro vás. - Doporučené relé - Pro příjem příspěvků od uvedených uživatelů přidejte následující relé do seznamu obecných relat. Vyhledávací relé Seznam relé, která se používají k vyhledávání a označování uživatelů. Označování a vyhledávání nebude fungovat, pokud nejsou k dispozici žádné možnosti. Lokální relé @@ -851,11 +670,8 @@ Tato verze byla představena pro vás: Verze %1$s Děkujeme! - Maximální limit Omezené zápisy Rozštěpováno od - FORK - Git repositář: %1$s Internet: Klon: OTS: %1$s @@ -863,20 +679,13 @@ Existuje důkaz, že tento příspěvek byl podepsán někdy před %1$s. Důkaz byl označen v Bitcoin blockchainu v tomto datu a čase. Upravit příspěvek Návrh na vylepšení vašeho příspěvku - Souhrn změn - Rychlé opravy… Přijmout návrhy Spustit video ve vyskakovacím okně Stáhnout - Text písně zapnuto - Text písně vypnuto - Zapečetěná zpráva vypnuta. Klikněte pro zapnutí zapečetěné zprávy - Zapečetěná zpráva zapnuta. Klikněte pro vypnutí zapečetěné zprávy Odeslat Přehrát uživatelské jméno jako audio Připínáček Skenovat QR kód - Přejít na poskytovatele peněženky třetí strany Alby Není možné odpovědět na koncept Není možné citovat koncept Není možné reagovat na koncept @@ -917,15 +726,12 @@ Nedostatečné úložiště - Server nemá dostatek úložiště, aby úspěšně zpracoval požadavek Detekována smyčka - Server detekuje nekonečnou smyčku při zpracování požadavku Vyžadováno ověření sítě - Klient musí být autentizován, aby získal přístup k síti - NIP-96 Servery - Přidejte tolik serverů, kolik chcete. Můžete si vybrat, které použít později při nahrávání obrázku Blossom Servery Přidejte tolik serverů, kolik chcete. Můžete si vybrat, které použít později při nahrávání obrázku Přidat NIP-96 server Přidat Blossom Server Vymazat vše Opravdu chcete odstranit všechny koncepty? - Zásobník: Torrent soubor Stáhnout Nepodařilo se otevřít soubor @@ -938,37 +744,20 @@ Filtr kanálu, %1$s Kanál Fronta moderace - Neplatné NIP-47 URI - URI %1$s není platné přihlašovací URI NIP-47. Uživatel zveřejňuje svůj obsah na těchto přenašečích Uživatel přijímá oznámení na těchto přenašečích Uživatel přijímá soukromé zprávy na těchto přenašečích - Tato zpráva zmizí za %1$d dní Nahrát video Nalezen záznam o pádu Chcete poslat poslední záznam o pádu do Amethystu v soukromé zprávě? Žádné osobní údaje nebudou sdíleny Odeslat - O nás Pokyny Moderátoři Otevřít rozbalovací nabídku Sady sledování - Označené záložky - Obecné záložky - Veřejné - Soukromé - Smíšené - Zdá se, že zatím nemáte žádné sady sledování.\nKlepněte níže pro obnovení nebo použijte tlačítko přidat k vytvoření nové. Přidat autora do sady sledování Přidat nebo odebrat uživatele ze seznamů, nebo vytvořit nový seznam s tímto uživatelem. Ikona pro seznam - %1$s není v tomto seznamu - Vaše sady sledování - Nebyly nalezeny žádné sady sledování, nebo žádné nemáte. Klepněte níže pro obnovení nebo použijte menu pro vytvoření nové. - Došlo k problému při načítání: %1$s - Vytvořit nový seznam - Vytvořit nový seznam %1$s s uživatelem - Vytvoří %1$s sadu sledování a přidá do ní %2$s. Nový seznam sledovaných Název sady Popis sady (volitelné) @@ -978,8 +767,12 @@ na.. Přejmenovat Událost nemá dostatek informací pro vytvoření magnet odkazu - Moje seznamy/sady Vybrat podepisovatele Použít kodek H.265/HEVC Lepší kvalita při menší velikosti souboru, ale ne všechna zařízení podporují přehrávání H.265. + Služba blesku příjemce v %1$s není k dispozici. Byla vypočtena z adresy blesku \"%2$s\". Chyba: %3$s. Zkontrolujte, zda je server aktivní a zda je adresa blesku správná + Nepodařilo se vyřešit %1$s. Zkontrolujte, zda jste připojeni, zda je server aktivní a zda je adresa %2$s správná.\n\nVýjimka byla: %3$s + Chyba při analýze JSON z načtení faktury %1$s. Zkontrolujte uživatelské bleskové nastavení + Nelze vytvořit bleskovou fakturu. Zpráva od %1$s: %2$s + Nelze vytvořit bleskovou fakturu z %1$s: Prvek pr nebyl nalezen ve výsledném JSON. diff --git a/amethyst/src/main/res/values-cy-rGB/strings.xml b/amethyst/src/main/res/values-cy-rGB/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-cy-rGB/strings.xml +++ b/amethyst/src/main/res/values-cy-rGB/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-da-rDK/strings.xml b/amethyst/src/main/res/values-da-rDK/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-da-rDK/strings.xml +++ b/amethyst/src/main/res/values-da-rDK/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-de-rDE/strings.xml b/amethyst/src/main/res/values-de-rDE/strings.xml index bcccdb01e7..985e4b0d1f 100644 --- a/amethyst/src/main/res/values-de-rDE/strings.xml +++ b/amethyst/src/main/res/values-de-rDE/strings.xml @@ -32,8 +32,6 @@ Andere Belästigung Gewalt - Unbekannt - Relay-Symbol Unbekannter Autor Text kopieren Autor-ID kopieren @@ -48,12 +46,9 @@ Spam / Betrug melden Vortäuschung melden - Anstößigen Inhalt melden Illegales Verhalten melden Malware melden - Melde Mod Malware - Mod Sie verwenden einen öffentlichen Schlüssel und öffentliche Schlüssel sind schreibgeschützt. Mit einem privaten Schlüssel anmelden, um antworten zu können Sie verwenden einen öffentlichen Schlüssel und öffentliche Schlüssel sind schreibgeschützt. Mit einem privaten Schlüssel anmelden, um Beiträge boosten zu können Sie verwenden einen öffentlichen Schlüssel und öffentliche Schlüssel sind schreibgeschützt. Mit einem privaten Schlüssel anmelden, um Beiträge zu liken @@ -67,17 +62,14 @@ Sie verwenden einen öffentlichen Schlüssel und öffentliche Schlüssel sind schreibgeschützt. Mit einem privaten Schlüssel anmelden, um nicht mehr zu folgen Sie verwenden einen öffentlichen Schlüssel, und öffentliche Schlüssel sind nur lesbar. Melden Sie sich mit einem privaten Schlüssel an, um ein Wort oder einen Satz auszublenden Sie verwenden einen öffentlichen Schlüssel und öffentliche Schlüssel sind schreibgeschützt. Mit einem privaten Schlüssel anmelden, um ein Wort oder einen Satz anzeigen zu können - Du verwendest einen öffentlichen Schlüssel, der nur lesbar ist. Melde dich mit einem privaten Schlüssel an, um Einstellungen ändern zu können Du verwendest einen öffentlichen Schlüssel, der nur lesbar ist. Melde dich mit einem privaten Schlüssel an, um hochladen zu können Du verwendest einen öffentlichen Schlüssel, der nur lesbar ist. Melde dich mit einem privaten Schlüssel an, um Ereignisse zu signieren Unbefugte Entschlüsselung Der Signierer hat die erforderliche Entschlüsselung nicht autorisiert. Aktiviere NIP-44-Entschlüsselung in deiner Signierer-App und versuche es erneut Signierer nicht gefunden Wurde die Signierer-App deinstalliert? Überprüfe, ob sie installiert ist und dieses Konto enthält. Melde dich ab und wieder an, falls sich die App geändert hat. - Signierer hat sich unerwartet verhalten Externer Signierer hat Daten zurückgegeben, die für die Anfrage ungewöhnlich sind. Es könnte ein Fehler in Amethyst oder im Signierer vorliegen. Zaps - Aufrufe Boost boosted bearbeitet @@ -90,9 +82,7 @@ Hinzufügen "Antworten auf " " und " - "im Kanal " Profilbanner - Zahlung erfolgreich Fehler beim Parsen der Fehlermeldung " Folgen" " Anhänger" @@ -165,7 +155,6 @@ Nicht genug Guthaben in einer Mint, die dieser Empfänger akzeptiert. Laden Sie zuerst Ihre Cashu-Wallet auf. Verfügbar für diesen Empfänger: %1$s Sats Netzwerkgebühr - Ihre Wallet-App Transaktion: %1$s Lightning-Tipps Notiz an Empfänger @@ -179,16 +168,13 @@ Sichtbares Präfix 😎 Zum Beitrag hinzufügen - "Fehler beim Parsen der Vorschau für %1$s: %2$s" "Vorschaukartenbild für %1$s" Artikel - Neuer Kanal Kanalname Meine tolle Gruppe Bild-URL Bild-URL (optional) Beschreibung - Keine Beschreibung gefunden "Über uns…" Was beschäftigt dich? Eine Nachricht schreiben… @@ -198,42 +184,25 @@ Erstellen Umbenennen Abbrechen - Fehler beim Hochladen des Bildes - Relay-Adresse - Beiträge - Bytes Fehler Fehler Prozentsatz erfolgreicher Verbindungen zum Relay - Anzahl der Verbindungsfehler in dieser Sitzung - Startseite - Private Nachrichten - Öffentlicher Chat - Globale Feed - Such-Feed Benutzer suchen und hinzufügen - Benutzer hinzufügen Relay hinzufügen - Name - Name (zum @Taggen) Mein @tag-Name Anzeigename Mein Anzeigename Ostrich McAwesome Willkommen Ostrich! Benutzername - Mein Benutzername Über mich Avatar-URL Banner-URL Website-URL Pronomen - LN-Adresse - LN-URL (veraltet) Quell-Relays könnten veraltet sein Warnung über veraltetes Relay Auf dem Telefon speichern - In die Galerie abspeichern Bild in der Gal erie gespeichert @@ -252,15 +221,12 @@ erie gespeichert Ein Foto aufnehmen Video aufnehmen Eine Nachricht aufnehmen - Eine Nachricht aufnehmen Zum Aufnehmen einer Nachricht gedrückt halten Neu aufnehmen Aufnahme Aufnahme %1$s - Hochladen… Upload-Fehler Sprachnachricht konnte nicht hochgeladen werden - Unerwarteter Upload-Status NIP-95 wird für Sprachnachrichten noch nicht unterstützt Sprach-Upload fehlgeschlagen: %1$s Keine @@ -272,8 +238,6 @@ erie gespeichert Der Benutzer hat keine Lightning-Adresse eingerichtet, um Sats zu empfangen "Hier antworten…" In diesem Chat - Kopiert die Notiz-ID zum Teilen in die Zwischenablage - Kopiere Kanal-ID (Notiz) in die Zwischenablage Bearbeitet die Kanalmetadaten Beitreten Bekannt @@ -287,7 +251,6 @@ erie gespeichert Antworten Deine Galerie - "Folgt" "Berichte" "%1$s Meldungen" Weitere Optionen @@ -295,11 +258,8 @@ erie gespeichert Webseite Lightning-Adresse Kopiert die Nsec-ID (Ihr Passwort) zur Sicherung in die Zwischenablage - Kopiere geheimen Schlüssel in die Zwischenablage Privaten QR-Code anzeigen QR-Code für verschlüsselten privaten Schlüssel anzeigen - Kopiert den öffentlichen Schlüssel zum Teilen in die Zwischenablage - Kopiere öffentlichen Schlüssel (NPub) in die Zwischenablage Sende eine Direktnachricht Bearbeitet die Benutzermetadaten Folgen @@ -330,8 +290,6 @@ anz der Bedingungen ist erforderlich Wie sollen wir Sie nennen? Sie haben kein Nostr-Konto? Haben Sie schon ein Nostr-Konto? - Neues Konto anlegen - Neuen Schlüssel generieren Feed wird geladen Konto wird geladen verschlüsselt @@ -347,13 +305,7 @@ anz der Bedingungen ist erforderlich Offene Umfrage Feed ist leer. Aktualisieren - erstellt - mit Beschreibung von - und Bild - Chat-Namen geändert zu Neues Chat-Profil: - Beschreibung zu - und Bild zu Verlassen Entfolgen Kanal erstellt @@ -390,7 +342,6 @@ anz der Bedingungen ist erforderlich Nostr-Adresse nie jetzt - Sekunden s m t @@ -398,7 +349,6 @@ anz der Bedingungen ist erforderlich Beleidigungen / Hassrede Hassrede melden Nacktheit / Pornografie melden - andere Alle als bekannt markieren Alle als neu markieren Alle als gelesen markieren @@ -417,8 +367,6 @@ anz der Bedingungen ist erforderlich Authentifizierung fehlgeschlagen Biometrie konnte den Besitzer dieses Telefons nicht authentifizieren Biometrie konnte den Besitzer dieses Telefons nicht authentifizieren. Fehler: %1$s - Fehler - "Erstellt von %1$s" "Auszeichnungsbild für %1$s" Auszeichnungsbild Sie haben eine neue Auszeichnung erhalten @@ -426,7 +374,6 @@ anz der Bedingungen ist erforderlich Notiztext in die Zwischenablage kopiert Autor-ID in die Zwischenablage kopiert Notiz-ID in die Zwischenablage kopiert - Text auswählen "<Private Nachricht kann nicht entschlüsselt werden>\n\nSie wurden in einer privaten/verschlüsselten Unterhaltung zwischen %1$s und %2$s erwähnt." Neues Konto hinzufügen Konten @@ -438,8 +385,6 @@ anz der Bedingungen ist erforderlich Konto auswählen Neues Konto hinzufügen Aktives Konto - Verfügt über privaten Schlüssel - Nur öffentlicher Schlüssel, kein privater Schlüssel Zurück Auswählen Browserlink teilen @@ -463,14 +408,12 @@ anz der Bedingungen ist erforderlich Thread stummschalten Stummschaltung des Threads aufheben Melden - Löschen Nicht erneut anzeigen Spam oder Betrug Beleidigungen oder hasserfülltes Verhalten Bösartige Nachahmung Nacktheit oder explizite Inhalte Illegales Verhalten - Malware Durch das Blockieren eines Benutzers werden deren Inhalte in Ihrer App ausgeblendet. Ihre Notizen sind weiterhin öffentlich sichtbar, auch für Personen, die Sie blockiert haben. Blockierte Benutzer werden auf dem Bildschirm \"Sicherheitsfilter\" aufgelistet. Geplante Zeit auswählen Planen für… Veröffentlicht in %1$s - Fällig vor %1$s Zeit Beitrag planen Planung abbrechen @@ -575,7 +517,6 @@ anz der Bedingungen ist erforderlich Autor Anfragen Genehmigungen - Keine Community entspricht diesem Filter. Überprüfbare Regeln (optional) Veröffentlicht ein maschinenlesbares Regeldokument (NIP-9B) zusammen mit der Community. Unterstützende Clients blockieren nicht passende Beiträge bereits vor dem Senden. Zugelassene Ereignistypen @@ -604,26 +545,15 @@ anz der Bedingungen ist erforderlich WoT-Schranke hinzufügen Globale maximale Ereignisgröße (optional) Bytes — leer lassen für keine globale Obergrenze. - Erhalten - Meine - Verliehen - Entdecken Neues Abzeichen - Abzeichen bearbeiten Abzeichen verleihen Annehmen Ablehnen Aus Profil entfernen - Abzeichen-ID (d-tag) - tapferkeit, mitwirkender-2025… Name Lesbarer Name des Abzeichens Beschreibung Warum wird dieses Abzeichen verliehen? - Bild-URL (1024×1024) - https://example.com/badge.png - Vorschaubild-URL (optional) - https://example.com/badge-thumb.png Bild hochladen Wähle ein quadratisches Bild als Gesicht deines Abzeichens. Abzeichen wird geladen… @@ -632,7 +562,6 @@ anz der Bedingungen ist erforderlich Entfernen Unbenanntes Abzeichen Verliehen an %1$d - Du hast ein Abzeichen erhalten Profilabzeichen Abzeichen · %1$d Wähle aus, welche deiner erhaltenen Abzeichen auf deinem Profil erscheinen sollen. @@ -678,9 +607,6 @@ anz der Bedingungen ist erforderlich Teile deine Workouts Lass Amethyst abgeschlossene Workouts aus Health Connect (Samsung Health, Google Fit, Fitbit, Garmin…) lesen und einen Beitrag vorschlagen. Verbinden - Neues Workout erkannt - Teilen - Verwerfen Aus Health Connect Laufen Gehen @@ -694,7 +620,6 @@ anz der Bedingungen ist erforderlich Diät Fasten Apps - Apps Quelle: %1$s v%1$s Herunterladen @@ -703,12 +628,10 @@ anz der Bedingungen ist erforderlich Themen Verknüpfungen Neueste Version - Kommentare Sei der Erste, der kommentiert. von Ältere Versionen anzeigen Ältere Versionen ausblenden - Kalender Kurzvideos Öffentliche Chats Follow-Pakete @@ -718,18 +641,14 @@ anz der Bedingungen ist erforderlich ein Nest Bühne Warten auf Sprecher… - Publikum Hand heben Hand senken Audio verbinden - Trennen Stummschalten Stummschaltung aufheben - Verbinde… Raum wird ermittelt Transport öffnen Audio aushandeln - Audio verbunden Verbindet erneut… Aufnahme anhören Nachricht konnte nicht gesendet werden @@ -737,9 +656,7 @@ anz der Bedingungen ist erforderlich Diesen Raum schließen? Alle Teilnehmer werden getrennt. Der Raum wird im Feed als GESCHLOSSEN angezeigt. Raum schließen - Wähle eine Startzeit in der Zukunft. Audio fehlgeschlagen: %1$s - Audio ist für diesen Raum nicht verfügbar Sprechen Bühne verlassen Mikrofon stumm @@ -747,7 +664,6 @@ anz der Bedingungen ist erforderlich Gehe live… Übertragung fehlgeschlagen: %1$s Stummschalten fehlgeschlagen: %1$s - Mikrofonzugriff ist erforderlich, um in diesem Raum zu sprechen. Einstellungen öffnen Audioräume Hält Audio aktiv, solange ein Raum geöffnet ist. @@ -758,7 +674,6 @@ anz der Bedingungen ist erforderlich Nest beitreten Gastgeber Öffnen - Letzter Chat Im Raum ist gerade niemand. %1$d hört zu Gastgeber @@ -786,8 +701,6 @@ anz der Bedingungen ist erforderlich Publikum Hände Noch niemand im Publikum. - Senden - Sag etwas… Noch keine Nachrichten. Sei der Erste. Reagieren Raum bearbeiten @@ -821,7 +734,6 @@ anz der Bedingungen ist erforderlich Aktion fehlgeschlagen Die Aktion konnte nicht vorbereitet werden. Raum teilen - Minimieren Minimieren, um weiter zuzuhören Audio unterbrochen Raum wird geladen… @@ -854,7 +766,6 @@ anz der Bedingungen ist erforderlich Wähle, an welche MoQ-Hostserver Amethyst deine Nests veröffentlicht. Der erste Eintrag wird standardmäßig verwendet, wenn du einen neuen Space startest. Deine Server Wird als ersetzbares kind-10112-Ereignis gespeichert, damit andere Clients deine Einstellung lesen können. - Nest-Server hinzufügen Relay-URL (WebTransport) Auth-URL (JWT-Mint) Hinzufügen @@ -867,13 +778,11 @@ anz der Bedingungen ist erforderlich Server entfernen Noch keine Nest-Server. Füge unten einen hinzu oder wähle einen empfohlenen Server. Videos - Artikel Musik Wiedergabelisten Folgen Podcasts Folgen ansehen - Folgen Noch keine Folgen gefunden %1$d Folge @@ -885,9 +794,6 @@ anz der Bedingungen ist erforderlich Titelname Künstler Name des Künstlers - Audio-URL - https://… .mp3 - URL des Coverbilds (optional) Album (optional) Dauer in Sekunden (optional) Songtext oder Credits (optional) @@ -897,7 +803,6 @@ anz der Bedingungen ist erforderlich Zur Playlist hinzufügen Du hast noch keine eigenen Playlists. Verwende das Feld oben, um eine zu erstellen. Alle Playlists verwalten - Neue Playlist Playlist-Name Erstellen (Playlist ohne Titel) @@ -933,9 +838,6 @@ anz der Bedingungen ist erforderlich Lesezeichenliste löschen Beiträge anzeigen Artikel anzeigen - Links anzeigen - Hashtags anzeigen - Du hast noch keine Lesezeichenlisten. Tippe auf die Schaltfläche unten, um eine zu erstellen. Interessensets Du hast noch keine Interessensets. Tippe unten auf den Neu-Button, um eines zu erstellen. Neues Interessenset @@ -954,7 +856,6 @@ anz der Bedingungen ist erforderlich Private Beiträge(%1$s) Öffentliche Beiträge Öffentliche Beiträge(%1$s) - Private Artikel Private Artikel(%1$s) Öffentliche Artikel Öffentliche Artikel(%1$s) @@ -981,16 +882,6 @@ anz der Bedingungen ist erforderlich Metadaten von Lesezeichenlisten können von allen auf Nostr gesehen werden. Nur deine privaten Mitglieder sind verschlüsselt. In öffentlich verschieben In privat verschieben - Wallet-Verbindungsdienst - Autorisiert einen Nostr Secret, Zaps ohne Verlassen der App zu bezahlen. Bewahren Sie den geheimen Schlüssel sicher auf und verwenden Sie nach Möglichkeit ein privates Relay - Wallet Connect Public Key - Wallet-Verbindungs-Relay - Wallet-Verbindungs-Geheimnis - Geheimen Schlüssel anzeigen - nsec / hexadezimaler privater Schlüssel - Verbunden - Nicht verbunden - Erweitert: Verbindungsdetails manuell eingeben Schnelle Zap-Beträge Wird beim Drücken der Zap-Schaltfläche angezeigt. Tippe auf einen Betrag, um ihn zu entfernen. Wenn du es leer lässt, wird jedes Mal ein Dialog zur Eingabe eines Betrags geöffnet. Stattdessen On-Chain senden @@ -1022,14 +913,8 @@ anz der Bedingungen ist erforderlich Wallet verbinden Relay-Feed anzeigen Spendenbetrag in Sats - Umfrage veröffentlichen - Erforderliche Felder: - Zap-Empfänger - Hauptbeschreibung der Umfrage… - Wahl Wahl %s Beschreibung der Umfrageoption - Optionale Felder: Mindest-Zap-Betrag Maximaler Zap-Betrag Konsens @@ -1038,11 +923,8 @@ anz der Bedingungen ist erforderlich Mehrfachauswahl Schließdatum und -zeit Umfrage endet in %1$s - Schließen nach - Tagen Konnte nicht abstimmen Die Umfrage ist für neue Stimmen geschlossen - Zap-Betrag Es ist nur eine Stimme pro Benutzer für diesen Umfragetyp erlaubt "Veranstaltung suchen %1$s" Zap senden @@ -1078,11 +960,8 @@ anz der Bedingungen ist erforderlich Keine Zap Keine Spur in Nostr, nur in Lightning Anonym - Als neue Wegwerfidentität posten. Dein Konto wird nicht mit dieser Antwort verknüpft. - Diese Antwort wird von einer neuen anonymen Identität veröffentlicht Dateiserver Wählen Sie einen Server zum Hochladen dieser Datei - LnAddress oder @Benutzer Medienserver Legen Sie Ihre bevorzugten Medienupload Server fest. Lokalen Blossom-Cache verwenden @@ -1091,10 +970,8 @@ anz der Bedingungen ist erforderlich Kein lokaler Cache an Port 24242 erkannt. Nur Profilbilder cachen Den lokalen Cache auf Profilbilder beschränken. Feed-Bilder und -Videos werden direkt von den Originalservern geladen. - Du hast keine NIP-96-Server gesetzt. Du kannst die Amethyst-Liste verwenden oder unten einen hinzufügen ↓ Du hast keine Blossom Server gesetzt. Du kannst die Amethyst-Liste verwenden oder unten einen hinzufügen ↓ Empfohlene Medienserver - Integrierte Medienserver Amethysts Standardliste. Sie können sie einzeln hinzufügen oder die Liste hinzufügen. Standardliste verwenden Medienserver hinzufügen @@ -1117,36 +994,21 @@ anz der Bedingungen ist erforderlich Hashen Fertig Fehler - Deine Relays (NIP-95) - Dateien werden von deinen Relays gehostet. Neuer NIP: Überprüfe, ob sie unterstützt werden Privatsphäre-Optionen - Tor/Orbot-Einrichtung - Verbindung über deine Orbot-Einrichtung herstellen Anpassen Tor-Einstellungen - Von deiner Orbot/Tor trennen? - Deine Daten werden sofort im regulären Netzwerk übertragen Ja Nein - Folgen-Liste Alle Folgen Alle Benutzer Folgen Standard-Folgenliste - Folgt über Proxy In der Nähe Weltweit Kuratiert - Schach Meine Stummliste Follower-Listen Dies sind Follow-Listen für deine eigene Nutzung. Du kannst Nutzer privat oder öffentlich folgen. - Markierte Lesezeichen - Allgemeine Lesezeichen - Öffentlich - Privat - Gemischt - Es scheint, dass du noch keine Folge-Sets hast.\nTippe unten zum Aktualisieren oder verwende die Plus-Taste, um ein neues zu erstellen. Neu Autor zur Follower-Liste hinzufügen Benutzer zu Listen hinzufügen oder entfernen, oder eine neue Liste mit diesem Benutzer erstellen. @@ -1155,23 +1017,9 @@ anz der Bedingungen ist erforderlich %1$s ist ein privates Mitglied Als öffentliches Mitglied hinzufügen Als privates Mitglied hinzufügen - Öffentliche Mitglieder - Private Mitglieder - Öffentliche Profile - Private Profile - Mitglied - Mitglieder - Keine Mitglieder Leer - %1$s ist nicht in dieser Liste %1$s ist kein Mitglied Deine Listen und %1$s - Deine Listen - Keine Follower-Listen gefunden oder du hast keine. Tippe unten, um zu aktualisieren, oder verwende das Menü, um eine zu erstellen. - Beim Abrufen ist ein Problem aufgetreten: %1$s - Neue Liste erstellen - Neue %1$s-Liste mit Benutzer erstellen - Erstellt ein %1$s-Folge-Set und fügt %2$s hinzu. Neue Follower-Liste Neues Empfehlungspaket Follower-Liste kopieren/klonen @@ -1191,13 +1039,6 @@ anz der Bedingungen ist erforderlich Du benennst um von zu.. Standard-Port ist 9050 - ## Über Tor mit Orbot verbinden - \n\n1. Installiere [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Starte Orbot - \n3. Überprüfe in Orbot den Socks-Port. Standardmäßig wird der Port 9050 verwendet - \n4. Ändere gegebenenfalls den Port in Orbot - \n5. Konfiguriere den Socks-Port in diesem Bildschirm - \n6. Drücke die Aktivieren-Schaltfläche, um Orbot als Proxy zu verwenden Orbot Socks-Port Aktiver Tor-Engine Verwenden Sie die interne Version oder Orbot @@ -1239,8 +1080,6 @@ anz der Bedingungen ist erforderlich Verbergen Sie Ihre IP bei allen Verbindungen Erstellen Sie Ihre eigenen Ungültige Portnummer - Orbot verwenden - Tor/Orbot trennen Private Nachrichten Benachrichtigt dich, wenn eine private Nachricht eingeht Erhaltene Zaps @@ -1297,12 +1136,8 @@ anz der Bedingungen ist erforderlich Bluetooth Sprachanruf Videoanruf - Warte auf andere Teilnehmer\u2026 Teilnehmer hinzufügen Benutzer suchen\u2026 - Anruf konnte nicht gestartet werden - Anruf konnte nicht angenommen werden - Anrufsitzung konnte nicht erstellt werden Berechtigung erforderlich Amethyst benötigt Zugriff auf das Mikrofon, um einen Sprachanruf zu starten. Bitte aktiviere ihn in den App-Einstellungen. Amethyst benötigt Zugriff auf Kamera und Mikrofon, um einen Videoanruf zu starten. Bitte aktiviere sie in den App-Einstellungen. @@ -1336,24 +1171,13 @@ anz der Bedingungen ist erforderlich Android kann Relay-Verbindungen im Hintergrund einschränken. Deaktiviere die Akkuoptimierung für Amethyst, um zuverlässige Benachrichtigungen zu gewährleisten. Jetzt beheben Benachrichtigen: - Unterhaltung beitreten - Benutzer- oder Gruppen-ID - npub, nevent oder hex - Erstellen - Beitreten Heute Inhaltswarnung Warnung: %1$s Dieser Beitrag enthält sensiblen Inhalt, den einige Personen als beleidigend oder verstörend empfinden könnten - Sensiblen Inhalt immer ausblenden - Sensiblen Inhalt immer anzeigen - Immer Inhaltswarnungen anzeigen Ausblenden Anzeigen Warnen - Empfohlene Apps: - Spam von Fremden filtern - Warnung bei Meldungen von deinen Abonnements Spam filtern Versteckt Beiträge von Fremden, die 5 oder mehr Male genau die gleichen waren Client-Tag zu meinen Ereignissen hinzufügen @@ -1385,22 +1209,17 @@ anz der Bedingungen ist erforderlich Die Menge in Bytes, die an dieses Relais gesendet wurde, einschließlich Filter und Ereignisse Die Menge in Bytes, die von diesem Relais empfangen wurde, einschließlich Filter und Ereignisse Ereignisse gespeichert - Ein Fehler ist beim Abrufen von Relay-Informationen von %1$s aufgetreten Inhaber Verwendet von Service-Schlüssel - %1$s wird ausgeführt - %1$s wird ausgeführt (%2$s) Version Programme Kontakt Unterstützte NIPs Unterstützte GRASPs - Eintrittsgebühren Zutritt Abonnement Veröffentlichung - Zahlungen %1$s Zahlungs-URL Zielgruppe Richtlinien & Links @@ -1408,7 +1227,6 @@ anz der Bedingungen ist erforderlich Einschränkungen Länder Sprachen - Tags Themen Alle Länder Alle Sprachen @@ -1423,64 +1241,48 @@ anz der Bedingungen ist erforderlich Öffnen Lesen Schreiben - RTT Netzwerk Typ Unterstützte NIPs Anforderungen - Letzte Prüfung %1$d ms Akzeptierte Arten Standort Aktive Abonnements - Ausstehende Outbox-Ereignisse REQ-Abonnements (%1$d) COUNT-Abonnements (%1$d) Outbox-Ereignisse (%1$d) - Keine aktiven Abonnements für dieses Relay %1$d Autoren %1$d IDs seit %1$s bis %1$s Limit %1$d - Nachrichtenlänge - Abonnements - Filter - Länge der Abonnement-ID Mindestpräfix Max. Event-Tags - Inhaltslänge Max. Inhaltslänge Verwirft älter als Akzeptiert bis zu %1$s in der Zukunft vor %1$s - %1$s Nullen %1$s Bits Ereignis-Aufbewahrung Inhaltsgröße Verbindung Zugriffskontrolle Min. PoW-Schwierigkeit - Authentifizierung Authentifizierung erforderlich - Zahlung Zahlung erforderlich Max. Nachrichtenlänge Max. Abonnements Max. Filter pro Abo Max. Limit (zurückgegebene Ereignisse) - Standardlimit (zurückgegebene Ereignisse) Max. SubID-Länge Cashu-Token Minze: %1$s Einlösen - An Zap Wallet senden - In Cashu Wallet öffnen Token kopieren In anderer App öffnen Keine Lightning-Adresse festgelegt - Token in die Zwischenablage kopiert LIVE OFFLINE BEENDET @@ -1531,7 +1333,6 @@ anz der Bedingungen ist erforderlich Marmot-Status zurückgesetzt. Marmot-Status konnte nicht zurückgesetzt werden: %1$s Immer - Nur WLAN Unbegrenztes WLAN Nie Fertig @@ -1556,7 +1357,6 @@ anz der Bedingungen ist erforderlich Wählen Sie den Beitragsstil Profilgalerie-Stil Galeriestil auswählen - Bild laden Spammer Stummgeschaltet. Drücken, um Ton einzuschalten Ton ein. Zur Stummschaltung drücken @@ -1568,18 +1368,13 @@ anz der Bedingungen ist erforderlich Nostr-Adresse verifiziert Nostr-Adresse konnte nicht verifiziert werden Nostr-Adresse wird überprüft - Alle auswählen/abwählen Standard Auf Standardeinstellung zurücksetzen - Wählen Sie ein Relais aus, um fortzufahren - Weiterleiten von Zaps an: - Unterstützende Clients leiten Zaps an die LNAddress oder das Benutzerprofil unten weiter, anstatt an Ihre eigene Adresse Ort preisgeben als Fügt dem Beitrag einen Geohash Ihres Standorts hinzu. Die Öffentlichkeit wird wissen, dass Sie sich innerhalb von 5 km (3 mi) vom aktuellen Standort befinden Standort-exklusiver Beitrag Nur Anhänger des Ortes werden es sehen. Deine allgemeinen Anhänger werden es nicht sehen. Hashtag-exklusive Beitrag - Nur die Anhänger des Hashtags werden ihn sehen. Deine allgemeinen Follower werden ihn nicht sehen. Eine Webseite kommentieren Eine externe Ressource kommentieren %1$d Min. Lesezeit @@ -1600,20 +1395,14 @@ anz der Bedingungen ist erforderlich Audiodatei hochladen Wähle eine MP3, WAV oder FLAC. Sie wird beim Speichern auf deinen Medienserver hochgeladen. Audiodatei bereit zum Hochladen - Wird hochgeladen… Cover und Audio werden hochgeladen und veröffentlicht. Der Vorgang läuft weiter, auch wenn du den Bildschirm verlässt. - Hochladen fehlgeschlagen: %1$s Standort wird geladen Keine Standortberechtigungen Fügt eine Warnung für sensiblen Inhalt hinzu, bevor Ihr Inhalt angezeigt wird. Dies ist ideal für NSFW-Inhalte (nicht sicher für die Arbeit) oder Inhalte, die manche Menschen als anstößig oder verstörend empfinden könnten Grund (optional) - Neues Feature - Um diesen Modus zu aktivieren, muss Amethyst eine NIP-17-Nachricht senden (GiftWrapped, Versiegelte Direkt- und Gruppennachrichten). NIP-17 ist neu und die meisten Clients haben es noch nicht implementiert. Stellen Sie sicher, dass der Empfänger einen kompatiblen Client verwendet. - Aktivieren Öffentlich Gruppe Neue öffentliche oder private Gruppe - Relais Privat An Betreff @@ -1625,9 +1414,6 @@ anz der Bedingungen ist erforderlich Erklärung an Mitglieder Ändern des Namens für die neuen Ziele. Aus Zwischenablage einfügen - Ungültige NIP-47 URI - Die URI %1$s ist keine gültige NIP-47 Anmelde-URI. - Mit neuer NWC-Wallet verbinden Wallet nicht gefunden Amethyst konnte keine Wallet-Apps finden, die Nostr Wallet Connect (NWC) unterstützen. \n\nWas du tun kannst: @@ -1643,7 +1429,6 @@ anz der Bedingungen ist erforderlich Videos und GIFs automatisch abspielen Videos automatisch abspielen, wenn sie auf dem Bildschirm sichtbar sind URL-Vorschauen anzeigen - Wann Bilder geladen werden sollen Stapel kopieren In Zwischenablage kopieren In die Zwischenablage kopiert @@ -1659,43 +1444,21 @@ anz der Bedingungen ist erforderlich Medien hinzugefügt Medien wurden zu Ihrer Profilgalerie hinzugefügt Erstellt am - Regeln - Über uns Richtlinien Moderatoren Mit Amber anmelden Status aktualisieren - Fehler beim Verarbeiten der Fehlermeldung Die Abstimmungen werden nach der Höhe des Zaps gewichtet. Sie können einen Mindestbetrag festlegen, um Spam zu verhindern, und einen Höchstbetrag, um zu verhindern, dass große Zapper die Abstimmung dominieren. Verwenden Sie denselben Betrag in beiden Feldern, um sicherzustellen, dass jeder Stimme der gleiche Wert zukommt. Lassen Sie es leer, um jeden Betrag zu akzeptieren. Zap konnte nicht gesendet werden Mit dem Benutzer kommunizieren Nachricht %1$s OK - Konnte %1$s nicht erreichen: %2$s - Fehler beim Zusammenstellen der NIP-11-URL für %1$s: %2$s - Konnte %1$s nicht erreichen: %2$s - Fehler beim Analysieren der Antwort von %1$s: %2$s - Relais abgelehnt Nachfragen %1$s: %2$s - Konnte %1$s nicht erreichen: %2$s - Konnte das Ergebnis von %1$s nicht verarbeiten: %2$s - %1$s fehlgeschlagen mit Code %2$s - Aktiv für: - Startseite - Nachrichten - Plaudern - Global - Suche Zaps aufteilen und weiterleiten Unterstützende Clients werden Zaps an die hier hinzugefügten Benutzer aufteilen und weiterleiten, anstatt an Sie Benutzer suchen und hinzufügen Benutzername oder Anzeigename Fehlende Lightning-Konfiguration Benutzer %1$s hat keine Lightning-Adresse eingerichtet, um Sats zu empfangen - Prozent - 25 - Zaps aufteilen mit - Zaps weiterleiten an - Lightning-Wallets nicht gefunden Bezahlt Brieftasche %1$s Fehler beim Öffnen der Signatur-App @@ -1704,7 +1467,6 @@ anz der Bedingungen ist erforderlich Der Codec oder das Format wird auf diesem Gerät nicht unterstützt (%1$s). Versuche, es im Browser zu öffnen. Im Browser öffnen Signaturanfrage abgelehnt - Signaturanfrage abgelehnt Stellen Sie sicher, dass die Unterzeichner-Anwendung diese Transaktion autorisiert hat Keine Wallets gefunden, um eine Lightning-Rechnung zu bezahlen (Fehler: %1$s). Installieren Sie eine Lightning-Wallet, um Zaps zu verwenden Keine Wallets gefunden, um eine Lightning-Rechnung zu bezahlen. Installieren Sie eine Lightning-Wallet, um Zaps zu verwenden @@ -1720,40 +1482,23 @@ anz der Bedingungen ist erforderlich Option auswählen Konnte Rechnung nicht bezahlen Konnte nicht abheben - Konnte Wallet Connect nicht einrichten - Fehler beim Parsen der NIP-47-Verbindungszeichenfolge. Überprüfen Sie, ob diese korrekt ist, Ihr Wallet-Anbieter: %1$s. Fehler: %2$s - Fehler beim Parsen der NIP-47-Verbindungszeichenfolge. Überprüfen Sie, ob diese korrekt ist, Ihr Wallet-Anbieter: %1$s. Cashu konnte nicht eingelöst werden Mint hat folgende Fehlermeldung geliefert: %1$s - Cashu-Token bereits ausgegeben. Cashu erhalten %1$s Sats wurden an Ihre Wallet gesendet. (Gebühren: %2$s Sats) Keine kompatible Cashu-Brieftasche im System gefunden Konnte Rechnung nicht vom Server des Empfängers abrufen Ihr Wallet-Connect-Anbieter hat folgenden Fehler zurückgegeben: %1$s - Konnte keine Verbindung zu Tor herstellen Tor verbindet sich nicht Amethyst konnte den Tor-Start nicht abschließen. Eine reguläre (Nicht-Tor-)Verbindung verwenden, damit der Feed laden kann? Wir merken uns diese Auswahl für die nächste Stunde und versuchen Tor danach erneut. Verbindung ohne Tor verwenden Weiter warten - Herunterladen des Relaisdokuments nicht verfügbar Konnte keine LNUrl aus der Lightning-Adresse \"%1$s\" zusammenstellen. Überprüfen Sie die Konfiguration des Benutzers - Der Lightning-Service des Empfängers unter %1$s ist nicht verfügbar. Er wurde aus der Lightning-Adresse \"%2$s\" berechnet. Fehler: %3$s. Überprüfen Sie, ob der Server online ist und ob die Lightning-Adresse korrekt ist - Konnte %1$s nicht auflösen. Überprüfen Sie, ob Sie verbunden sind, ob der Server online ist und ob die Lightning-Adresse %2$s korrekt ist - Konnte %1$s nicht auflösen. Überprüfen Sie, ob Sie verbunden sind, ob der Server online ist und ob die Lightning-Adresse %2$s korrekt ist.\n\nAusnahme war: %3$s - Konnte Rechnung nicht von %1$s abholen Rechnung konnte nicht von %1$s abgerufen werden: %2$s - Fehler beim analysieren von JSON aus der Lightning-Adresse. Überprüfen Sie die Lightning-Konfiguration des Benutzers Fehler beim Parsen von JSON von %1$s. Überprüfen Sie die Blitzeinrichtung des Benutzers - Callback-URL nicht in der Serverkonfiguration der Lightning-Adresse des Benutzers gefunden Callback-URL aus %1$s Antwort nicht gefunden - Fehler beim Parsen von JSON aus der Rechnungsabruf der Lightning-Adresse. Überprüfen Sie die Lightning-Konfiguration des Benutzers - Fehler beim Parsen von JSON von %1$s. Überprüfen Sie die Blitzeinrichtung des Benutzers Falscher Rechnungsbetrag (%1$s Sats) von %2$s. Er hätte %3$s sein sollen Konnte keine Lightning-Rechnung erstellen, bevor der Zap gesendet wurde. Die Lightning-Wallet des Empfängers hat folgenden Fehler gesendet: %1$s - Blitzrechnung konnte nicht erstellt werden. Nachricht von %1$s: %2$s - Konnte keine Lightning-Rechnung erstellen, bevor der Zap gesendet wurde. Element pr wurde nicht in der resultierenden JSON gefunden. - Kann keine Blitzrechnung von %1$s erstellen: Element pr nicht im resultierenden JSON gefunden. Nur-Lese-Benutzer Keine Reaktionen eingerichtet Benachrichtigungen @@ -1779,13 +1524,11 @@ anz der Bedingungen ist erforderlich Dem Verkäufer eine Nachricht senden Hallo %1$s, ist das noch verfügbar? Hallo, ist das noch verfügbar? - Artikel verkaufen Titel iPhone 13 Zustand Kategorie Preis (in Sats) - 1000 Ort Stadt, Staat, Land Neu @@ -1814,20 +1557,13 @@ anz der Bedingungen ist erforderlich Sonstiges Fehler beim Laden der Medien Konnte die komprimierte Datei nicht öffnen - Fehler beim komprimieren der Medien: %1$s Fehler beim Hochladen: %1$s Der Server hat nach dem Hochladen keine URL angegeben Hochgeladene Medien konnten nicht vom Server heruntergeladen werden Die heruntergeladene Datei konnte nach dem Hochladen nicht überprüft werden: %1$s - Lokale Datei konnte nicht zum Hochladen vorbereitet werden: %1$s Konnte %1$s nicht erreichen: %2$s - Upload fehlgeschlagen: %1$s Löschen fehlgeschlagen: %1$s Medien sind zu groß für NIP-95 - Miniaturansicht kann nicht geladen werden - Konnte Kopfzeileninformationen nicht vorbereiten: %1$s - Komprimierung abgebrochen - Komprimierung fehlgeschlagen eine Datei zurückzugeben Dateien verschlüsseln Dateien vor dem Hochladen verschlüsseln, um die Privatsphäre zu schützen. Einige Server akzeptieren möglicherweise keine verschlüsselten Dateien bei kostenlosen Konten. Verschlüsselter Upload fehlgeschlagen @@ -1854,27 +1590,18 @@ anz der Bedingungen ist erforderlich Metadaten können nicht aus AVIF entfernt werden: %1$s Entwurf bearbeiten Einloggen mit QR-Code - Route Startseite - Suche Entdecken Nachrichten Benachrichtigungen - Global Kurzfilme - Bilder - Workouts Kalender Kalenderlisten Schach Wallet - Guthaben Senden Empfangen Transaktionen - Keine Wallet verbunden - Richte eine Nostr Wallet Connect (NWC)-Verbindung in deinen Zap-Einstellungen ein, um die Wallet zu nutzen. - Wallet einrichten Sats BOLT-11-Rechnung einfügen Bezahlen @@ -1902,8 +1629,6 @@ anz der Bedingungen ist erforderlich Dies entfernt die Wallet-Verbindung. Du kannst sie später jederzeit wieder hinzufügen. Wallet-Name Meine Wallet - Deine Wallets - Wallets verwalten Keine Wallets verbunden Verbinde eine oder mehrere NWC-Wallets, um Zahlungen zu senden und zu empfangen. NWC-Verbindung hinzufügen @@ -1922,12 +1647,9 @@ anz der Bedingungen ist erforderlich Mint-URL Mint entfernen Verlauf - Wallet bearbeiten Nutzap-Schlüssel (erweitert) Ein separater privater Schlüssel, der nur zum Empfangen von NIP-61-Nutzaps dient. Nicht dein Nostr-Identitätsschlüssel. Neuen Schlüssel erzeugen - Macht alle ausstehenden Nutzaps ungültig, die an den aktuellen Schlüssel gebunden sind. - Aktuellen Schlüssel behalten Privater P2PK-Schlüssel (hex) Cashu-Wallet bearbeiten Änderungen speichern @@ -1943,7 +1665,6 @@ anz der Bedingungen ist erforderlich Beliebte Mints Passende Mints - Diesen Mint empfehlen Empfangen LN senden Token senden @@ -2003,10 +1724,6 @@ anz der Bedingungen ist erforderlich Speichern Umbenennen Wallet umbenennen - Bearbeiten - Ungültige NWC-Verbindungs-URI - Nach oben - Nach unten On-Chain-Transaktionen Keine On-Chain-Adresse für dieses Konto verfügbar. Kein On-Chain-Backend konfiguriert. @@ -2081,17 +1798,13 @@ anz der Bedingungen ist erforderlich Zahlung gesendet (%1$d von %2$d Quittung veröffentlicht), aber die nächste Quittung konnte nicht veröffentlicht werden Zahlung gesendet (%1$d von %2$d Quittungen veröffentlicht), aber die nächste Quittung konnte nicht veröffentlicht werden - Sicherheitsfilter Folgeliste importieren Neuer Beitrag Neue Kurzfilme: Bilder oder Videos Neue Community-Notiz Neues Produkt - Neuer Geo-Exklusiver Beitrag Neuer Artikel Neue Umfrage - Neue Zap-Umfrage - Neue reguläre Umfrage Neues Bild Neuer Kalendertermin Kalendertermin bearbeiten @@ -2106,8 +1819,6 @@ anz der Bedingungen ist erforderlich Tag Bevorstehend Vergangen - Noch keine bevorstehenden oder vergangenen Kalendertermine aus deinem ausgewählten Feed. - Noch keine Kalenderlisten. Dein Kalender ist leer Termine, die von Personen geteilt werden, denen du folgst, erscheinen hier. Tippe auf +, um eigene zu erstellen. Noch keine Listen @@ -2134,8 +1845,6 @@ anz der Bedingungen ist erforderlich Nächste Woche Vorheriger Tag Nächster Tag - Keine Termine an diesem Tag - Keine Termine Geht weiter Tag %1$d von %2$d Zum Telefonkalender hinzufügen @@ -2195,7 +1904,6 @@ anz der Bedingungen ist erforderlich Das gewählte Bild konnte nicht hochgeladen werden. Versuche es erneut oder füge eine URL ein. Teilnehmer (%1$d) Name, npub oder nip-05 suchen - Gib einen gültigen npub… oder 64-stelligen hex pubkey ein. Teilnehmer entfernen Kalendererinnerungen Erinnerungen senden @@ -2216,10 +1924,7 @@ anz der Bedingungen ist erforderlich Termindetails Neues kurzes Video Neues langes Video - Titel Zusammenfassung (optional) - Cover-Bild-URL (optional) - Schreib deinen Artikel in Markdown… Vorschau Bearbeiten Titelbild hinzufügen @@ -2303,18 +2008,14 @@ anz der Bedingungen ist erforderlich %1$s weiterleiten Rela-Liste erweitern Notizoptionen - Rela-Listenauswahl Umfrage Umfrage deaktivieren Bitcoin-Rechnung hinzufügen Bitcoin-Rechnung abbrechen - Verkauf eines Artikels abbrechen Zapraiser hinzufügen Zapraiser abbrechen Ort hinzufügen Ort entfernen - Zap-Aufteilung hinzufügen - Zap-Aufteilung abbrechen Inhaltswarnung hinzufügen Inhaltswarnung entfernen Ablaufdatum hinzufügen @@ -2329,11 +2030,8 @@ anz der Bedingungen ist erforderlich Ungültige Adresse Amethyst hat eine URI zum Öffnen erhalten, aber diese URI war ungültig: %1$s DM Posteingangs-Relais - Relais: %1$s - Verwendung regulärer Relais Richten Sie Ihre privaten Posteingangs-Relais ein Diese Einstellung lässt alle wissen, welche Relais verwendet werden sollen, wenn sie Nachrichten an Sie senden. Ohne diese könnten Sie einige Nachrichten verpassen. - Gute Optionen sind:\n - inbox.nostr.wine (bezahlt)\n - you.nostr1.com (persönliche Relais - bezahlt) Gute Optionen sind:\n - auth.nostr1.com (gratis)\n - inbox.nostr.wine (bezahlt)\n - relay.0xchat.com (gratis) Fügen Sie 1–3 Relais ein, die als Ihr privater Posteingang dienen sollen. DM Posteingangs-Relais sollten Nachrichten von jedem akzeptieren, aber nur Ihnen erlauben, sie herunterzuladen. Jetzt einrichten @@ -2353,7 +2051,6 @@ anz der Bedingungen ist erforderlich Das Erstellen einer Relay-Liste, die speziell zum Empfangen von Benachrichtigungen gedacht ist, ist entscheidend für dein Nostr-Erlebnis. Füge 1–3 Relays hinzu, die Benachrichtigungen für dich empfangen. Stelle sicher, dass sie keine Zahlung oder Web of Trust vom Absender verlangen, sonst erhältst du nur Benachrichtigungen von zahlenden oder langjährigen Nutzern. Gute Optionen sind:\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social - DM-Upload Relaiseinstellungen Relay neu anordnen Öffentliche Heimrelais @@ -2370,12 +2067,8 @@ anz der Bedingungen ist erforderlich Relays, auf denen deine MLS KeyPackages veröffentlicht werden (MIP-00). Andere Nutzer rufen diese KeyPackages ab, um dich zu Marmot-Gruppenchats einzuladen. Füge 1–3 Relays hinzu, die KeyPackage-Ereignisse von dir akzeptieren und öffentliches Lesen erlauben. Private Relais Fügen Sie zwischen 1–3 Relais ein, um Ereignisse zu speichern, die niemand anders sehen kann, wie Ihre Entwürfe und/oder App-Einstellungen. Idealerweise sind diese Relais entweder lokal oder erfordern eine Authentifizierung, bevor Sie die Inhalte eines jeden Benutzers herunterladen. - Allgemeine Relais - Amethyst verwendet diese Relais, um Beiträge für Sie herunterzuladen. Verbundene Relays Aktuelle Liste der verwendeten Relays - Empfohlene Relais - Fügen Sie die folgenden Relais zu Ihrer Liste hinzu, um Beiträge von den aufgelisteten Benutzern zu erhalten. Suchrelais Liste der Relais, die für die Suche und das Taggen von Benutzern verwendet werden. Das Taggen und die Suche funktionieren nicht, wenn keine Optionen verfügbar sind. Lokale Relais @@ -2410,11 +2103,8 @@ anz der Bedingungen ist erforderlich Diese Version wurde Ihnen präsentiert von: Version %1$s Vielen Dank! - Maximallimit Eingeschränkte Schriften Geforkt von - FORK - Git Repository: %1$s Internet: Klonen: Offen @@ -2439,20 +2129,13 @@ anz der Bedingungen ist erforderlich Artikel bearbeiten Beitrag bearbeiten Vorschlag zur Verbesserung Ihres Beitrags - Zusammenfassung der Änderungen - Schnelle Korrekturen… Den Vorschlag annehmen Video in einem Pop-Up starten Herunterladen - Liedtext an - Liedtext aus - Versiegelte Nachricht aus. Klicken Sie, um die versiegelte Nachricht einzuschalten - Versiegelte Nachricht an. Klicken Sie, um die versiegelte Nachricht auszuschalten Senden Benutzernamen als Audio abspielen Reißzwecke QR-Code scannen - Navigieren Sie zum Drittanbieter-Wallet-Anbieter Alby Datum auswählen Es ist nicht möglich, auf einen Entwurf zu antworten Es ist nicht möglich, einen Entwurf zu zitieren @@ -2494,23 +2177,18 @@ anz der Bedingungen ist erforderlich Unzureichender Speicher - Der Server hat nicht genug Speicher, um die Anfrage erfolgreich zu verarbeiten Schleife erkannt - Der Server erkennt eine Endlosschleife, während er die Anfrage bearbeitet Netzwerk-Authentifizierung erforderlich - Der Client muss authentifiziert werden, um auf das Netzwerk zuzugreifen - NIP-96 Server - Fügen Sie beliebig viele Server hinzu. Sie können wählen, welche später beim Hochladen Ihres Bildes verwendet werden soll Blossom Server Fügen Sie beliebig viele Server hinzu. Sie können wählen, welche später beim Hochladen Ihres Bildes verwendet werden soll NIP-96 Server hinzufügen Blossom Server hinzufügen Alles löschen Möchten Sie wirklich alle Entwürfe löschen? - Stapel: Torrentdatei Herunterladen Fehler beim Öffnen der Datei Keine Torrent-Apps installiert, um die Datei zu öffnen und herunterzuladen. Das Ereignis enthält nicht genügend Informationen, um einen Magnetlink zu erstellen - Meine Listen/Sets Meine Listen - Benutzer Liste zum Filtern des Feeds auswählen Feeds Hash-Tags @@ -2541,7 +2219,6 @@ anz der Bedingungen ist erforderlich Private Nachricht Öffentliche Nachricht Chat-Relais - Das Relais, mit dem sich alle Benutzer dieses Chats verbinden Bild teilen… Bild kann nicht geteilt werden, bitte versuchen Sie es später erneut… Video teilen… @@ -2588,7 +2265,6 @@ anz der Bedingungen ist erforderlich Möchten Sie den letzten Absturzbericht per Direktnachricht an Amethyst senden? Es werden keine persönlichen Daten weitergegeben Senden Diese Nachricht verschwindet in %1$s - Diese Nachricht verschwindet in %1$d Tagen Signierer auswählen Bereits in der Liste Private Mitglieder @@ -2610,7 +2286,6 @@ anz der Bedingungen ist erforderlich Paketname Neuer Paketname Paketbeschreibung - Neue Paketbeschreibung Liste veröffentlichen Empfehlungspaket veröffentlichen Liste löschen @@ -2624,13 +2299,9 @@ anz der Bedingungen ist erforderlich Einklappen Ausklappen Fehlgeschlagene erneut senden (%1$d) - +%1$d weitere Sendungen - " (%1$d in Bearbeitung)" - %1$d/%2$d Relays Zeitüberschreitung Erneuter Versuch… Erneut versuchen - Anzeigen Schließen %1$d/%2$d Senden @@ -2656,7 +2327,6 @@ anz der Bedingungen ist erforderlich Neu starten Annehmen Ablehnen - Neues Spiel Neues Schachspiel Spiel wird geladen… Spiel nicht gefunden @@ -2811,23 +2481,13 @@ anz der Bedingungen ist erforderlich Profil, aus dem importiert werden soll Namenssuche, npub1…, alice@example.com Unterstützt npub, NIP-05, Hex und Namecoin (.bit / d/ / id/) - Folgeliste nachschlagen Tipp %1$d Konten gefunden %1$d ausgewählt - Über Namecoin aufgelöst - Folge jetzt %1$d Konten - Dein Feed ist bereit. - Überspringen - Weiteres suchen %1$d Konten folgen - Weitere importieren - Weiter Vorerst überspringen - Löse %1$s auf… Folgeliste wird abgerufen… Keine Follows gefunden - Folge %1$d Konten… "Gib das Profil eines Freundes oder Community-Leaders ein. Du kannst deren npub, NIP-05-Adresse oder einen Namecoin-Namen wie alice@example.bit oder id/alice für blockchain-verifizierte Identitäten verwenden." Alle auswählen %1$d%% Verfügbarkeit @@ -2835,7 +2495,6 @@ anz der Bedingungen ist erforderlich Verbindung testen Teste Server… Verbunden - Fehlgeschlagen Testergebnisse Diagnose Letzter Test @@ -2848,9 +2507,6 @@ anz der Bedingungen ist erforderlich Vertrauen Ablehnen Relay-Synchronisierung - Relay-Synchronisierung - Veröffentliche deine Ereignisse erneut auf allen bekannten Relays, um deine Outbox-, Inbox- und DM-Relays aktuell zu halten. Erfordert WLAN — dies kann viele Daten verbrauchen. - Relay-Synchronisierung öffnen… Was passiert Dieses Tool durchsucht alle Relays, die deine App gesehen hat, und verteilt deine Ereignisse an die richtigen Ziele: Lade alle Ereignisse herunter, die du erstellt hast, und sende sie an deine Outbox-Relays. @@ -2860,14 +2516,9 @@ anz der Bedingungen ist erforderlich Mobile Daten verwenden? Synchronisierung starten Trotzdem starten (mobile Daten) - Pausen - Fortsetzen - Neu starten Abbrechen Relais: %1$d / %2$d Ereignisse verteilt: %1$d neue von %2$d gesendeten und %3$d empfangenen - Synchronisierung pausiert - %1$d von %2$d Relays abgeschlossen — bisher %3$d Ereignisse verteilt. Tippe auf Fortsetzen. Synchronisierung abgeschlossen %1$d Ereignisse an Ziel-Relays weitergeleitet von %2$d empfangenen. %1$d Ereignisse von Ziel-Relays als neu akzeptiert. @@ -2882,16 +2533,13 @@ anz der Bedingungen ist erforderlich ges. %1$s empf. %1$s neu %1$s - keine Ereignisse Bitcoin Explorer (OTS) - ereignisse Ereignisse von dir Ereignisse an dich durchsuchbare Ereignisse DMs profile Ausgangs-Listen - relaiseinstellungen Zuletzt gesehen vor %1$s Zuletzt gesehen am %1$s (vor %2$s) Gerade eben gesehen @@ -2949,7 +2597,6 @@ anz der Bedingungen ist erforderlich Suche nach Geräten in deinem WLAN… HLS-Upload - Veröffentliche HLS in mehreren Auflösungen auf deinem Medienserver Video auswählen Dein Video wird in mehrere Auflösungen transkodiert, damit Zuschauer eine reibungslose Wiedergabe auf jeder Verbindung erhalten. Ändern @@ -2964,10 +2611,6 @@ anz der Bedingungen ist erforderlich H.265 ist auf diesem Gerät nicht verfügbar — wechsle zu H.264. Versionen Quellauflösung: %1$d×%2$d - Wird erstellt: %1$s - (%1$s übersprungen — über Quelle) - %1$d kbps - über Quelle — wird übersprungen HD-Video veröffentlichen Veröffentliche „%1$s“… Transkodiere %1$s @@ -2979,7 +2622,6 @@ anz der Bedingungen ist erforderlich Video veröffentlicht Dein HD-Video ist auf Nostr live. Etwas ist schiefgelaufen - Notiz anzeigen Fertig Erneut versuchen Paket-Aktionen @@ -2994,30 +2636,21 @@ anz der Bedingungen ist erforderlich Attestierung Gültig Ungültig - Akzeptiert - Abgelehnt Wird verifiziert - Verifiziert Widerrufen Gültig ab %1$s Gültig bis %1$s Attestierungsanfrage - Attestierung für ein Ereignis anfordern Empfehlung des Attestierers Empfohlen für Arten: Kompetenz des Attestierers - Kompetent für die Verifizierung von Arten: %1$s - Bestätigt Beantragt Attestierung für Zeitraum Von Bis Jetzt Gesamter Zeitraum - Letzte Synchronisierung: %1$s - Seit letzter Synchronisierung Web-Lesezeichen - Noch keine Web-Lesezeichen. Tippe auf + um eines hinzuzufügen. Web-Lesezeichen hinzufügen Web-Lesezeichen bearbeiten URL @@ -3056,13 +2689,10 @@ anz der Bedingungen ist erforderlich https://example.com/image.jpg Website-URL (optional) https://beispiel.com - Frist (optional) Frist festlegen Neues Ziel - Ziel erstellen Löschanfrage Fordere Relays auf, alle deine Daten bis zum gewählten Datum dauerhaft zu löschen. Diese Aktion basiert auf NIP-62 und ist in einigen Rechtsgebieten rechtlich bindend. - Relay auswählen Ziel-Relays ALLE RELAYS Dies wird ALLE Relays auffordern, alles zu löschen, was mit deinem Schlüssel bis zum gewählten Datum verbunden ist. Dieses Ereignis wird so breit wie möglich gesendet. Diese Aktion kann nicht rückgängig gemacht werden. @@ -3078,7 +2708,6 @@ anz der Bedingungen ist erforderlich Datum wählen Uhrzeit wählen Löschverlauf - Aktualisieren Dies sind deine vergangenen Löschanfrage-Ereignisse, die auf verbundenen Relays gefunden wurden. Relays, die in diesen Ereignissen markiert sind, sollten keine deiner Daten von vor dem Ereignisdatum mehr speichern. Keine Löschanfragen gefunden Du hast noch keine Löschanfrage-Ereignisse gesendet. @@ -3121,7 +2750,6 @@ anz der Bedingungen ist erforderlich Ereignis sperren Art erlauben IP blockieren - Öffentlicher Schlüssel (hex) Ereignis-ID (hex) Art-Nummer IP-Adresse @@ -3132,7 +2760,6 @@ anz der Bedingungen ist erforderlich Relay-Name Relay-Beschreibung Relay-Symbol-URL - Relay verwalten Verwalten Mitglieder Mitglieder von %1$s @@ -3203,7 +2830,6 @@ anz der Bedingungen ist erforderlich Aktionen für Emoji-Paket Meine Emoji-Pakete Emojis - Emoji-Sets durchsuchen Privat Privates Emoji Öffentliche Emojis sind für alle sichtbar und erscheinen in deinem Reaktionsmenü und in der \":\"-Autovervollständigungsauswahl, wenn dieses Paket in deiner Emoji-Liste ist. @@ -3228,4 +2854,10 @@ anz der Bedingungen ist erforderlich Nowhere Drop Nowhere Kunst Nowhere Forum + + Der Lightning-Service des Empfängers unter %1$s ist nicht verfügbar. Er wurde aus der Lightning-Adresse \"%2$s\" berechnet. Fehler: %3$s. Überprüfen Sie, ob der Server online ist und ob die Lightning-Adresse korrekt ist + Konnte %1$s nicht auflösen. Überprüfen Sie, ob Sie verbunden sind, ob der Server online ist und ob die Lightning-Adresse %2$s korrekt ist.\n\nAusnahme war: %3$s + Fehler beim Parsen von JSON von %1$s. Überprüfen Sie die Blitzeinrichtung des Benutzers + Blitzrechnung konnte nicht erstellt werden. Nachricht von %1$s: %2$s + Kann keine Blitzrechnung von %1$s erstellen: Element pr nicht im resultierenden JSON gefunden. diff --git a/amethyst/src/main/res/values-de/strings.xml b/amethyst/src/main/res/values-de/strings.xml index c58a7ff98f..9141f0baba 100644 --- a/amethyst/src/main/res/values-de/strings.xml +++ b/amethyst/src/main/res/values-de/strings.xml @@ -21,8 +21,6 @@ Illegales Verhalten Andere Belästigung - Unbekannt - Relay-Symbol Unbekannter Autor Text kopieren Autor-ID kopieren @@ -36,12 +34,9 @@ Spam / Betrug melden Vortäuschung melden - Anstößigen Inhalt melden Illegales Verhalten melden Malware melden - Melde Mod Malware - Mod Sie verwenden einen öffentlichen Schlüssel und öffentliche Schlüssel sind schreibgeschützt. Mit einem privaten Schlüssel anmelden, um antworten zu können Sie verwenden einen öffentlichen Schlüssel und öffentliche Schlüssel sind schreibgeschützt. Mit einem privaten Schlüssel anmelden, um Beiträge boosten zu können Sie verwenden einen öffentlichen Schlüssel und öffentliche Schlüssel sind schreibgeschützt. Mit einem privaten Schlüssel anmelden, um Beiträge zu liken @@ -52,7 +47,6 @@ Sie verwenden einen öffentlichen Schlüssel, und öffentliche Schlüssel sind nur lesbar. Melden Sie sich mit einem privaten Schlüssel an, um ein Wort oder einen Satz auszublenden Sie verwenden einen öffentlichen Schlüssel und öffentliche Schlüssel sind schreibgeschützt. Mit einem privaten Schlüssel anmelden, um ein Wort oder einen Satz anzeigen zu können Zaps - Aufrufe Boost boosted bearbeitet @@ -65,9 +59,7 @@ Hinzufügen "Antworten auf " " und " - "im Kanal " Profilbanner - Zahlung erfolgreich Fehler beim Parsen der Fehlermeldung " Folgen" " Anhänger" @@ -89,9 +81,7 @@ Sichtbares Präfix 😎 Zum Beitrag hinzufügen - "Fehler beim Parsen der Vorschau für %1$s: %2$s" "Vorschaukartenbild für %1$s" - Neuer Kanal Kanalname Meine tolle Gruppe Bild-URL @@ -102,33 +92,18 @@ Speichern Erstellen Abbrechen - Fehler beim Hochladen des Bildes - Relay-Adresse - Beiträge - Bytes Fehler - Anzahl der Verbindungsfehler in dieser Sitzung - Startseite - Private Nachrichten - Öffentlicher Chat - Globale Feed - Such-Feed Relay hinzufügen - Name Anzeigename Mein Anzeigename Ostrich McAwesome Willkommen Ostrich! Benutzername - Mein Benutzername Über mich Avatar-URL Banner-URL Website-URL Pronomen - LN-Adresse - LN-URL (veraltet) - In die Galerie abspeichern Bild in der Gal erie gespeichert @@ -138,11 +113,8 @@ erie gespeichert Video in der Videogalerie des Telefons gespeichert Video konnte nicht gespeichert werden Bild hochladen - Hochladen… Der Benutzer hat keine Lightning-Adresse eingerichtet, um Sats zu empfangen "Hier antworten…" - Kopiert die Notiz-ID zum Teilen in die Zwischenablage - Kopiere Kanal-ID (Notiz) in die Zwischenablage Bearbeitet die Kanalmetadaten Beitreten Bekannt @@ -154,18 +126,14 @@ erie gespeichert Antworten Deine Galerie - "Folgt" "Berichte" Weitere Optionen " Relais" Webseite Lightning-Adresse Kopiert die Nsec-ID (Ihr Passwort) zur Sicherung in die Zwischenablage - Kopiere geheimen Schlüssel in die Zwischenablage Privaten QR-Code anzeigen QR-Code für verschlüsselten privaten Schlüssel anzeigen - Kopiert den öffentlichen Schlüssel zum Teilen in die Zwischenablage - Kopiere öffentlichen Schlüssel (NPub) in die Zwischenablage Sende eine Direktnachricht Bearbeitet die Benutzermetadaten Folgen @@ -196,8 +164,6 @@ anz der Bedingungen ist erforderlich Wie sollen wir Sie nennen? Sie haben kein Nostr-Konto? Haben Sie schon ein Nostr-Konto? - Neues Konto anlegen - Neuen Schlüssel generieren Feed wird geladen Konto wird geladen "Fehler beim Laden der Antworten: " @@ -205,12 +171,6 @@ anz der Bedingungen ist erforderlich Noch keine Benachrichtigungen. Feed ist leer. Aktualisieren - erstellt - mit Beschreibung von - und Bild - Chat-Namen geändert zu - Beschreibung zu - und Bild zu Verlassen Entfolgen Kanal erstellt @@ -243,7 +203,6 @@ anz der Bedingungen ist erforderlich Beleidigungen / Hassrede Hassrede melden Nacktheit / Pornografie melden - andere Alle als bekannt markieren Alle als neu markieren Alle als gelesen markieren @@ -262,23 +221,18 @@ anz der Bedingungen ist erforderlich Authentifizierung fehlgeschlagen Biometrie konnte den Besitzer dieses Telefons nicht authentifizieren Biometrie konnte den Besitzer dieses Telefons nicht authentifizieren. Fehler: %1$s - Fehler - "Erstellt von %1$s" "Auszeichnungsbild für %1$s" Sie haben eine neue Auszeichnung erhalten Auszeichnung verliehen an Notiztext in die Zwischenablage kopiert Autor-ID in die Zwischenablage kopiert Notiz-ID in die Zwischenablage kopiert - Text auswählen "<Private Nachricht kann nicht entschlüsselt werden>\n\nSie wurden in einer privaten/verschlüsselten Unterhaltung zwischen %1$s und %2$s erwähnt." Neues Konto hinzufügen Konten Konto auswählen Neues Konto hinzufügen Aktives Konto - Verfügt über privaten Schlüssel - Nur öffentlicher Schlüssel, kein privater Schlüssel Zurück Auswählen Browserlink teilen @@ -296,14 +250,12 @@ anz der Bedingungen ist erforderlich Löschen Blockieren Melden - Löschen Nicht erneut anzeigen Spam oder Betrug Beleidigungen oder hasserfülltes Verhalten Bösartige Nachahmung Nacktheit oder explizite Inhalte Illegales Verhalten - Malware Durch das Blockieren eines Benutzers werden deren Inhalte in Ihrer App ausgeblendet. Ihre Notizen sind weiterhin öffentlich sichtbar, auch für Personen, die Sie blockiert haben. Blockierte Benutzer werden auf dem Bildschirm \"Sicherheitsfilter\" aufgelistet. Zu den öffentlichen Lesezeichen hinzufügen Aus den privaten Lesezeichen entfernen Aus den öffentlichen Lesezeichen entfernen - Wallet-Verbindungsdienst - Autorisiert einen Nostr Secret, Zaps ohne Verlassen der App zu bezahlen. Bewahren Sie den geheimen Schlüssel sicher auf und verwenden Sie nach Möglichkeit ein privates Relay - Wallet Connect Public Key - Wallet-Verbindungs-Relay - Wallet-Verbindungs-Geheimnis - Geheimen Schlüssel anzeigen - nsec / hexadezimaler privater Schlüssel Spendenbetrag in Sats - Umfrage veröffentlichen - Erforderliche Felder: - Zap-Empfänger - Hauptbeschreibung der Umfrage… Wahl %s Beschreibung der Umfrageoption - Optionale Felder: Mindest-Zap-Betrag Maximaler Zap-Betrag Konsens (0–100)% - Schließen nach - Tagen Konnte nicht abstimmen Die Umfrage ist für neue Stimmen geschlossen - Zap-Betrag Es ist nur eine Stimme pro Benutzer für diesen Umfragetyp erlaubt "Veranstaltung suchen %1$s" Füge eine öffentliche Nachricht hinzu @@ -382,12 +319,9 @@ anz der Bedingungen ist erforderlich Keine Spur in Nostr, nur in Lightning Dateiserver Wählen Sie einen Server zum Hochladen dieser Datei - LnAddress oder @Benutzer Medienserver Legen Sie Ihre bevorzugten Medienupload Server fest. - Du hast keine NIP-96-Server gesetzt. Du kannst die Amethyst-Liste verwenden oder unten einen hinzufügen ↓ Du hast keine Blossom Server gesetzt. Du kannst die Amethyst-Liste verwenden oder unten einen hinzufügen ↓ - Integrierte Medienserver Amethysts Standardliste. Sie können sie einzeln hinzufügen oder die Liste hinzufügen. Standardliste verwenden Medienserver hinzufügen @@ -400,30 +334,16 @@ anz der Bedingungen ist erforderlich Hashen Fertig Fehler - Deine Relays (NIP-95) - Dateien werden von deinen Relays gehostet. Neuer NIP: Überprüfe, ob sie unterstützt werden Privatsphäre-Optionen - Tor/Orbot-Einrichtung - Verbindung über deine Orbot-Einrichtung herstellen Anpassen Tor-Einstellungen - Von deiner Orbot/Tor trennen? - Deine Daten werden sofort im regulären Netzwerk übertragen Ja Nein - Folgen-Liste Alle Folgen In der Nähe Weltweit Stummliste Standard-Port ist 9050 - ## Über Tor mit Orbot verbinden - \n\n1. Installiere [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Starte Orbot - \n3. Überprüfe in Orbot den Socks-Port. Standardmäßig wird der Port 9050 verwendet - \n4. Ändere gegebenenfalls den Port in Orbot - \n5. Konfiguriere den Socks-Port in diesem Bildschirm - \n6. Drücke die Aktivieren-Schaltfläche, um Orbot als Proxy zu verwenden Orbot Socks-Port Aktiver Tor-Engine Verwenden Sie die interne Version oder Orbot @@ -465,8 +385,6 @@ anz der Bedingungen ist erforderlich Verbergen Sie Ihre IP bei allen Verbindungen Erstellen Sie Ihre eigenen Ungültige Portnummer - Orbot verwenden - Tor/Orbot trennen Private Nachrichten Benachrichtigt dich, wenn eine private Nachricht eingeht Erhaltene Zaps @@ -475,20 +393,9 @@ anz der Bedingungen ist erforderlich Von %1$s für %1$s Benachrichtigen: - Unterhaltung beitreten - Benutzer- oder Gruppen-ID - npub, nevent oder hex - Erstellen - Beitreten Heute Inhaltswarnung Dieser Beitrag enthält sensiblen Inhalt, den einige Personen als beleidigend oder verstörend empfinden könnten - Sensiblen Inhalt immer ausblenden - Sensiblen Inhalt immer anzeigen - Immer Inhaltswarnungen anzeigen - Empfohlene Apps: - Spam von Fremden filtern - Warnung bei Meldungen von deinen Abonnements Neues Reaktionssymbol Keine Reaktionstypen ausgewählt. Lange drücken, um zu ändern Zap-Sammlung @@ -499,37 +406,24 @@ anz der Bedingungen ist erforderlich In Relay schreiben Die Menge in Bytes, die an dieses Relais gesendet wurde, einschließlich Filter und Ereignisse Die Menge in Bytes, die von diesem Relais empfangen wurde, einschließlich Filter und Ereignisse - Ein Fehler ist beim Abrufen von Relay-Informationen von %1$s aufgetreten Inhaber Version Programme Kontakt Unterstützte NIPs - Eintrittsgebühren Zahlungs-URL Einschränkungen Länder Sprachen - Tags Veröffentlichungsrichtlinie Fehler und Hinweise von diesem Relais - Nachrichtenlänge - Abonnements - Filter - Länge der Abonnement-ID Mindestpräfix Maximale Anzahl von Ereignis-Tags - Inhaltslänge Mindest-PoW - Authentifizierung - Zahlung Cashu-Token Einlösen - An Zap Wallet senden - In Cashu Wallet öffnen Token kopieren Keine Lightning-Adresse festgelegt - Token in die Zwischenablage kopiert LIVE OFFLINE BEENDET @@ -549,7 +443,6 @@ anz der Bedingungen ist erforderlich App Einstellungen Einstellungen Immer - Nur WLAN Unbegrenztes WLAN Nie Fertig @@ -573,7 +466,6 @@ anz der Bedingungen ist erforderlich Wählen Sie den Beitragsstil Profilgalerie-Stil Galeriestil auswählen - Bild laden Spammer Stummgeschaltet. Drücken, um Ton einzuschalten Ton ein. Zur Stummschaltung drücken @@ -581,12 +473,8 @@ anz der Bedingungen ist erforderlich Nostr-Adresse verifiziert Nostr-Adresse konnte nicht verifiziert werden Nostr-Adresse wird überprüft - Alle auswählen/abwählen Standard Auf Standardeinstellung zurücksetzen - Wählen Sie ein Relais aus, um fortzufahren - Weiterleiten von Zaps an: - Unterstützende Clients leiten Zaps an die LNAddress oder das Benutzerprofil unten weiter, anstatt an Ihre eigene Adresse Ort preisgeben als Fügt dem Beitrag einen Geohash Ihres Standorts hinzu. Die Öffentlichkeit wird wissen, dass Sie sich innerhalb von 5 km (3 mi) vom aktuellen Standort befinden Standort-exklusiver Beitrag @@ -594,9 +482,6 @@ anz der Bedingungen ist erforderlich Standort wird geladen Keine Standortberechtigungen Fügt eine Warnung für sensiblen Inhalt hinzu, bevor Ihr Inhalt angezeigt wird. Dies ist ideal für NSFW-Inhalte (nicht sicher für die Arbeit) oder Inhalte, die manche Menschen als anstößig oder verstörend empfinden könnten - Neues Feature - Um diesen Modus zu aktivieren, muss Amethyst eine NIP-17-Nachricht senden (GiftWrapped, Versiegelte Direkt- und Gruppennachrichten). NIP-17 ist neu und die meisten Clients haben es noch nicht implementiert. Stellen Sie sicher, dass der Empfänger einen kompatiblen Client verwendet. - Aktivieren Öffentlich Neue öffentliche oder private Gruppe Privat @@ -613,7 +498,6 @@ anz der Bedingungen ist erforderlich Bilder und GIFs automatisch laden Videos und GIFs automatisch abspielen URL-Vorschauen anzeigen - Wann Bilder geladen werden sollen Stapel kopieren In Zwischenablage kopieren Npub in Zwischenablage kopieren @@ -624,45 +508,23 @@ anz der Bedingungen ist erforderlich Medien hinzugefügt Medien wurden zu Ihrer Profilgalerie hinzugefügt Erstellt am - Regeln Mit Amber anmelden Status aktualisieren - Fehler beim Verarbeiten der Fehlermeldung Die Abstimmungen werden nach der Höhe des Zaps gewichtet. Sie können einen Mindestbetrag festlegen, um Spam zu verhindern, und einen Höchstbetrag, um zu verhindern, dass große Zapper die Abstimmung dominieren. Verwenden Sie denselben Betrag in beiden Feldern, um sicherzustellen, dass jeder Stimme der gleiche Wert zukommt. Lassen Sie es leer, um jeden Betrag zu akzeptieren. Zap konnte nicht gesendet werden Mit dem Benutzer kommunizieren Nachricht %1$s OK - Konnte %1$s nicht erreichen: %2$s - Fehler beim Zusammenstellen der NIP-11-URL für %1$s: %2$s - Konnte %1$s nicht erreichen: %2$s - Fehler beim Analysieren der Antwort von %1$s: %2$s - Relais abgelehnt Nachfragen %1$s: %2$s - Konnte %1$s nicht erreichen: %2$s - Konnte das Ergebnis von %1$s nicht verarbeiten: %2$s - %1$s fehlgeschlagen mit Code %2$s - Aktiv für: - Startseite - Nachrichten - Plaudern - Global - Suche Zaps aufteilen und weiterleiten Unterstützende Clients werden Zaps an die hier hinzugefügten Benutzer aufteilen und weiterleiten, anstatt an Sie Benutzer suchen und hinzufügen Benutzername oder Anzeigename Fehlende Lightning-Konfiguration Benutzer %1$s hat keine Lightning-Adresse eingerichtet, um Sats zu empfangen - Prozent - 25 - Zaps aufteilen mit - Zaps weiterleiten an - Lightning-Wallets nicht gefunden Bezahlt Brieftasche %1$s Fehler beim Öffnen der Signatur-App Die Unterzeichner-App konnte nicht gefunden werden. Prüfen Sie, ob die App nicht deinstalliert wurde - Signaturanfrage abgelehnt Stellen Sie sicher, dass die Unterzeichner-Anwendung diese Transaktion autorisiert hat Keine Wallets gefunden, um eine Lightning-Rechnung zu bezahlen (Fehler: %1$s). Installieren Sie eine Lightning-Wallet, um Zaps zu verwenden Keine Wallets gefunden, um eine Lightning-Rechnung zu bezahlen. Installieren Sie eine Lightning-Wallet, um Zaps zu verwenden @@ -673,36 +535,19 @@ anz der Bedingungen ist erforderlich Option auswählen Konnte Rechnung nicht bezahlen Konnte nicht abheben - Konnte Wallet Connect nicht einrichten - Fehler beim Parsen der NIP-47-Verbindungszeichenfolge. Überprüfen Sie, ob diese korrekt ist, Ihr Wallet-Anbieter: %1$s. Fehler: %2$s - Fehler beim Parsen der NIP-47-Verbindungszeichenfolge. Überprüfen Sie, ob diese korrekt ist, Ihr Wallet-Anbieter: %1$s. Cashu konnte nicht eingelöst werden Mint hat folgende Fehlermeldung geliefert: %1$s - Cashu-Token bereits ausgegeben. Cashu erhalten %1$s Sats wurden an Ihre Wallet gesendet. (Gebühren: %2$s Sats) Keine kompatible Cashu-Brieftasche im System gefunden Konnte Rechnung nicht vom Server des Empfängers abrufen Ihr Wallet-Connect-Anbieter hat folgenden Fehler zurückgegeben: %1$s - Konnte keine Verbindung zu Tor herstellen - Herunterladen des Relaisdokuments nicht verfügbar Konnte keine LNUrl aus der Lightning-Adresse \"%1$s\" zusammenstellen. Überprüfen Sie die Konfiguration des Benutzers - Der Lightning-Service des Empfängers unter %1$s ist nicht verfügbar. Er wurde aus der Lightning-Adresse \"%2$s\" berechnet. Fehler: %3$s. Überprüfen Sie, ob der Server online ist und ob die Lightning-Adresse korrekt ist - Konnte %1$s nicht auflösen. Überprüfen Sie, ob Sie verbunden sind, ob der Server online ist und ob die Lightning-Adresse %2$s korrekt ist - Konnte %1$s nicht auflösen. Überprüfen Sie, ob Sie verbunden sind, ob der Server online ist und ob die Lightning-Adresse %2$s korrekt ist.\n\nAusnahme war: %3$s - Konnte Rechnung nicht von %1$s abholen Rechnung konnte nicht von %1$s abgerufen werden: %2$s - Fehler beim analysieren von JSON aus der Lightning-Adresse. Überprüfen Sie die Lightning-Konfiguration des Benutzers Fehler beim Parsen von JSON von %1$s. Überprüfen Sie die Blitzeinrichtung des Benutzers - Callback-URL nicht in der Serverkonfiguration der Lightning-Adresse des Benutzers gefunden Callback-URL aus %1$s Antwort nicht gefunden - Fehler beim Parsen von JSON aus der Rechnungsabruf der Lightning-Adresse. Überprüfen Sie die Lightning-Konfiguration des Benutzers - Fehler beim Parsen von JSON von %1$s. Überprüfen Sie die Blitzeinrichtung des Benutzers Falscher Rechnungsbetrag (%1$s Sats) von %2$s. Er hätte %3$s sein sollen Konnte keine Lightning-Rechnung erstellen, bevor der Zap gesendet wurde. Die Lightning-Wallet des Empfängers hat folgenden Fehler gesendet: %1$s - Blitzrechnung konnte nicht erstellt werden. Nachricht von %1$s: %2$s - Konnte keine Lightning-Rechnung erstellen, bevor der Zap gesendet wurde. Element pr wurde nicht in der resultierenden JSON gefunden. - Kann keine Blitzrechnung von %1$s erstellen: Element pr nicht im resultierenden JSON gefunden. Nur-Lese-Benutzer Keine Reaktionen eingerichtet Einen Push-Benachrichtigungsanbieter auswählen @@ -720,13 +565,11 @@ anz der Bedingungen ist erforderlich Dem Verkäufer eine Nachricht senden Hallo %1$s, ist das noch verfügbar? Hallo, ist das noch verfügbar? - Artikel verkaufen Titel iPhone 13 Zustand Kategorie Preis (in Sats) - 1000 Ort Stadt, Staat, Land Neu @@ -755,20 +598,13 @@ anz der Bedingungen ist erforderlich Sonstiges Fehler beim Laden der Medien Konnte die komprimierte Datei nicht öffnen - Fehler beim komprimieren der Medien: %1$s Fehler beim Hochladen: %1$s Der Server hat nach dem Hochladen keine URL angegeben Hochgeladene Medien konnten nicht vom Server heruntergeladen werden Die heruntergeladene Datei konnte nach dem Hochladen nicht überprüft werden: %1$s - Lokale Datei konnte nicht zum Hochladen vorbereitet werden: %1$s Konnte %1$s nicht erreichen: %2$s - Upload fehlgeschlagen: %1$s Löschen fehlgeschlagen: %1$s Medien sind zu groß für NIP-95 - Miniaturansicht kann nicht geladen werden - Konnte Kopfzeileninformationen nicht vorbereiten: %1$s - Komprimierung abgebrochen - Komprimierung fehlgeschlagen eine Datei zurückzugeben Medienqualität Wählen Sie Niedrige Qualität, um Ihre Medien in eine kleinere Datei mit geringerer Qualität zu komprimieren, Hohe Qualität, um sie in eine größere Datei mit höherer Qualität zu komprimieren, oder \"Ohne Kompression\", um die Medien ohne Kompression hochzuladen. Niedrig @@ -777,15 +613,11 @@ anz der Bedingungen ist erforderlich Ohne Kompression Entwurf bearbeiten Einloggen mit QR-Code - Route Startseite - Suche Entdecken Nachrichten Benachrichtigungen - Global Kurzfilme - Sicherheitsfilter Neuer Beitrag Neue Kurzfilme: Bilder oder Videos Neue Community-Notiz @@ -800,29 +632,22 @@ anz der Bedingungen ist erforderlich %1$s weiterleiten Rela-Liste erweitern Notizoptionen - Rela-Listenauswahl Umfrage Umfrage deaktivieren Bitcoin-Rechnung hinzufügen Bitcoin-Rechnung abbrechen - Verkauf eines Artikels abbrechen Zapraiser hinzufügen Zapraiser abbrechen Ort hinzufügen Ort entfernen - Zap-Aufteilung hinzufügen - Zap-Aufteilung abbrechen Inhaltswarnung hinzufügen Inhaltswarnung entfernen Npub als QR-Code anzeigen Ungültige Adresse Amethyst hat eine URI zum Öffnen erhalten, aber diese URI war ungültig: %1$s DM Posteingangs-Relais - Relais: %1$s - Verwendung regulärer Relais Richten Sie Ihre privaten Posteingangs-Relais ein Diese Einstellung lässt alle wissen, welche Relais verwendet werden sollen, wenn sie Nachrichten an Sie senden. Ohne diese könnten Sie einige Nachrichten verpassen. - Gute Optionen sind:\n - inbox.nostr.wine (bezahlt)\n - you.nostr1.com (persönliche Relais - bezahlt) Gute Optionen sind:\n - auth.nostr1.com (gratis)\n - inbox.nostr.wine (bezahlt)\n - relay.0xchat.com (gratis) Fügen Sie 1–3 Relais ein, die als Ihr privater Posteingang dienen sollen. DM Posteingangs-Relais sollten Nachrichten von jedem akzeptieren, aber nur Ihnen erlauben, sie herunterzuladen. Jetzt einrichten @@ -831,7 +656,6 @@ anz der Bedingungen ist erforderlich Das Erstellen einer Relaisliste, die speziell für die Suche und Benutzerkennzeichnung entwickelt wurde, wird diese Ergebnisse verbessern. Fügen Sie 1–3 Relais ein, die beim Suchen nach Inhalten oder beim Taggen von Benutzern verwendet werden sollen. Stellen Sie sicher, dass Ihre ausgewählten Relais NIP-50 implementieren Gute Optionen sind:\n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com - DM-Upload Relaiseinstellungen Öffentliche Heimrelais Dieser Relais-Typ speichert alle Ihre Inhalte. Amethyst sendet Ihre Beiträge hierher und andere werden diese Relais verwenden, um Ihre Inhalte zu finden. Fügen Sie 1–3 Relais ein. Sie können persönliche Relais, bezahlte Relais oder öffentliche Relais sein. @@ -841,10 +665,6 @@ anz der Bedingungen ist erforderlich Fügen Sie 1–3 Relais ein, die als Ihr privater Posteingang dienen sollen. Andere werden diese Relais verwenden, um Ihnen DMs zu senden. DM-Posteingangsrelais sollten Nachrichten von jedem akzeptieren, aber nur Ihnen erlauben, sie herunterzuladen. Gute Optionen sind:\n - inbox.nostr.wine (bezahlt)\n - you.nostr1.com (persönliche Relais - bezahlt) Private Relais Fügen Sie zwischen 1–3 Relais ein, um Ereignisse zu speichern, die niemand anders sehen kann, wie Ihre Entwürfe und/oder App-Einstellungen. Idealerweise sind diese Relais entweder lokal oder erfordern eine Authentifizierung, bevor Sie die Inhalte eines jeden Benutzers herunterladen. - Allgemeine Relais - Amethyst verwendet diese Relais, um Beiträge für Sie herunterzuladen. - Empfohlene Relais - Fügen Sie die folgenden Relais zu Ihrer Liste hinzu, um Beiträge von den aufgelisteten Benutzern zu erhalten. Suchrelais Liste der Relais, die für die Suche und das Taggen von Benutzern verwendet werden. Das Taggen und die Suche funktionieren nicht, wenn keine Optionen verfügbar sind. Lokale Relais @@ -856,11 +676,8 @@ anz der Bedingungen ist erforderlich Diese Version wurde Ihnen präsentiert von: Version %1$s Vielen Dank! - Maximallimit Eingeschränkte Schriften Geforkt von - FORK - Git Repository: %1$s Internet: Klonen: OTS: %1$s @@ -868,20 +685,13 @@ anz der Bedingungen ist erforderlich Es gibt einen Beweis, dass dieser Beitrag irgendwann vor %1$s signiert wurde. Der Beweis wurde zu diesem Datum und Uhrzeit in der Bitcoin-Blockchain gestempelt. Beitrag bearbeiten Vorschlag zur Verbesserung Ihres Beitrags - Zusammenfassung der Änderungen - Schnelle Korrekturen… Den Vorschlag annehmen Video in einem Pop-Up starten Herunterladen - Liedtext an - Liedtext aus - Versiegelte Nachricht aus. Klicken Sie, um die versiegelte Nachricht einzuschalten - Versiegelte Nachricht an. Klicken Sie, um die versiegelte Nachricht auszuschalten Senden Benutzernamen als Audio abspielen Reißzwecke QR-Code scannen - Navigieren Sie zum Drittanbieter-Wallet-Anbieter Alby Es ist nicht möglich, auf einen Entwurf zu antworten Es ist nicht möglich, einen Entwurf zu zitieren Es ist nicht möglich, auf einen Entwurf zu reagieren @@ -922,15 +732,12 @@ anz der Bedingungen ist erforderlich Unzureichender Speicher - Der Server hat nicht genug Speicher, um die Anfrage erfolgreich zu verarbeiten Schleife erkannt - Der Server erkennt eine Endlosschleife, während er die Anfrage bearbeitet Netzwerk-Authentifizierung erforderlich - Der Client muss authentifiziert werden, um auf das Netzwerk zuzugreifen - NIP-96 Server - Fügen Sie beliebig viele Server hinzu. Sie können wählen, welche später beim Hochladen Ihres Bildes verwendet werden soll Blossom Server Fügen Sie beliebig viele Server hinzu. Sie können wählen, welche später beim Hochladen Ihres Bildes verwendet werden soll NIP-96 Server hinzufügen Blossom Server hinzufügen Alles löschen Möchten Sie wirklich alle Entwürfe löschen? - Stapel: Torrentdatei Herunterladen Fehler beim Öffnen der Datei @@ -938,23 +745,19 @@ anz der Bedingungen ist erforderlich Liste zum Filtern des Feeds auswählen Beim Sperren des Geräts abmelden Bild teilen… - Du verwendest einen öffentlichen Schlüssel, der nur lesbar ist. Melde dich mit einem privaten Schlüssel an, um Einstellungen ändern zu können Du verwendest einen öffentlichen Schlüssel, der nur lesbar ist. Melde dich mit einem privaten Schlüssel an, um hochladen zu können Du verwendest einen öffentlichen Schlüssel, der nur lesbar ist. Melde dich mit einem privaten Schlüssel an, um Ereignisse zu signieren Unbefugte Entschlüsselung Der Signierer hat die erforderliche Entschlüsselung nicht autorisiert. Aktiviere NIP-44-Entschlüsselung in deiner Signierer-App und versuche es erneut Signierer nicht gefunden Wurde die Signierer-App deinstalliert? Überprüfe, ob sie installiert ist und dieses Konto enthält. Melde dich ab und wieder an, falls sich die App geändert hat. - Keine Beschreibung gefunden Ein Foto aufnehmen Video aufnehmen Eine Nachricht aufnehmen - Eine Nachricht aufnehmen Zum Aufnehmen einer Nachricht gedrückt halten Bezahltes Relay Tor-Verbindung erzwingen Auszeichnungsbild - Folgt über Proxy Signaturanfrage abgelehnt Verbundene Relays Aktuelle Liste der verwendeten Relays @@ -979,36 +782,19 @@ anz der Bedingungen ist erforderlich Feed-Filter, %1$s Feed Moderationswarteschlange - Ungültige NIP-47 URI - Die URI %1$s ist keine gültige NIP-47 Anmelde-URI. Der Benutzer veröffentlicht seine Inhalte auf diesen Relays Der Benutzer erhält Benachrichtigungen auf diesen Relays Der Benutzer empfängt Direktnachrichten auf diesen Relays - Diese Nachricht verschwindet in %1$d Tagen Absturzbericht gefunden Möchten Sie den letzten Absturzbericht per Direktnachricht an Amethyst senden? Es werden keine persönlichen Daten weitergegeben Senden - Über uns Richtlinien Moderatoren Dropdown-Menü öffnen Folge-Sets - Markierte Lesezeichen - Allgemeine Lesezeichen - Öffentlich - Privat - Gemischt - Es scheint, dass du noch keine Folge-Sets hast.\nTippe unten zum Aktualisieren oder verwende die Plus-Taste, um ein neues zu erstellen. Autor zum Folge-Set hinzufügen Benutzer zu Listen hinzufügen oder entfernen, oder eine neue Liste mit diesem Benutzer erstellen. Symbol für Liste - %1$s ist nicht in dieser Liste - Deine Folge-Sets - Keine Folge-Sets gefunden oder du hast keine. Tippe unten zum Aktualisieren oder verwende das Menü, um eines zu erstellen. - Beim Abrufen ist ein Problem aufgetreten: %1$s - Neue Liste erstellen - Neue %1$s-Liste mit Benutzer erstellen - Erstellt ein %1$s-Folge-Set und fügt %2$s hinzu. Neue Folgen-Liste Set-Name Set-Beschreibung (optional) @@ -1018,8 +804,12 @@ anz der Bedingungen ist erforderlich zu.. Umbenennen Das Ereignis enthält nicht genügend Informationen, um einen Magnetlink zu erstellen - Meine Listen/Sets Signierer auswählen H.265/HEVC-Codec verwenden Bessere Qualität bei kleinerer Dateigröße, aber nicht alle Geräte unterstützen die H.265-Wiedergabe. + Der Lightning-Service des Empfängers unter %1$s ist nicht verfügbar. Er wurde aus der Lightning-Adresse \"%2$s\" berechnet. Fehler: %3$s. Überprüfen Sie, ob der Server online ist und ob die Lightning-Adresse korrekt ist + Konnte %1$s nicht auflösen. Überprüfen Sie, ob Sie verbunden sind, ob der Server online ist und ob die Lightning-Adresse %2$s korrekt ist.\n\nAusnahme war: %3$s + Fehler beim Parsen von JSON von %1$s. Überprüfen Sie die Blitzeinrichtung des Benutzers + Blitzrechnung konnte nicht erstellt werden. Nachricht von %1$s: %2$s + Kann keine Blitzrechnung von %1$s erstellen: Element pr nicht im resultierenden JSON gefunden. diff --git a/amethyst/src/main/res/values-el-rGR/strings.xml b/amethyst/src/main/res/values-el-rGR/strings.xml index 05b640d73c..21ff85b738 100644 --- a/amethyst/src/main/res/values-el-rGR/strings.xml +++ b/amethyst/src/main/res/values-el-rGR/strings.xml @@ -15,8 +15,6 @@ Ανεπιθύμητο Πλαστοπροσωπία Παράνομη Συμπεριφορά - Άγνωστο - Εικονίδιο Διαμοιραστή Άγνωστος Συντάκτης Αντιγραφή Κειμένου Αντιγραφή ID Συντάκτη @@ -27,7 +25,6 @@ Αναφορά Ανεπιθύμητου / Απάτης Αναφορά Πλαστοπροσωπίας - Αναφορά Διευκρίνησης Περιεχομένου Αναφορά Παράνομης Συμπεριφοράς Συνδεθείτε με το \"Μυστικό Κλειδί\" σας για να απαντάτε σε δημοσιεύσεις Συνδεθείτε με το \"Μυστικό Κλειδί\" σας για να προωθείτε δημοσιεύσεις @@ -38,7 +35,6 @@ Συνδεθείτε με το \"Μυστικό Κλειδί\" σας για να σταματήσετε να ακολουθείτε κάποιον Συνδεθείτε με το \"Μυστικό Κλειδί\" σας ώστε να μπορείτε να αποκλείετε ανεπιθύμητες λέξεις ή φράσεις Συνδεθείτε με το \"Μυστικό Κλειδί\" σας ώστε να μπορείτε να αναζητάτε συγκεκριμένες λέξεις ή φράσεις - Προβολή μετρήσεων Προώθηση προωθημένο Παράθεση @@ -46,9 +42,7 @@ Προσθήκη "απάντηση σε " " και " - "στο κανάλι " Ταπετσαρία Προφίλ - Επιτυχής Πληρωμή Σφάλμα ανάλυσης σφάλμα μηνύματος " Ακολουθείτε" " Ακόλουθοι" @@ -63,9 +57,7 @@ Σας ευχαριστώ πολύ! Ποσό σε Sats Αποστολή Sats - "Σφάλμα ανάλυσης προεπισκόπησης για %1$s : %2$s" "Προεπισκόπηση Κάρτα Εικόνας για %1$s" - Νέο Κανάλι Όνομα Καναλιού Η υπέροχη Ομάδα μου Διεύθυνση Εικόνας Url @@ -76,34 +68,20 @@ Αποθήκευση Δημιουργία Ακύρωση - Αποτυχία μεταφόρτωσης εικόνας - Διεύθυνση Διαμοιραστή - Δημοσιεύσεις Σφάλματα - Ροή Αρχικής Σελίδας - Ροή Προσωπικών Μηνυμάτων - Ροή Δημόσιας Συζήτησης - Παγκόσμια Ροή - Ροή Αναζήτησης Προσθήκη Διαμοιραστή Προβολή Ονόματος Το εμφανιζόμενο ονόμά μου Όνομα Χρήστη - Το Όνομα Χρήστη μου Σχετικά με εμένα Διεύθυνση εικόνας Προφίλ URL Διεύθυνση εικόνας Ταπετσαρίας URL Διεύθυνση Ιστοσελίδας URL - Διεύθυνση LN - Διεύθυνση LN (ξεπερασμένη) Η εικόνα αποθηκεύτηκε στη συλλογή Αποτυχία αποθήκευσης εικόνας Μεταφόρτωση εικόνας - Μεταφόρτωση… Ο χρήστης δεν έχει ορίσει διεύθυνση LN για να λαμβάνει sats "απαντήστε εδώ…" - Αντιγραφή του ID της δημοσίευσης στο πρόχειρο για κοινή χρήση στο Nostr - Αντιγραφή του ID του Καναλιού (της δημοσίευσης) στο πρόχειρο Επεξεργασία των Μεταδεδομένων των Καναλιού Εγγραφή Γνωστό @@ -113,16 +91,12 @@ Συζητήσεις Δημοσιεύσεις Απαντήσεις - "Άτομα που ακολουθώ" "Αναφορές" Περισσότερες Επιλογές " Διαμοιραστές" Ιστοσελίδα Διεύθυνση Lightning Αντιγράφει το \"Μυστικό Κλειδί\" σας (Nsec ID ή αλλιώς ο μυστικός κωδικός πρόσβασής σας) στο πρόχειρο για δημιουργία αντιγράφου ασφαλείας - Αντιγραφή του \"Μυστικού Κλειδιού\" σας στο Πρόχειρο - Αντιγράφει το \"Δημόσιο Κλειδί\" σας στο Πρόχειρο για κοινή χρήση - Αντιγραφή του \"Δημόσιου Κλειδιού\" σας (NPub) στο Πρόχειρο Αποστολή Άμεσου Μηνύματος Επεξεργασία των Μεταδεδομένων του Χρήστη Σας ακολουθεί @@ -142,7 +116,6 @@ Απαιτείται αποδοχή των όρων Απαιτείται Κλειδί Σύνδεση - Δημιουργία νέου κλειδιού Φόρτωση ροής Φόρτωση λογαριασμού @@ -151,12 +124,6 @@ Προσπαθήστε ξανά Η Ροή είναι κενή. Ανανέωση - δημιουργήθηκε - με περιγραφή του - και εικόνα - αλλάξτε όνομα συνομιλίας σε - περιγραφή σε - και εικόνα σε Αποχώρηση Να μην ακολουθώ Το κανάλι δημιουργήθηκε @@ -177,7 +144,6 @@ Ασέβεια / Ρητορική μίσους Αναφορά Ρητορικής μίσους Αναφορά Γυμνό / Πορνό - άλλοι Σήμανση όλων των γνωστοποιήσεων ως αναγνωσμένων Σήμανση όλων των νέων δημοσιεύσεων ως αναγνωσμένων Σήμανση όλων ως αναγνωσμένα @@ -187,23 +153,18 @@ Αποτυχία ταυτοποίησης Η βιομετρική ταυτοποίηση του ιδιοκτήτη αυτού του τηλεφώνου απέτυχε Η βιομετρική ταυτοποίηση του ιδιοκτήτη αυτού του τηλεφώνου απέτυχε. Σφάλμα: %1$s - Σφάλμα - "Δημιουργήθηκε από %1$s" "Σήμα βράβευσης για %1$s" Λάβατε ένα νέο Σήμα Βράβευσης Απονομή σήματος βράβευσης σε Το κείμενο της δημοσίευσης αποθηκεύτηκε στο πρόχειρο Το \"Δημόσιο Κλειδί\" του συντάκτη της δημοσίευσης αποθηκεύτηκε στο πρόχειρο Το ID της δημοσίευσης (@note1) αποθηκεύτηκε στο πρόχειρο - Επιλογή Κειμένου "<Unable to decrypt private message>\n\nΕιδοποίηση ιδιωτικής συνομιλίας μεταξύ %1$s και %2$s." Προσθήκη Νέου Λογαριασμού Λογαριασμοί Επιλογή Λογαριασμού Προσθήκη Νέου Λογαριασμού Ενεργός λογαριασμός - Διαθέτει \"Μυστικό Κλειδί\" - Μόνο για ανάγνωση, χωρίς \"Μυστικό Κλειδί\" Επιστροφή Επιλογή Κοινοποίηση Συνδέσμου Περιηγητή @@ -220,7 +181,6 @@ Διαγραφή Αποκλεισμός Αναφορά - Διαγραφή Να μην εμφανιστεί ξανά Ανεπιθύμητο ή απάτη Υβριστικό περιεχόμενο ή ρητορική μίσους @@ -245,29 +205,14 @@ Προσθήκη στους Δημόσιους Σελιδοδείκτες Αφαίρεση από Ιδιωτικούς Σελιδοδείκτες Αφαίρεση από Δημόσιους Σελιδοδείκτες - Υπηρεσία Σύνδεσης Πορτοφολιού - Εξουσιοδοτεί ένα Nostr Secret να εκτελέσει πληρωμή zaps εντός της εφαρμογής. Κρατήστε το Nostr Secret ασφαλές και χρησιμοποιήστε έναν ιδιωτικό Διαμοιραστή αν είναι δυνατόν - Σύνδεση Πορτοφολιού, Δημόσιο Κλειδί (Pubkey) - Σύνδεση Πορτοφολιού, Διαμοιραστής (Relay) - Σύνδεση Πορτοφολιού, Secret - Εμφάνιση \"Μυστικό Κλειδί\" - nsec / hex μυστικό κλειδί Νέο ποσό σε Sats - Δημοσίευση Δημοσκόπησης - Απαιτούμενα Πεδία: - Παραλήπτες Zap - Κύρια περιγραφή Δημοσκόπησης… Επιλογή %s Περιγραφή επιλογής δημοσκόπησης - Προαιρετικά πεδία: Ελάχιστο Zap Μέγιστο Zap Συναίνεση - Λήξη μετά από - ημέρες Αδυναμία ψηφοφορίας Η δημοσκόπηση έχει λήξει - Ποσό Zap Μόνο μία ψήφος ανά χρήστη επιτρέπεται σε αυτόν τον τύπο δημοσκόπησης "Αναζήτηση γεγονότος %1$s" Προσθήκη δημόσιου μηνύματος @@ -295,30 +240,12 @@ Ο παραλήπτης και το κοινό δε γνωρίζουν ποιός έστειλε την πληρωμή Δεν αφήνει ίχνος στο Nostr, παρά μόνο στο Lightning Εξυπηρετητής Αρχείων - LnAddress (διεύθυνση Lightning) ή @Χρήστης - Οι Διαμοιραστές σας (NIP-95) - Τα αρχεία φιλοξενούνται στους Διακομιστές σας (relays). Νέο NIP: ελέγξτε αν το υποστηρίζουν - Ρυθμίσεις Tor/Orbot - Συνδεθείτε μέσω ρυθμίσεων του Orbot - Αποσύνδεση από το Orbot/Tor? - Τα δεδομένα σας θα μεταφερθούν άμεσα στο κανονικό δίκτυο Ναι Όχι - Ακολούθηση Λίστας Όσοι Ακολουθώ Όλοι - ## Σύνδεση μέσω Tor με Orbot - \n\n1. Εγκατάσταση [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Εκκίνηση Orbot - \n3. Στο Orbot, ελέγξτε τη θύρα Socks. Προκαθορισμένος αριθμός θύρας: 9050 - \n4. Αν χρειάζεται αλλάξτε τη θύρα στο Orbot - \n5. Ρυθμίστε τη θύρα Socks σε αυτή την οθόνη - \n6. Πατήστε Ενεργοποίηση για να χρησιμοποιήσετε το Orbot ως διαμεσολαβητή - Θύρα Orbot Μη έγκυρος αριθμός θύρας - Χρήση Orbot - Αποσύνδεση Tor/Orbot Προσωπικά Μηνύματα Σας ειδοποιεί όταν φτάνει ένα ιδιωτικό μήνυμα Ληφθέντα Zaps @@ -327,20 +254,9 @@ για %1$s Ειδοποίηση: - Συμμετοχή στη Συζήτηση - ID Χρήστη ή Ομάδας - npub, nevent ή hex - Δημιουργία - Εγγραφή Σήμερα Προειδοποίηση περιεχομένου Αυτή η ανάρτηση περιέχει ευαίσθητο περιεχόμενο το οποίο μερικοί άνθρωποι μπορεί να βρουν προσβλητικό ή ενοχλητικό - Πάντα απόκρυψη ευαίσθητου περιεχομένου - Πάντα εμφάνιση ευαίσθητου περιεχομένου - Να εμφανίζονται πάντα προειδοποιήσεις περιεχομένου - Συνιστάται: - Φίλτρο spam από αγνώστους - Προειδοποίηση όταν δημοσιεύσεις έχουν αναφορές από αυτούς που ακολουθείτε Νέο εικονίδιο Αντίδρασης Δεν έχουν επιλεγεί εικονίδια αντίδρασης. Πατήστε παρατεταμένα το κουμπί της καρδιάς για αλλαγή Θέτει τον στόχο του ποσού σε sats (υποδιαίρεση του Bitcoin, 1 Bitcoin = 100.000.000 sats) που θέλετε να συγκεντρώσετε για αυτή τη δημοσίευση. Οι Nostr clients που υποστηρίζουν τη λειτουργία zapraiser ίσως δείχνουν μια μπάρα προόδου του στόχου σας ώστε να ενισχύσουν πιθανές δωρεές @@ -348,32 +264,21 @@ Zapraiser στο %1$s. %2$s sats ως την επίτευξη του στόχου Ανάγνωση από Διαμοιραστή (Relay) Γράψτε στον Διαμοιραστή - Παρουσιάστηκε σφάλμα κατά τη λήψη πληροφοριών για τον Διαμοιραστή από %1$s Κάτοχος Έκδοση Λογισμικό Επικοινωνία Υποστηριζόμενα NIPs (Nostr Improvement Proposals) - Κόστος Εγγραφής Διεύθυνση πληρωμής url Περιορισμοί Χώρες Γλώσσες - Ετικέτες Πολιτική δημοσιεύσεων - Μέγεθος μηνύματος - Συνδρομές - Φίλτρα - Μήκος id εγγραφής Ελάχιστο πρόθεμα Μέγιστος αριθμός ετικετών ανά δημοσίευση - Μέγεθος περιεχομένου Ελάχιστη Απόδειξη Έργου (PoW - Proof of Work) - Πιστοποίηση - Πληρωμή Εξαργύρωση Cashu Δεν έχει οριστεί διεύθυνση Lightning - Το token αντιγράφηκε στο πρόχειρο ΖΩΝΤΑΝΑ ΕΚΤΟΣ ΣΥΝΔΕΣΗΣ ΤΕΛΕΙΩΣΕ @@ -395,7 +300,6 @@ (translated) row titles. Marked translatable="false" so protocol terms (blossom, nsec, negentropy, …) stay searchable in every locale and aren't sent to translators. --> Πάντα - Μόνο WiFi Ποτέ Σύστημα Φωτεινό @@ -408,7 +312,6 @@ Προεπισκόπηση URL Κύλιση σε Πλήρη Οθόνη Απόκρυψη μενού κατά την κύλιση - Φόρτωση Εικόνας Ανεπιθύμητοι Χρήστες Σε σίγαση. Κάντε κλικ για κατάργηση σίγασης Ήχος ενεργός. Κάντε κλικ για σίγαση @@ -416,17 +319,10 @@ Η διεύθυνση Nostr επαληθεύτηκε Η διεύθυνση Nostr απέτυχε επαλήθευσης Έλεγχος διεύθυνσης Nostr - Επιλογή/Αποεπιλογή όλων Προεπιλογή - Επιλέξτε Διαμεσολαβητή για να συνεχίσετε - Προώθηση Zaps σε: - Οι clients θα προωθήσουν τα zaps στη διεύθυνση lightning ή στο Προφίλ Χρήστη που φαίνεται παρακάτω αντί για το δικό σας Εμφάνιση τοποθεσίας ως Προσθέτει ένα Geohash (γεωγραφικό στίγμα) της τοποθεσίας σας στη δημοσίευση. Το κοινό θα γνωρίζει ότι βρίσκεστε σε απόσταση 5km (3μίλια) από την τρέχουσα τοποθεσία Προσθέτει μια προειδοποίηση ευαίσθητου περιεχομένου πριν εμφανίσει τη δημοσίευσή σας. Ιδανικό για δημοσίευση με περιεχόμενο NSFW ή περιεχόμενο που κάποια άτομα μπορεί να βρουν προσβλητικό ή ενοχλητικό - Νέα Λειτουργία - Η ενεργοποίηση αυτής της λειτουργίας απαιτεί από το Amethyst να στείλει ένα μήνυμα NIP-17 (GiftWrapped, Sealed Direct και Group Messages). Το NIP-17 είναι νέο και οι περισσότεροι clients δεν το έχουν υιοθετήσει ακόμα. Βεβαιωθείτε ότι ο αποδέκτης χρησιμοποιεί έναν συμβατό client. - Ενεργοποίηση Δημόσια Ιδιωτικό Προς @@ -442,42 +338,24 @@ Αυτόματη φόρτωση εικόνων και GIFs Αυτόματη αναπαραγωγή βίντεο και GIFs Εμφάνιση προεπισκόπησης συνδέσμων - Φόρτωση περιγραφής εικόνας Αντιγραφή διεύθυνσης URL στο πρόχειρο Αντιγραφή ID δημοσίευσης στο πρόχειρο Δημιουργήθηκε στις - Κανόνες Σύνδεση με Amber Ενημέρωση κατάστασης - Σφάλμα ανάλυσης σφάλμα μηνύματος Η ψηφοφορία σε μια δημοσίευση Δημοσκόπησης γίνεται με zaps. Τα zaps είναι μικροπληρωμές σε satoshi (sats). Τα sats είναι υποδιαίρεση του Bitcoin. Κάθε Bitcoin έχει 100.000.000 sats. Η επιλογή με τα περισσότερα zaps (δηλαδή τα περισσότερα sats) είναι η επικρατέστερη. Μπορείτε να ορίσετε ένα ελάχιστο ποσό zap για να αποφύγετε την ψήφο spammers αλλά και ένα μέγιστο ποσό ώστε να αποφύγετε μεγάλους zappers (χρήστες που στέλνουν zaps) που επιθυμούν να χειραγωγήσουν την ψηφοφορία. Χρησιμοποιήστε το ίδιο ποσό και στα δύο πεδία για να βεβαιωθείτε ότι κάθε ψήφος αποτιμάται το ίδιο. Ή αφήστε τα πεδία κενά για να αποδεχτείτε οποιοδήποτε ποσό. Αδυναμία αποστολής zap Μήνυμα στον Χρήστη - Αποτυχία εύρεσης %1$s: %2$s - Αποτυχία εύρεσης %1$s: %2$s - Αποτυχία ανάλυσης αποτελέσματος από %1$s: %2$s - %1$s αποτυχία με κωδικό %2$s - Ενεργό για: - Αρχική σελίδα - Προσωπικά μηνύματα - Συνομιλίες - Όλοι - Αναζήτηση Διαχωρισμός και προώθηση Zaps Οι cients θα διαχωρίσουν και θα προωθήσουν τα zaps στους χρήστες που προστέθηκαν εδώ αντί για εσάς Αναζήτηση και Προσθήκη Χρήστη Όνομα Χρήστη ή εμφανιζόμενο όνομα Λείπει η ρύθμιση lightning (LN) Ο Χρήστης %1$s δεν έχει ορίσει διεύθυνση LN (lightning) για να λαμβάνει sats - Ποσοστό - Διαχωρισμός zaps με - Προώθηση zaps σε - Δε βρέθηκαν πορτοφόλια Lightning Πληρώθηκε Πορτοφόλι %1$s Σφάλμα ανοίγματος εφαρμογής υπογραφής - Υπογραφή αιτήματος απορρίφθηκε Δε βρέθηκαν πορτοφόλια για να πληρώσετε το τιμολόγιο Lightning (Error: %1$s). Παρακαλώ εγκαταστήστε ένα πορτοφόλι Lightning για να χρησιμοποιήσετε τα zaps Δε βρέθηκε ψηφιακό πορτοφόλι για πληρωμή Lightning. Παρακαλώ εγκαταστήστε ένα πορτοφόλι Lightning για να χρησιμοποιήσετε τα zaps Κρυφές Λέξεις @@ -487,28 +365,15 @@ Διαλέξτε μια επιλογή Αδυναμία πληρωμής τιμολογίου Αδυναμία ανάληψης - Δεν ήταν δυνατή η εγκατάσταση του Wallet Connect - Σφάλμα ανάλυσης NIP-47. Ελέγξτε αν αυτό είναι σωστό με τον πάροχο του πορτοφολιού σας: %1$s. Σφάλμα: %2$s - Σφάλμα ανάλυσης NIP-47. Ελέγξτε αν αυτό είναι σωστό με τον πάροχο του πορτοφολιού σας: %1$s. Αδυναμία εξαργύρωσης Cashu Το Mint έδωσε το ακόλουθο μήνυμα σφάλματος: %1$s - Τα Cashu tokens έχουν ήδη δαπανηθεί. Ληφθέντα Cashu %1$s sats στάλθηκαν στο πορτοφόλι σας. (Κρατήσεις: %2$s sats) Αδυναμία ανάκτησης τιμολογίου από τους διακομιστές του παραλήπτη Ο πάροχος σύνδεσης του πορτοφολιού σας επέστρεψε το ακόλουθο σφάλμα: %1$s - Αδυναμία σύνδεσης στο Tor - Αδυναμία λήψης εγγράφου από τον Διαμεσολαβητή (relay) Δεν ήταν δυνατή η δημιουργία του LNUrl από τη διεύθυνση Lightning \"%1$s\". Ελέγξτε ρυθμίσεις χρήστη - Η υπηρεσία Lightning του αποδέκτη στο %1$s δεν είναι διαθέσιμη. Υπολογίστηκε από τη διεύθυνση Lightning \"%2$s\". Σφάλμα: %3$s. Ελέγξτε αν ο διακομιστής λειτουργεί και αν η διεύθυνση Lightning είναι σωστή - Αδυναμία επίλυσης %1$s. Ελέγξτε αν είστε συνδεδεμένοι, αν ο διακομιστής λειτουργεί και αν η διεύθυνση Lightning %2$s είναι σωστή - Αδυναμία λήψης τιμολογίου από %1$s - Σφάλμα Ανάλυσης JSON από τη διεύθυνση Lightning. Ελέγξτε τις ρυθμίσεις Lightning του χρήστη - Ο σύνδεσμος URL στις ρυθμίσεις διακομιστή της διεύθυνσης Lightning του Χρήστη, δε βρέθηκε - Σφάλμα Ανάλυσης JSON από τη διεύθυνση ανάκτησης τιμολογίου Lightning. Ελέγξτε τις ρυθμίσεις Lightning του χρήστη Λανθασμένο ποσό πληρωμής (%1$s sats) από %2$s. Θα έπρεπε να είναι %3$s Αδυναμία δημιουργίας πληρωμής Lightning πριν την αποστολή του zap. Το πορτοφόλι Lightning του δέκτη έστειλε το ακόλουθο σφάλμα: %1$s - Αδυναμία δημιουργίας πληρωμής Lightning πριν την αποστολή του zap. Το στοιχείο pr δε βρέθηκε στο JSON. Χρήστης μόνο για ανάγνωση Καμία ρύθμιση αντιδράσεων Επιλέξτε μια εφαρμογή UnifiedPush @@ -533,4 +398,6 @@ + + Η υπηρεσία Lightning του αποδέκτη στο %1$s δεν είναι διαθέσιμη. Υπολογίστηκε από τη διεύθυνση Lightning \"%2$s\". Σφάλμα: %3$s. Ελέγξτε αν ο διακομιστής λειτουργεί και αν η διεύθυνση Lightning είναι σωστή diff --git a/amethyst/src/main/res/values-en-rGB/strings.xml b/amethyst/src/main/res/values-en-rGB/strings.xml index 1c31a607e6..b20c782ccd 100644 --- a/amethyst/src/main/res/values-en-rGB/strings.xml +++ b/amethyst/src/main/res/values-en-rGB/strings.xml @@ -26,4 +26,5 @@ + diff --git a/amethyst/src/main/res/values-eo-rUY/strings.xml b/amethyst/src/main/res/values-eo-rUY/strings.xml index d0e8756d1d..8ff3a40f8e 100644 --- a/amethyst/src/main/res/values-eo-rUY/strings.xml +++ b/amethyst/src/main/res/values-eo-rUY/strings.xml @@ -15,8 +15,6 @@ Spamo Personigo Kontraŭleĝa Konduto - Nekonata - Plusendila Ikono Nekonata Aŭtoro Kopii Tekston Kopii ID de Aŭtoro @@ -27,7 +25,6 @@ Raporti Spamon / Friponon Raporti Personigon - Raporti Eksplicitan Enhavon Raporti Kontraŭleĝan Konduton Ensaluti per sekreta ŝlosilo por respondi Ensaluti per sekreta ŝlosilo por impulsi afiŝojn @@ -37,7 +34,6 @@ Ensalutu per sekreta ŝlosilo por sekvi Ensalutu per sekreta ŝlosilo por malsekvi Zapoj - Nombro da Vidoj Plifortigi impulsita Citi @@ -45,9 +41,7 @@ Aldoni "respondante al " " kaj " - "en kanalo " Profila Murpapero - Sukcesa Pago Eraro analizante de erara mesaĝo " Sekvanti" " Sekvantoj" @@ -62,9 +56,7 @@ Dankegon! Kvanto en Satoj Sendi Satojn - "Eraro anazilante antaŭrigardon de %1$s : %2$s" "Antaŭrigardi Bildon de %1$s" - Nova Kanalo Kanala Nomo Mia Mojosa Grupo Bilda URL @@ -75,35 +67,20 @@ Konservi Krei Nuligi - Malsukcesis alŝuti la bildon - Plusendilo Adreso - Afiŝoj - Bajtoj Eraroj - Hejma Fluo - Fluo de Privata Mesaĝoj - Fluo de Publikaj Babiloj - Tutmonda Fluo - Serĉi Fluon Aldoni Plusendilon Montra Nomo Mia montra nomo Uzantnomo - Mia uzantnomo Pri mi URL de Avataro URL de Murpapero URL de Retejo - LN Adreso - LN URL (malmoderna) Bildo konservita al la galerio Malsukcesis konservi la bildon Alŝuti Bildon - Alŝutante… Uzanto ne havas lightning-adreson por ricevi satojn "respondi ĉi tie.…" - Kopias la ID de Noto al la tondujo por kunhavigi - Kopii ID de Kanalo (Noto) al la tondujo Redaktas la Metadatumojn de Kanalo Aliĝi Konataj @@ -113,16 +90,12 @@ Konversacioj Notoj Respondoj - "Sekvitaj" "Raportoj" Pli da Opcioj " Plusendiloj" Retejo Lightning-Adreso Kopii la Nsec ID (vian pasvorton) al la tondujo por sekurkopio - Kopii sekretan ŝlosilon al la tondujo - Kopii publikan ŝlosilon al la tondujo por kunhavigi - Kopii publikan ŝlosilon (NPub) al la tondujo Sendi rektan mesaĝon Redakti metadatumojn de uzanto Sekvi @@ -142,7 +115,6 @@ Konsento al kondiĉoj estas nepra Ŝlosilo estas nepra Ensaluti - Generi novan ŝlosilon Ŝargante fluon @@ -150,12 +122,6 @@ Provi denove Fluo estas malplena. Renovigi - kreita - kun priskribo de - kaj bildo - ŝanĝigis babilejo-nomon al - priskribon al - kaj bildon al Eliri Malsekvi Kanalo kreita @@ -177,7 +143,6 @@ Blasfemo / Malama Parolado Raporti Malaman paroladon Raporti Nudecon / Pornon - aliajn Marki ĉiujn Konatajn legitaj Marki ĉiujn Novajn legitaj Marki ĉiujn legitajn @@ -185,23 +150,18 @@ Sekreta ŝlosilo (nsec) kopiita al tondujo Kopii mian sekretan ŝlosilon Aŭtentikigo malsukcesis - Eraro - "Kreita per %1$s" "Ŝildeto-premia bildo por %1$s" Vi ricevis novan ŝildeto-premion Ŝildeto-premio doniĝita al Kopiita tekston de noto al tondujo Kopiita @npub de aŭtoro al tondujo Kopiita ID de noto (@note1) al tondujo - Elekti Tekston "<Privata mesaĝo nemalĉifrebla.>\n\nVi estis citita en privata konversacio inter %1$s kaj %2$s." Aldoni Novan Konton Kontoj Elekti Konton Aldoni Novan Konton Aktiva konto - Havas sekretan ŝlosilon - Nur legebla, neniu sekreta ŝlosilo Malantaŭen Elekti Kunhavigi Ligilon @@ -218,7 +178,6 @@ Forigi Bloki Denunci - Forigi Ne montru denove Spamo aŭ trompoj Obscena aŭ malŝata konduto @@ -243,28 +202,13 @@ Aldoni al Publikaj Legosignoj Forigi el Privataj Legosignoj Forigi el Publikaj Legosignoj - Servico de Monujo-Konektado - Permesas Nostr-Sekreton por pagi zapojn sen eliri la apon. Konservi la sekreton sekura kaj uzu privatan plusendilon laŭeble - Pubŝlosilo de Wallet Connect - Plusendilo de Wallet Connect - Sekreto de Wallet Connect - Montri sekretan ŝlosilon - nsec / heks privata ŝlosilo Promesi Kvanton en Satoj - Afiŝi Enketon - Necesaj kampoj: - Zapi ricevantojn - Ĉefa priskribo de enketo… Elekto %s Priskribo de elekto de enketo - Nedevigaj kampoj: Minimumo de Zapoj Maksimumo de Zapoj Interkonsento (0–100)% - Fermi post - tagoj - Kvanto de zapoj Nur po unu voĉdono por uzanto estas permesita en ĉi tia enketo "Serĉanta Eventon %1$s" Aldoni publikan mesaĝon @@ -292,30 +236,12 @@ Ne-Zapo Ne spuro en Nostr, nur en Lightning Dosiera Servilo - LNAdreson aŭ @Uzanto - Viaj plusendiloj (NIP-95) - Dosieroj estas konservita de viaj plusendiloj. Nova NIP: kontrolu se ili subtenas - Tor/Orbot aranĝo - Konekti tra via Orbot aranĝo - Malkonekti el via Orbot/Tor? - Viaj datumoj estos tuj sendita en la normala reto Jes Ne - Listo de Sekvoj Ĉiuj Sekvoj Ĝenerala - ## Konektu tra Tor per Orbot - \n\n1. Instalu [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Aktivigu Orbot - \n3. En Orbot, kontrolu la Socks konektejon. Defaulte uzas 9050 - \n4. Se necesa, ŝanĝu la konektejon en Orbot - \n5. Agordu la Socks konektejon en ĉi tiu ekrano - \n6. Alkliki la Aktivigi butonon por uzi Orbot kiel prokuro - Socks-Konektejo de Orbot Nevalida nombro de konektejo - Uzi Orbot - Malkonekti Tor/Orbot Privataj Mesaĝoj Sciigas vin kiam privata mesaĝo alvenas Zapojn Ricevitaj @@ -325,20 +251,9 @@ pro %1$s Sciigi: - Aliĝu al la Konversacio - ID de Uzanto aŭ Grupo - npub, nevent aŭ hex - Krei - Aliĝi Hodiaŭ Enhava averto Ĉi tiu afiŝo enhavas delikatan enhavon, kiu povas ofendi aŭ ĝeni iujn - Ĉiam kaŝi delikatajn enhavojn - Ĉiam montri delikatajn enhavojn - Ĉiam montri enhavajn avertojn - Rekomendas: - Filtri spamon el fremduloj - Averti kiam afiŝoj havas denuncojn de viaj sekvituloj Nova Reaga Simbolo Neniaj reagoj selektitaj. Premu longe por ŝanĝi Zapkolekto @@ -347,32 +262,22 @@ Zapkolekto je %1$s. %2$s satoj al celo Legi el plusendilo Skribi al Plusendilo - Eraro okazis akirante de plusendila informacio el %1$s Posedanto Versio Programaro Kontakto Subtenitaj NIPoj - Enirpago URL de pagoj Limoj Landoj Lingvoj - Etikedoj Reguloj de Afiŝado - Longo de Mesaĝo - Abonoj - Filtriloj - Longo de ID de Abono Minimuma prefikso Maksimumaj etikedoj de evento - Longo de enhavo Minimuma PoW - Pago Cashu Signo Elpagi Neniu Lightning-Adreso agordita - Signo kopita al tondujo VIVE SENRETA FINITA @@ -394,7 +299,6 @@ (translated) row titles. Marked translatable="false" so protocol terms (blossom, nsec, negentropy, …) stay searchable in every locale and aren't sent to translators. --> Ĉiam - Nur-Wifi Neniam Sistemo Hela @@ -405,7 +309,6 @@ Antaŭrigardo de Bildo Ludado de Video Antaŭrigardo de URL - Montri bildon Spamistoj Silentigita. Alklaki por malsilentigi Ŝalta sono. Alklaki por silentigi @@ -413,17 +316,10 @@ Nostr-adreso konfirmita Nostr-adreso malsukcesis konfirmon Kontrolanta de Nostr-adreso - Selekti/Malselekti ĉion Defaŭlta - Elekti plusendilon por daŭrigi - Plusendi Zapojn al: - Subtenantaj klientoj plusendos zapojn al la ĉi-suba LNAdreso aŭ Uzantprofilo anstataŭ al la via Montri Loko kiel Aldonas Geohash de via loko al la afiŝo. La aŭdienco scios kiam vi estas je 5km (3mi) de la nuna loko Aldonas averton de delikata enhavo antaŭ ol montri vian enhavon. Ĉi tiu estas perfekta por NSFW enhavo aŭ enhavo kiun iu povas trovi ofensiva aŭ ĝena - Nova Trajto - Por aktivigi ĉi tiun reĝimon Amethyst devus sendi NIP-17 mesaĝon (GiftWrapped, Sealed Direct kaj Grupa Mesaĝojn). NIP-17 estas nova kaj la plejparto de klientoj ankoraŭ ne instalis ĝin. Konfirmu ke la ricevanto uzas kongruan klienton. - Aktivigi Publika Privata Al @@ -438,13 +334,10 @@ Aŭtomate montri imaĝojn kaj GIFojn Aŭtomate montri videojn kaj GIFojn Montri antaŭrigardoj de URL - Kiam montri imaĝojn Kopii URL al tondujo Kopi ID de Noto al tondujo Kreita en - Reguloj Ĝistadigi vian staton - Eraro analizante de erara mesaĝo Voĉdonoj pezas laŭ la zap-kvanto. Vi povas difini minimuman kvanton por eviti spamistojn kaj maksimuman kvanton por eviti ke grandaj zapistoj ekregu la enketon. Uzu la saman kvanton en ambaŭ kampoj por certigi ke ĉiuj voĉdonoj pezus same. Malplenigu ĝin por akcepti ajnan kvanton. Nekapable sendi zapon Mesaĝi la Uzanto @@ -461,4 +354,5 @@ + diff --git a/amethyst/src/main/res/values-eo/strings.xml b/amethyst/src/main/res/values-eo/strings.xml index eed86b9974..dacc20870e 100644 --- a/amethyst/src/main/res/values-eo/strings.xml +++ b/amethyst/src/main/res/values-eo/strings.xml @@ -15,8 +15,6 @@ Spamo Personigo Kontraŭleĝa Konduto - Nekonata - Plusendila Ikono Nekonata Aŭtoro Kopii Tekston Kopii ID de Aŭtoro @@ -27,7 +25,6 @@ Raporti Spamon / Friponon Raporti Personigon - Raporti Eksplicitan Enhavon Raporti Kontraŭleĝan Konduton Ensaluti per sekreta ŝlosilo por respondi Ensaluti per sekreta ŝlosilo por impulsi afiŝojn @@ -37,7 +34,6 @@ Ensalutu per sekreta ŝlosilo por sekvi Ensalutu per sekreta ŝlosilo por malsekvi Zapoj - Nombro da Vidoj Plifortigi impulsita Citi @@ -45,9 +41,7 @@ Aldoni "respondante al " " kaj " - "en kanalo " Profila Murpapero - Sukcesa Pago Eraro analizante de erara mesaĝo " Sekvanti" " Sekvantoj" @@ -62,9 +56,7 @@ Dankegon! Kvanto en Satoj Sendi Satojn - "Eraro anazilante antaŭrigardon de %1$s : %2$s" "Antaŭrigardi Bildon de %1$s" - Nova Kanalo Kanala Nomo Mia Mojosa Grupo Bilda URL @@ -75,35 +67,20 @@ Konservi Krei Nuligi - Malsukcesis alŝuti la bildon - Plusendilo Adreso - Afiŝoj - Bajtoj Eraroj - Hejma Fluo - Fluo de Privata Mesaĝoj - Fluo de Publikaj Babiloj - Tutmonda Fluo - Serĉi Fluon Aldoni Plusendilon Montra Nomo Mia montra nomo Uzantnomo - Mia uzantnomo Pri mi URL de Avataro URL de Murpapero URL de Retejo - LN Adreso - LN URL (malmoderna) Bildo konservita al la galerio Malsukcesis konservi la bildon Alŝuti Bildon - Alŝutante… Uzanto ne havas lightning-adreson por ricevi satojn "respondi ĉi tie… " - Kopias la ID de Noto al la tondujo por kunhavigi - Kopii ID de Kanalo (Noto) al la tondujo Redaktas la Metadatumojn de Kanalo Aliĝi Konataj @@ -113,16 +90,12 @@ Konversacioj Notoj Respondoj - "Sekvitaj" "Raportoj" Pli da Opcioj " Plusendiloj" Retejo Lightning-Adreso Kopii la Nsec ID (vian pasvorton) al la tondujo por sekurkopio - Kopii sekretan ŝlosilon al la tondujo - Kopii publikan ŝlosilon al la tondujo por kunhavigi - Kopii publikan ŝlosilon (NPub) al la tondujo Sendi rektan mesaĝon Redakti metadatumojn de uzanto Sekvi @@ -142,18 +115,11 @@ Konsento al kondiĉoj estas nepra Ŝlosilo estas nepra Ensaluti - Generi novan ŝlosilon Ŝargante fluon "Eraro ŝargante respondojn: " Provi denove Fluo estas malplena. Renovigi - kreita - kun priskribo de - kaj bildo - ŝanĝigis babilejo-nomon al - priskribon al - kaj bildon al Eliri Malsekvi Kanalo kreita @@ -175,7 +141,6 @@ Blasfemo / Malama Parolado Raporti Malaman paroladon Raporti Nudecon / Pornon - aliajn Marki ĉiujn Konatajn legitaj Marki ĉiujn Novajn legitaj Marki ĉiujn legitajn @@ -183,23 +148,18 @@ Sekreta ŝlosilo (nsec) kopiita al tondujo Kopii mian sekretan ŝlosilon Aŭtentikigo malsukcesis - Eraro - "Kreita per %1$s" "Ŝildeto-premia bildo por %1$s" Vi ricevis novan ŝildeto-premion Ŝildeto-premio doniĝita al Kopiita tekston de noto al tondujo Kopiita @npub de aŭtoro al tondujo Kopiita ID de noto (@note1) al tondujo - Elekti Tekston "<Privata mesaĝo nemalĉifrebla.>\n\nVi estis citita en privata konversacio inter %1$s kaj %2$s." Aldoni Novan Konton Kontoj Elekti Konton Aldoni Novan Konton Aktiva konto - Havas sekretan ŝlosilon - Nur legebla, neniu sekreta ŝlosilo Malantaŭen Elekti Kunhavigi Ligilon @@ -216,7 +176,6 @@ Forigi Bloki Denunci - Forigi Ne montru denove Spamo aŭ trompoj Obscena aŭ malŝata konduto @@ -241,28 +200,13 @@ Aldoni al Publikaj Legosignoj Forigi el Privataj Legosignoj Forigi el Publikaj Legosignoj - Servico de Monujo-Konektado - Permesas Nostr-Sekreton por pagi zapojn sen eliri la apon. Konservi la sekreton sekura kaj uzu privatan plusendilon laŭeble - Pubŝlosilo de Wallet Connect - Plusendilo de Wallet Connect - Sekreto de Wallet Connect - Montri sekretan ŝlosilon - nsec / heks privata ŝlosilo Promesi Kvanton en Satoj - Afiŝi Enketon - Necesaj kampoj: - Zapi ricevantojn - Ĉefa priskribo de enketo… Elekto %s Priskribo de elekto de enketo - Nedevigaj kampoj: Minimumo de Zapoj Maksimumo de Zapoj Interkonsento (0–100)% - Fermi post - tagoj - Kvanto de zapoj Nur po unu voĉdono por uzanto estas permesita en ĉi tia enketo "Serĉanta Eventon %1$s" Aldoni publikan mesaĝon @@ -290,30 +234,12 @@ Ne-Zapo Ne spuro en Nostr, nur en Lightning Dosiera Servilo - LNAdreson aŭ @Uzanto - Viaj plusendiloj (NIP-95) - Dosieroj estas konservita de viaj plusendiloj. Nova NIP: kontrolu se ili subtenas - Tor/Orbot aranĝo - Konekti tra via Orbot aranĝo - Malkonekti el via Orbot/Tor? - Viaj datumoj estos tuj sendita en la normala reto Jes Ne - Listo de Sekvoj Ĉiuj Sekvoj Ĝenerala - ## Konektu tra Tor per Orbot - \n\n1. Instalu [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Aktivigu Orbot - \n3. En Orbot, kontrolu la Socks konektejon. Defaulte uzas 9050 - \n4. Se necesa, ŝanĝu la konektejon en Orbot - \n5. Agordu la Socks konektejon en ĉi tiu ekrano - \n6. Alkliki la Aktivigi butonon por uzi Orbot kiel prokuro - Socks-Konektejo de Orbot Nevalida nombro de konektejo - Uzi Orbot - Malkonekti Tor/Orbot Privataj Mesaĝoj Sciigas vin kiam privata mesaĝo alvenas Zapojn Ricevitaj @@ -322,20 +248,9 @@ El %1$s pro %1$s Sciigi: - Aliĝu al la Konversacio - ID de Uzanto aŭ Grupo - npub, nevent aŭ hex - Krei - Aliĝi Hodiaŭ Enhava averto Ĉi tiu afiŝo enhavas delikatan enhavon, kiu povas ofendi aŭ ĝeni iujn - Ĉiam kaŝi delikatajn enhavojn - Ĉiam montri delikatajn enhavojn - Ĉiam montri enhavajn avertojn - Rekomendas: - Filtri spamon el fremduloj - Averti kiam afiŝoj havas denuncojn de viaj sekvituloj Nova Reaga Simbolo Neniaj reagoj selektitaj. Premu longe por ŝanĝi Zapkolekto @@ -344,32 +259,22 @@ Zapkolekto je %1$s. %2$s satoj al celo Legi el plusendilo Skribi al Plusendilo - Eraro okazis akirante de plusendila informacio el %1$s Posedanto Versio Programaro Kontakto Subtenitaj NIPoj - Enirpago URL de pagoj Limoj Landoj Lingvoj - Etikedoj Reguloj de Afiŝado - Longo de Mesaĝo - Abonoj - Filtriloj - Longo de ID de Abono Minimuma prefikso Maksimumaj etikedoj de evento - Longo de enhavo Minimuma PoW - Pago Cashu Signo Elpagi Neniu Lightning-Adreso agordita - Signo kopita al tondujo VIVE SENRETA FINITA @@ -387,7 +292,6 @@ Aldonas averton de delikata enhavo antaŭ montri ĉi tiun enhavon Agordoj Ĉiam - Nur-Wifi Neniam Sistemo Hela @@ -398,7 +302,6 @@ Antaŭrigardo de Bildo Ludado de Video Antaŭrigardo de URL - Montri bildon Spamistoj Silentigita. Alklaki por malsilentigi Ŝalta sono. Alklaki por silentigi @@ -406,17 +309,10 @@ Nostr-adreso konfirmita Nostr-adreso malsukcesis konfirmon Kontrolanta de Nostr-adreso - Selekti/Malselekti ĉion Defaŭlta - Elekti plusendilon por daŭrigi - Plusendi Zapojn al: - Subtenantaj klientoj plusendos zapojn al la ĉi-suba LNAdreso aŭ Uzantprofilo anstataŭ al la via Montri Loko kiel Aldonas Geohash de via loko al la afiŝo. La aŭdienco scios kiam vi estas je 5km (3mi) de la nuna loko Aldonas averton de delikata enhavo antaŭ ol montri vian enhavon. Ĉi tiu estas perfekta por NSFW enhavo aŭ enhavo kiun iu povas trovi ofensiva aŭ ĝena - Nova Trajto - Por aktivigi ĉi tiun reĝimon Amethyst devus sendi NIP-17 mesaĝon (GiftWrapped, Sealed Direct kaj Grupa Mesaĝojn). NIP-17 estas nova kaj la plejparto de klientoj ankoraŭ ne instalis ĝin. Konfirmu ke la ricevanto uzas kongruan klienton. - Aktivigi Publika Privata Al @@ -431,13 +327,10 @@ Aŭtomate montri imaĝojn kaj GIFojn Aŭtomate montri videojn kaj GIFojn Montri antaŭrigardoj de URL - Kiam montri imaĝojn Kopii URL al tondujo Kopi ID de Noto al tondujo Kreita en - Reguloj Ĝistadigi vian staton - Eraro analizante de erara mesaĝo Voĉdonoj pezas laŭ la zap-kvanto. Vi povas difini minimuman kvanton por eviti spamistojn kaj maksimuman kvanton por eviti ke grandaj zapistoj ekregu la enketon. Uzu la saman kvanton en ambaŭ kampoj por certigi ke ĉiuj voĉdonoj pezus same. Malplenigu ĝin por akcepti ajnan kvanton. Nekapable sendi zapon Mesaĝi la Uzanto diff --git a/amethyst/src/main/res/values-es-rES/strings.xml b/amethyst/src/main/res/values-es-rES/strings.xml index 916aa2a0d6..7eccf944f9 100644 --- a/amethyst/src/main/res/values-es-rES/strings.xml +++ b/amethyst/src/main/res/values-es-rES/strings.xml @@ -32,8 +32,6 @@ Otro Acoso Violencia - Desconocido - Icono del transmisor Autor desconocido Copiar texto Copiar PubKey del usuario @@ -48,12 +46,9 @@ Reportar Spam / Estafa Reportar suplantación de identidad - Reportar contenido explícito Reportar comportamiento ilegal Reportar malware - Reportar mod Malware - Mod Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder responder Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder impulsar publicaciones. Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para indicar que te gustan las publicaciones. @@ -67,17 +62,14 @@ Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder dejar de seguir a otros usuarios. Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder ocultar una palabra o frase. Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder mostrar una palabra o frase. - Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder cambiar la configuración. Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder subir contenido. Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder firmar eventos. Descifrado no autorizado El firmante no autorizó un descifrado necesario para realizar esta operación. Activa el descifrado NIP-44 en tu aplicación de firmante e inténtalo de nuevo No se ha encontrado el firmante. ¿Se ha desinstalado la app del firmante? Comprueba si el firmante está instalado y tiene esta cuenta. Cierra sesión y vuelve a iniciar sesión en la app del firmante si ha cambiado. - Fallo en el comportamiento del firmante El firmante externo devolvió una carga útil que no concuerda con la solicitud. Es posible que haya un error, ya sea en Amethyst o en el firmante. Zaps - Total de visualizaciones Impulsar Impulsada editada @@ -90,9 +82,7 @@ Añadir "respondiendo a " " y " - "en el canal " Banner de perfil - El pago se ha realizado correctamente Error al analizar el mensaje de error " Siguiendo" " Seguidores" @@ -165,7 +155,6 @@ No hay suficiente saldo en una moneda que acepte este destinatario. Recarga tu billetera de Cashu primero. Disponible para este destinatario: %1$s sats Comisión de red - tu app de billetera Transacción: %1$s Donación Lightning Nota al receptor @@ -179,16 +168,13 @@ Prefijo visible 😎 Agregar a publicación - "Error al analizar la vista previa de %1$s : %2$s" "Imagen de vista previa para %1$s" Artículo - Nuevo canal Nombre del canal Mi grupo genial URL de imagen Url de imagen (opcional) Descripción - No se ha encontrado la descripción "Sobre nosotros…" ¿Qué tienes en mente? Escribir un mensaje… @@ -198,42 +184,25 @@ Crear Cambiar nombre Cancelar - No se pudo cargar la imagen - Dirección del relé - Publicaciones - Bytes Error Errores Porcentaje de conexiones exitosas al relé - El número de errores de conexión en esta sesión - Tus noticias - Fuente de mensajes privados - Fuente de chat público - Fuente global - Fuente de búsqueda Buscar y añadir usuario - Añadir un usuario Añadir transmisor - Nombre - Nombre (para @etiquetar) Mi nombre de @etiqueta Nombre para mostrar Mi nombre para mostrar Avestruz Maravillosa ¡Te damos la bienvenida, Avestruz! Nombre de usuario - Mi nombre de usuario Sobre mí URL del avatar URL del banner Dirección web Pronombres - Dirección LN - Dirección LN (antigua) Los relés de origen pueden ser obsoletos Aviso de relé obsoleto Guardar en el teléfono - Guardar en la galería Imagen guardada en la galería La descarga del vídeo ha comenzado… La descarga del contenido multimedia ha comenzado… @@ -250,15 +219,12 @@ Hacer una foto Grabar un video Grabar un mensaje - Grabar un mensaje Haz clic y mantén pulsado para grabar un mensaje Volver a grabar Grabación Grabando %1$s - Cargando… Error de carga Error al cargar el mensaje de voz - Estado inesperado de carga NIP-95 aún no es compatible con mensajes de voz Error al cargar voz: %1$s Ninguna @@ -270,8 +236,6 @@ El usuario no tiene una configuración de dirección Lightning para recibir sats "responde aquí… " En este chat - Copia el ID de la nota al portapapeles para compartirla en Nostr - Copiar el ID del canal (nota) al portapapeles Edita los metadatos del canal Unirse Conocidos @@ -285,7 +249,6 @@ Respuestas Tuyo Galería - "Siguiendo" "Reportes" "%1$s informes" Más opciones @@ -293,11 +256,8 @@ Sitio web Dirección Lightning Copia el ID Nsec (tu contraseña) en el portapapeles para hacer una copia de seguridad - Copiar clave privada al portapapeles Mostrar código QR de clave privada Mostrar código QR de clave privada cifrada - Copia la clave pública al portapapeles para compartir - Copiar la clave pública (NPub) al portapapeles Enviar un mensaje directo Edita los metadatos del usuario Seguir @@ -326,8 +286,6 @@ ¿Cómo debemos llamarte? ¿No tienes una cuenta de Nostr? ¿Ya tienes una cuenta de Nostr? - Crear una cuenta nueva - Generar una nueva clave Cargando el tablón… Cargando cuenta encriptado @@ -343,13 +301,7 @@ Encuesta abierta Tablón vacío Actualizar - Creado - con descripción de - y foto - cambió el nombre del chat a Nuevo perfil de chat: - descripción a - e imagen a Salir Dejar de seguir Canal creado @@ -386,7 +338,6 @@ Dirección de Nostr nunca ahora - segundos h m d @@ -394,7 +345,6 @@ Blasfemias / Discurso de odio Denuncia discurso de odio Reportar desnudos / Porno - otros Marcar los conocidos como leídos Marcar los nuevos como leídos Marcar todos como leídos @@ -415,8 +365,6 @@ Autenticación fallida El sistema biométrico no pudo autenticar al propietario de este teléfono El sistema biométrico no pudo autenticar al propietario de este teléfono. Error: %1$s - Error - "Credo por %1$s" "Imagen del Badge para %1$s" \"Imagen de premio de insignia Has recibido un nuevo Badge @@ -424,7 +372,6 @@ Texto de nota copiado al portapapeles \@npub del autor copiado al portapapeles ID de nota copiada (@note1) al portapapeles - Seleccionar texto "<Unable to decrypt private message>\n\nTe citaron en una conversación privada o encriptada entre %1$s y %2$s." Agregar cuenta nueva Cuentas @@ -436,8 +383,6 @@ Seleccionar cuenta Agregar cuenta nueva Cuenta activa - Tiene clave privada - Solo de lectura, sin clave privada Volver Seleccionar Compartir enlace del navegador @@ -458,14 +403,12 @@ Silenciar hilo Reactivar hilo Reportar - Eliminar No mostrar de nuevo Spam o estafas Groserías o conducta que incita al odio Suplantación de identidad malintencionada Desnudos o contenido gráfico Comportamiento ilegal - Malware Si bloqueas a un usuario, se ocultará su contenido en tu app. Tus notas todavía son visibles públicamente, incluso para las personas que bloquees. Los usuarios bloqueados aparecen en la pantalla \"Filtros de seguridad\". Reportar abuso @@ -493,7 +436,6 @@ Elegir hora programada Programación para… Se publica en %1$s - Se venció hace %1$s Hora Programar publicación Cancelar programación @@ -568,7 +510,6 @@ Autor Solicitudes Aprobaciones - Ninguna comunidad coincide con este filtro. Reglas verificables (opcional) Publica un documento de reglas legibles automáticamente (NIP-9B) junto con la comunidad. Los clientes que lo admiten bloquean las publicaciones que no coinciden antes de enviarlas. Guardar límites @@ -633,7 +574,6 @@ Transmitir en vivo… Transmisión fallida: %1$s Error al silenciar: %1$s - Se requiere acceso al micrófono para hablar en esta sala. Sin permisos Nests Mantiene la reproducción de audio mientras una sala está abierta. @@ -644,7 +584,6 @@ Unirse a nest Anfitrión Abrir - Chat reciente Nadie se encuentra en la sala en este momento. %1$d escuchando Anfitrión @@ -672,8 +611,6 @@ Público Manos Todavía no hay nadie en el público. - Enviar - Di algo… Aún no hay mensajes. Sé el primero en chatear. Reaccionar Editar sala @@ -690,7 +627,6 @@ Elige en qué servidores host de MoQ quieres que Amethyst publique tus nests. La primera entrada es predeterminada cuando creas un nuevo espacio. Tus servidores Guardado como un evento reemplazable para que otros clientes puedan leer tus preferencias. - Agregar un servidor de nest URL del relé (WebTransport) URL de autenticación (generación de JWT) Agregar @@ -712,9 +648,6 @@ Eliminar lista de marcadores Ver publicaciones Ver artículos - Ver enlaces - Ver hashtags - Aún no tienes ninguna lista de marcadores. Pulsa el nuevo botón de abajo para crear una. Publicaciones privadas Publicaciones privadas(%1$s) Publicaciones públicas @@ -725,16 +658,6 @@ Los metadatos de las listas de marcadores son visibles para cualquier usuario de Nostr. Solo los miembros privados están cifrados. Mover a público Mover a privado - Servicio de conexión a monedero - Autoriza a un secreto de Nostr para pagar zaps sin salir de la app. Mantén el secreto seguro y usa un relé privado si es posible. - Clave pública de conexión a monedero - Relé de conexión a monedero - Secreto de conexión a monedero - Clave secreta de conexión a monedero - clave privada nsec / hex - Conectada - No conectada - Avanzado: introduce manualmente los detalles de la conexión Cantidad de zap rápido Aparece al presionar el botón de zap. Pulsa una cantidad para eliminarla. Si la dejas vacía, se abrirá el cuadro de diálogo para introducir una cantidad cada vez. Privacidad de zaps @@ -742,14 +665,8 @@ Conectar cartera Ver fuente de relés Destinar cantidad en sats - Publicar encuesta - Campos obligatorios: - Destinatarios de zaps - Descripción de encuesta principal… - Opción Opción %s Descripción de opción de encuesta - Campos opcionales: Zap mínimo Zap máximo Consenso @@ -758,11 +675,8 @@ Opción múltiple Fecha y hora de cierre de la encuesta La encuesta se cierra en %1$s - Cerrar después de - días No se puede votar Encuesta cerrada para votos nuevos - Monto del zap Solo se permite un voto por usuario en este tipo de encuesta "Buscando evento %1$s" Enviar zap @@ -796,17 +710,12 @@ No zap No hay rastro en Nostr, solo en Lightning Anónimo - Publicar como una nueva identidad temporal. Tu cuenta no quedará vinculada a esta respuesta. - Esta respuesta se publicará desde una nueva identidad anónima Servidor de archivos Elegir un servidor para cargar este archivo - Dirección o @usuario de Lightning Servidores multimedia Configura tus servidores preferidos para subir contenido multimedia. - No tienes ningún servidor NIP-96 configurado. Puedes utilizar la lista de Amethyst o añadir uno de la lista a continuación ↓ No tienes ningún servidor Blossom configurado. Puedes utilizar la lista de Amethyst o añadir uno de la lista a continuación ↓ Servidores multimedia recomendados - Servidores multimedia integrados Lista predeterminada de Amethyst. Puedes agregarlos individualmente o añadir la lista. Usar lista predeterminada Agregar servidor multimedia @@ -823,51 +732,22 @@ Cifrando Listo Error - Tus relés (NIP-95) - Los archivos están alojados en tus relés. Nuevo NIP: comprueba si son compatibles. Opciones de privacidad - Configuración de Tor/Orbot - Conéctate a través de tu configuración de Orbot Ajustar Configuración de Tor - ¿Desconectarse de tu Orbot/Tor? - Los datos se transferirán de inmediato en la red normal Sí No - Lista de seguidos Todos los seguidos Todas las cuentas a las que sigue el usuario - Siguiendo a través de proxy A mi alrededor Global Lista de silenciados Conjuntos de seguimiento - Marcadores etiquetados - Marcadores generales - Público - Privado - Mixto - Al parecer, aún no tienes ningún conjunto de seguimiento. - \nPulsa abajo para actualizar o pulsa los botones de añadir para crear uno nuevo. - Añadir autor a conjunto de seguimiento Añadir o eliminar usuario de las listas, o crear una nueva lista con este usuario. - Miembros privados - Perfiles públicos - Perfiles privados - miembro - miembros - Sin miembros Vacío - %1$s no se encuentra en esta lista %1$s no es miembro Tus listas y %1$s - Tus conjuntos de seguimiento - No se han encontrado conjuntos de seguimiento, o no tienes ningún conjunto de seguimiento. Pulsa abajo para actualizar o utiliza el menú para crear uno. - Ha habido un problema al recuperar: %1$s - Crear nueva lista - Nueva lista con membresía de %1$s - Crea un nuevo conjunto de seguimiento y añade a %1$s como miembro de %2$s. Nueva lista de seguimiento Nuevo paquete de seguimiento Copiar/Clonar lista de seguimiento @@ -887,14 +767,6 @@ Estás cambiando el nombre de a.. El puerto predeterminado es 9050 - ## Conéctate a través de Tor con Orbot - \n\n1. Instala [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android). - \n2. Inicia Orbot. - \n3. En Orbot, comprueba el puerto Socks. La opción predeterminada es 9050. - \n4. Si es necesario, cambia el puerto en Orbot. - \n5. Configura el puerto Socks en la pantalla. - \n6. Presiona y activa el botón para usar Orbot como proxy. - Puerto Socks de Orbot Motor de Tor activo Usar la versión interna u Orbot @@ -936,8 +808,6 @@ Oculta tu IP en todas las conexiones Crea el tuyo Número de puerto inválido - Usar Orbot - Desconectar Tor/Orbot Mensajes privados Te notifica cuando llega un mensaje privado Zaps recibidos @@ -969,23 +839,12 @@ Bluetooth Llamada de voz Notificar: - Unirse a la conversación - ID de usuario o grupo - npub, nevent o hexadecimal - Crear - Unirse Hoy Advertencia de contenido Esta publicación incluye contenido delicado que algunas personas pueden considerar ofensivo o perturbador. - Ocultar siempre el contenido delicado - Mostrar siempre el contenido delicado - Mostrar siempre advertencias sobre contenido Ocultar Mostrar Advertir - Recomendaciones: - Filtrar el spam de desconocidos - Avisar cuando las publicaciones tengan reportes de tus seguidos Filtrar spam Oculta las publicaciones de desconocidos que sean exactamente iguales 5 o más veces. Advertir sobre reportes @@ -1002,18 +861,15 @@ Relé de escritura La cantidad en bytes que se enviaron a este relé, incluyendo filtros y eventos La cantidad en bytes que se recibieron de este relé, incluyendo filtros y eventos - Se ha producido un error al intentar obtener información sobre el relé de %1$s Propietario Versión Software Contacto NIP compatibles Grasps compatibles - Tasas de admisión Admisión Suscripción Publicación - Pagos %1$s URL de pagos Público objetivo Políticas y enlaces @@ -1021,7 +877,6 @@ Limitaciones Países Idiomas - Etiquetas Temas Todos los países Todos los idiomas @@ -1034,48 +889,34 @@ Abrir Leer Escribir - RTT Red Tipo NIP compatibles Requisitos - Última comprobación %1$d ms Kinds aceptados Suscripciones activas - Eventos de outbox pendientes Suscripciones REQ (%1$d) Suscripciones COUNT (%1$d) - Longitud del mensaje - Suscripciones - Filtros - Longitud del ID de la suscripción Prefijo mínimo Etiquetas de evento máximas - Longitud del contenido Retención de eventos Tamaño de contenido Conectividad Control de acceso PoW mínima - Autenticación Se requiere autorización - Pago Se requiere pago Longitud máxima del mensaje Suscripciones máximas Filtros máximos por suscripción Límite máximo (devolución de eventos) - Límite predeterminado (devolución de eventos) Longitud máxima de subID Token de Cashu Canjear - Enviar a monedero de zaps - Abrir en monedero de Cashu Copiar token Abrir en otra app La dirección de Lightning no se ha configurado - Token copiado al portapapeles EN VIVO FUERA DE LÍNEA TERMINÓ @@ -1115,7 +956,6 @@ negentropy, …) stay searchable in every locale and aren't sent to translators. --> Zona peligrosa Siempre - Solo Wi-Fi WiFi sin medición Nunca Completo @@ -1139,7 +979,6 @@ Elegir el estilo de publicación Estilo de galería de perfil Elige el estilo de galería - Cargar imagen Spammers Silenciado. Hacer clic para reactivar el sonido. Sonido activado. Hacer clic para silenciar. @@ -1150,28 +989,19 @@ La dirección de Nostr se verificó No se pudo verificar la dirección de Nostr Verificando dirección de Nostr - Seleccionar o deseleccionar todo Predeterminados Restablecer valores predeterminados - Seleccionar un relé para continuar - Reenviar zaps a: - Los clientes compatibles reenviarán los zaps a la dirección de Lightning o al perfil de usuario indicados a continuación en lugar de a los tuyos. Revelar ubicación como Agrega un Geohash de tu ubicación al mensaje. El público sabrá que te encuentras a menos de 5 km (3 mi) de la ubicación actual. Publicación con ubicación exclusiva Solo los seguidores de la ubicación la verán. Tus seguidores generales no la verán. Publicación exclusiva de hashtag - Solo los seguidores del hashtag la verán. Tus seguidores generales no la verán. Cargando ubicación Sin permisos de ubicación Agrega una advertencia de contenido delicado antes de mostrarlo. Esto es ideal para cualquier contenido NSFW o que a algunas personas les pueda resultar ofensivo o perturbador. Motivo (opcional) - Función nueva - La activación de este modo requiere que Amethyst envíe un mensaje NIP-17 (mensajes directos sellados, de grupo y “GiftWrapped\"). NIP-17 es nuevo y la mayoría de los clientes aún no lo han implementado. Comprueba que el destinatario use un cliente compatible. - Activar Público Nuevo grupo público o privado - Relé Privado Para Asunto @@ -1183,16 +1013,12 @@ Explicación para los miembros Cambio de nombre para los nuevos objetivos. Pegar desde el portapapeles - URI de NIP-47 no válido - El URI %1$s no es un URI de inicio de sesión NIP-47 válido. - Conectar a nueva cartera NWC Cartera no encontrada Para la interfaz de la aplicación Tema oscuro, claro o del sistema Cargar automáticamente imágenes y GIF Reproducir automáticamente videos y GIF Mostrar vistas previas de URL - Cuándo cargar imágenes Copiar stack Copiar al portapapeles Copiar npub al portapapeles @@ -1203,49 +1029,26 @@ Contenido multimedia añadido Contenido multimedia añadido a la galería del perfil Creado - Reglas - Sobre nosotros Directrices Moderadores Iniciar sesión con Amber Actualiza tu estado - Error al analizar el mensaje de error Los votos se calculan según la cantidad de zaps. Puedes establecer una cantidad mínima para evitar spammers y una máxima para que los zappers grandes no puedan dominar la encuesta. Usa la misma cantidad en ambos campos para asegurarte de que cada voto tenga el mismo valor. Déjalos vacíos para aceptar cualquier cantidad. No se pudo enviar el zap Mensaje para el usuario Mensaje %1$s OK - No se pudo llegar a %1$s: %2$s - Error al ensamblar la url NIP-11 para %1$s: %2$s - No se pudo contactar %1$s: %2$s - Error al analizar la respuesta de %1$s: %2$s - El relé rechazó la solicitud %1$s: %2$s - No se pudo llegar a %1$s: %2$s - Error al analizar el resultado de %1$s: %2$s - %1$s falló con el código %2$s - Activo para: - Inicio - Mensajes directos - Chats - Global - Búsqueda Dividir y reenviar zaps Los clientes compatibles dividirán y reenviarán los zaps a los usuarios que se agreguen aquí en lugar de enviártelos a ti. Buscar y agregar usuario Nombre de usuario o para mostrar Lightning no está configurado El usuario %1$s no tiene una dirección de Lightning configurada para recibir sats. - Porcentaje - 25 - Dividir zaps con - Reenviar zaps a - No se encontraron billeteras de Lightning Pagado Monedero %1$s Error al abrir la aplicación firmante No se pudo encontrar la aplicación firmante. Comprueba si no se desinstaló la aplicación. Solicitud de firma rechazada - Solicitud de firma rechazada Asegúrate de que la aplicación firmante haya autorizado esta transacción. No se encontraron monederos para pagar una factura de Lightning (error: %1$s). Instala un monedero de Lightning para usar zaps. No se encontraron monederos para pagar una factura de Lightning. Instala un monedero de Lightning para usar zaps. @@ -1256,36 +1059,19 @@ Seleccionar una opción No se pudo pagar la factura No se pudo retirar - No se pudo configurar Wallet Connect - Error al analizar la cadena de conexión NIP-47. Comprueba si esto es correcto con el proveedor del monedero: %1$s. Error: %2$s - Error al analizar la cadena de conexión NIP-47. Comprueba si esto es correcto con el proveedor del monedero: %1$s. No se pudo canjear Cashu La Mint proporcionó el siguiente mensaje de error: %1$s - Los tokens de Cashu ya se gastaron. Cashu recibido Se enviaron %1$s sats a tu monedero (comisión: %2$s sats). No se encontró ningún monedero de Cashu compatible en el sistema No se puede obtener la factura de los servidores del destinatario El proveedor de conexión de monedero devolvió el siguiente error: %1$s - No se pudo conectar a Tor - No está disponible la descarga de documentos del relé No se pudo ensamblar la LNUrl desde la dirección de Lightning \"%1$s\". Comprueba la configuración del usuario. - El servicio de Lightning del destinatario en %1$s no está disponible. Se calculó a partir de la dirección de Lightning \"%2$s\". Error: %3$s. Comprueba si el servidor está activo y si la dirección de Lightning es correcta. - No se pudo resolver %1$s. Comprueba si tienes conexión, si el servidor está activo y si la dirección de Lightning \"%2$s\" es correcta. - No se pudo resolver %1$s. Comprueba si tienes conexión, si el servidor está activo y si la dirección de Lightning \"%2$s\" es correcta..\n\nLa excepción fue: %3$s - No se pudo obtener la factura de %1$s No se ha podido obtener la factura de %1$s: %2$s - Error al analizar JSON desde la dirección de Lightning. Comprueba la configuración de Lightning del usuario. Error al analizar JSON desde %1$s. Comprueba la configuración de Lightning del usuario. - No se encontró la URL de devolución de llamada en la configuración del servidor de la dirección de Lightning del usuario. No se encontró la URL de devolución de llamada en la respuesta de %1$s. - Error al analizar JSON desde la recuperación de factura de la dirección de Lightning. Comprueba la configuración de Lightning del usuario. - Error al analizar JSON desde la recuperación de factura de %1$s. Comprueba la configuración de Lightning del usuario. Cantidad de factura incorrecta (%1$s sats) de %2$s. Debería haber sido %3$s. No se pudo crear una factura de Lightning antes de enviar el zap. El monedero de Lightning del destinatario envió el siguiente error: %1$s. - No se pudo crear una factura de Lightning. Mensaje de %1$s: %2$s. - No se pudo crear una factura de Lightning antes de enviar el zap. No se encontró el elemento pr en el JSON resultante. - No se pudo crear una factura de Lightning desde %1$s: no se encontró el elemento pr en el JSON resultante. Usuario de solo lectura No hay reacciones configuradas Seleccionar una aplicación UnifiedPush @@ -1303,13 +1089,11 @@ Envía un mensaje al vendedor Hola, %1$s, ¿esto todavía está disponible? Hola, ¿esto todavía está disponible? - Vender un artículo Título iPhone 13 Estado Categoría Precio (en sats) - 1000 Ubicación Ciudad, estado, país. Nuevo @@ -1338,20 +1122,13 @@ Otros Error al subir contenido multimedia No se pudo abrir el archivo comprimido - Error al comprimir el contenido multimedia: %1$s Error de carga: %1$s El servidor no proporcionó una URL después de la carga No se pudo descargar el contenido cargado desde el servidor No se pudo comprobar el archivo descargado después de cargar: %1$s - No se pudo preparar el archivo local para cargar: %1$s Error al cargar a %1$s: %2$s - Error al subir: %1$s Error al eliminar: %1$s El contenido multimedia es demasiado grande para NIP-95 - No se puede subir imagen en miniatura - No se pudo preparar la información del encabezado: %1$s - Compresión cancelada - La compresión no pudo devolver un archivo Muchos servidores no aceptan archivos cifrados en cuentas gratuitas. Puedes volver a intentarlo sin cifrado. Reintentar sin cifrado Advertencia: Sin cifrado, cualquiera con el enlace del archivo puede ver el contenido. @@ -1365,34 +1142,25 @@ Mejor calidad en tamaños de archivos más pequeños, pero no todos los dispositivos admiten la reproducción H.265. Editar borrador Iniciar sesión con código QR - Ruta Inicio - Buscar Descubrir Mensajes Notificaciones - Global Cortos Ajedrez Cartera - Saldo Enviar Recibir Transacciones - No hay cartera conectada - Configure una conexión de Nostr Wallet Connect (NWC) en la configuración de zaps para usar la cartera. - Configurar cartera sats Pegar una factura BOLT-11 Pagar - Filtros de seguridad Importar seguidos Nueva publicación Nuevos cortos: imágenes o vídeos Nueva nota comunitaria Nuevo producto - Nueva publicación geoexclusiva Abrir todas las reacciones a esta publicación Cerrar todas las reacciones a esta publicación Responder @@ -1418,29 +1186,22 @@ Relé %1$s Ampliar lista de relés Opciones de notas - Selector de lista de relés Encuesta Desactivar encuesta Factura de Bitcoin Cancelar factura de Bitcoin - Cancelar la venta de un artículo Recaudación de zaps Cancelar zapraiser Ubicación Eliminar ubicación - Divisiones de zaps - Cancelar división de zap Añadir advertencia de contenido Eliminar advertencia de contenido Mostrar npub como código QR Dirección inválida Amethyst recibió un URI para abrir pero era inválido: %1$s Relés de buzón de entrada para mensajes directos - Relés: %1$s - Usando relés normales Configura tus relés de buzón de entrada privados Esta configuración permite que todo el mundo sepa qué relés usar cuando te envíen mensajes. Sin ellos, es posible que no recibas algunos mensajes. - Algunas buenas opciones son:\n - inbox.nostr.wine (de pago)\n - you.nostr1.com (relés personales; de pago) Algunas buenas opciones son:\n - auth.nostr1.com (free)\n - inbox.nostr.wine (paid)\n - relay.0xchat.com (free) Inserta entre 1 y 3 relés para que te sirvan de buzón de entrada privado. Los relés del buzón de entrada para mensajes directos deberían aceptar cualquier mensaje de cualquier persona, pero solo te permiten descargarlos. Configurar ahora @@ -1449,7 +1210,6 @@ La creación de una lista de relés específicamente diseñada para la búsqueda y el etiquetado de usuarios mejorará estos resultados. Inserta entre 1 y 3 relés para usarlos al buscar contenido o etiquetar usuarios. Asegúrate de que los relés que elijas implementen NIP-50. Algunas buenas opciones son: \n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com - Carga de mensaje directo Configuración de relés Relés de inicio públicos El usuario está publicando su contenido a estos relés @@ -1462,12 +1222,8 @@ Inserta entre 1 y 3 relés para que te sirvan de buzón de entrada privado. Otros usarán estos relés para enviarte mensajes directos. Los relés del buzón de entrada para mensajes directos deberían aceptar cualquier mensaje de cualquier persona, pero solo te permiten descargarlos. Algunas buenas opciones son:\n - inbox.nostr.wine (de pago)\n - you.nostr1.com (relés personales; de pago) Relés privados Inserta entre 1 y 3 relés para almacenar eventos que nadie más pueda ver, como los borradores o la configuración de la app. Lo ideal es que estos relés sean locales o requieran autenticación antes de descargar el contenido de cada usuario. - Relés generales - Amethyst usa estos relés para descargar publicaciones por ti. Relés conectados Lista actual de relés en uso - Relés recomendados - Agrega los siguientes relés a la lista de relés generales para recibir publicaciones de los usuarios de la lista. Relés de búsqueda Lista de relés que se usarán al buscar contenido o usuarios. El etiquetado y la búsqueda no funcionarán si no hay opciones disponibles. Asegúrate de que implementen NIP-50. Relés locales @@ -1494,11 +1250,8 @@ Esta versión fue posible gracias a: Versión %1$s ¡Gracias! - Límite máximo Escrituras restringidas Bifurcación de - BIFURCACIÓN - Repositorio Git: %1$s Web: Clon: OTS: %1$s @@ -1506,20 +1259,13 @@ Hay prueba de que esta publicación se firmó en algún momento antes de %1$s. La prueba se marcó en la cadena de bloques de Bitcoin en esa fecha y hora. Editar publicación Propuesta para mejorar una publicación - Resumen de cambios - Correcciones rápidas… Aceptar la sugerencia Iniciar video en una ventana emergente Descargar - Letra activada - Letra desactivada - Mensaje sellado desactivado. Haz clic para activar el mensaje sellado. - Mensaje sellado activado. Haz clic para desactivar el mensaje sellado. Enviar Reproducir nombre de usuario como audio Marcador Escanear código QR - Ir al proveedor externo de monederos Alby No es posible responder a un borrador de nota No es posible citar un borrador de nota No es posible reaccionar a un borrador de nota @@ -1560,28 +1306,23 @@ Almacenamiento insuficiente: el servidor no dispone de almacenamiento suficiente para procesar correctamente la solicitud. Bucle detectado: el servidor detecta un bucle infinito al procesar la solicitud. Autenticación de red requerida: el cliente debe estar autenticado para acceder a la red. - Servidores NIP-96 - Añade tantos servidores como quieras. Puedes elegir cuál utilizar más tarde al cargar tu foto. Servidores Blossom Añade tantos servidores como quieras. Puedes elegir cuál utilizar más tarde al subir tu foto. Agregar servidor NIP-96 Añadir un servidor Blossom Borrar todo ¿Seguro quieres eliminar todos los borradores? - Stack: Archivo torrent Descargar Error al abrir el archivo No hay aplicaciones torrent instaladas para abrir y descargar el archivo. El evento no tiene suficiente información para crear un enlace magnético - Mis listas/conjuntos Selecciona una lista para filtrar el tablón Cerrar sesión al bloquear dispositivo Mensaje privado Mensaje público Relé de chat - Relé al que todos los usuarios de este chat se conectan Compartir imagen… No se puede compartir la imagen, inténtalo de nuevo más tarde… Buscar hashtag: #%1$s @@ -1596,7 +1337,6 @@ Informe de error encontrado ¿Te gustaría enviar el informe de error reciente a Amethyst en un mensaje directo? No se compartirá información personal Enviarlo - Este mensaje desaparecerá en %1$d días Seleccionar firmante @@ -1608,4 +1348,10 @@ + + El servicio de Lightning del destinatario en %1$s no está disponible. Se calculó a partir de la dirección de Lightning \"%2$s\". Error: %3$s. Comprueba si el servidor está activo y si la dirección de Lightning es correcta. + No se pudo resolver %1$s. Comprueba si tienes conexión, si el servidor está activo y si la dirección de Lightning \"%2$s\" es correcta..\n\nLa excepción fue: %3$s + Error al analizar JSON desde la recuperación de factura de %1$s. Comprueba la configuración de Lightning del usuario. + No se pudo crear una factura de Lightning. Mensaje de %1$s: %2$s. + No se pudo crear una factura de Lightning desde %1$s: no se encontró el elemento pr en el JSON resultante. diff --git a/amethyst/src/main/res/values-es-rMX/strings.xml b/amethyst/src/main/res/values-es-rMX/strings.xml index d64565c149..3350f1b181 100644 --- a/amethyst/src/main/res/values-es-rMX/strings.xml +++ b/amethyst/src/main/res/values-es-rMX/strings.xml @@ -32,8 +32,6 @@ Otro Acoso Violencia - Desconocido - Ícono de relé Autor desconocido Copiar texto Copiar llave pública del usuario @@ -48,12 +46,9 @@ Reportar spam o estafa Reportar suplantación de identidad - Reportar contenido explícito Reportar comportamiento ilegal Reportar malware - Reportar mod Malware - Mod Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder responder Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder impulsar publicaciones Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para indicar que te gustan las publicaciones. @@ -73,10 +68,8 @@ El firmante no autorizó un descifrado necesario para realizar esta operación. Activa el descifrado NIP-44 en tu aplicación de firmante e inténtalo de nuevo No se ha encontrado el firmante. ¿Se desinstaló la app del firmante? Comprueba si el firmante está instalado y tiene esta cuenta. Cierra sesión y vuelve a iniciar sesión en la app del firmante si cambió. - Fallo en el comportamiento del firmante El firmante externo devolvió una carga útil que no concuerda con la solicitud. Es posible que haya un error, ya sea en Amethyst o en el firmante. Zaps - Total de visualizaciones Impulsar Impulsada editada @@ -89,9 +82,7 @@ Agregar "respondiendo a " " y " - "en el canal " Banner del perfil - El pago se realizó correctamente Error al analizar el mensaje de error " Siguiendo" " Seguidores" @@ -164,7 +155,6 @@ No hay suficiente saldo en una moneda que acepte este destinatario. Recarga tu billetera de Cashu primero. Disponible para este destinatario: %1$s sats Comisión de red - tu app de billetera Transacción: %1$s Propinas mediante Lightning Nota para el destinatario @@ -178,16 +168,13 @@ Prefijo visible 😎 Agregar a publicación - "Error al analizar la vista previa de %1$s : %2$s" "Vista previa de imagen de tarjeta para %1$s" Artículo - Nuevo canal Nombre del canal Mi grupo genial URL de imagen Url de imagen (opcional) Descripción - No se encontró la descripción "Quiénes somos…" ¿Qué estás pensando? Escribir un mensaje… @@ -197,42 +184,25 @@ Crear Cambiar nombre Cancelar - Error al subir la imagen - Dirección del relé - Publicaciones - Bytes Error Errores Porcentaje de conexiones exitosas al relé - El número de errores de conexión en esta sesión - Tus noticias - Feed de mensajes privados - Feed del chat público - Feed global - Feed de búsqueda Buscar y agregar usuario - Agregar un usuario Agregar un relé - Nombre - Nombre (para @etiquetar) Mi nombre de @etiqueta Nombre para mostrar Mi nombre para mostrar Avestruz Maravillosa ¡Te damos la bienvenida, Avestruz! Nombre de usuario - Mi nombre de usuario Quién soy URL del avatar URL del banner URL del sitio web Pronombres - Dirección de Lightning - URL de Lightning (obsoleta) Los relés de origen pueden ser obsoletos Aviso de relé obsoleto Guardar en el teléfono - Guardar en la galería Imagen guardada en la galería Comenzó la descarga del video… Comenzó la descarga del contenido multimedia… @@ -248,15 +218,12 @@ Subir archivo Tomar una foto Grabar un mensaje - Grabar un mensaje Haz clic y mantén presionado para grabar un mensaje Volver a grabar Grabación Grabando %1$s - Subiendo… Error de carga Error al cargar el mensaje de voz - Estado inesperado de carga NIP-95 aún no es compatible con mensajes de voz Error al cargar voz: %1$s Ninguna @@ -268,8 +235,6 @@ El usuario no tiene configurada una dirección de Lightning para recibir sats "responde aquí… " En este chat - Copia el ID de la nota al portapapeles para compartirla en Nostr - Copiar el ID del canal (nota) al portapapeles Edita los metadatos del canal Unirse Conocidos @@ -281,7 +246,6 @@ Respuestas Tuyo Galería - "Seguidos" "Reportes" "%1$s informes" Más opciones @@ -289,11 +253,8 @@ Sitio web Dirección de Lightning Copia el ID Nsec (tu contraseña) en el portapapeles para hacer una copia de seguridad - Copiar la clave secreta al portapapeles Mostrar código QR de clave privada Mostrar código QR de clave privada cifrada - Copia la clave pública al portapapeles para compartirla - Copiar la clave pública (NPub) al portapapeles Enviar un mensaje directo Edita los metadatos del usuario Seguir @@ -322,8 +283,6 @@ ¿Cómo debemos llamarte? ¿No tienes una cuenta de Nostr? ¿Ya tienes una cuenta de Nostr? - Crear una cuenta nueva - Generar una clave nueva Cargando feed Cargando cuenta encriptado @@ -339,13 +298,7 @@ Encuesta abierta El feed está vacío. Actualizar - creado - con la descripción de - e imagen - cambió el nombre del chat a Nuevo perfil de chat: - descripción a - e imagen a Salir Dejar de seguir Canal creado @@ -382,7 +335,6 @@ Dirección de Nostr nunca ahora - segundos h m d @@ -390,7 +342,6 @@ Groserías o lenguaje que incita al odio Reportar lenguaje que incita al odio Reportar desnudos o pornografía - otros Marcar todos los conocidos como leídos Marcar todos los nuevos como leídos Marcar todos como leídos @@ -411,8 +362,6 @@ Error de autenticación El sistema biométrico no pudo autenticar al propietario de este teléfono El sistema biométrico no pudo autenticar al propietario de este teléfono. Error: %1$s - Error - "Creado por %1$s" "Imagen de premio de insignia por %1$s" \"Imagen de premio de insignia Recibiste un nuevo premio de insignia @@ -420,7 +369,6 @@ Texto de la nota copiado al portapapeles \@npub del autor copiado al portapapeles ID de la nota (@note1) copiado al portapapeles - Seleccionar texto "<Unable to decrypt private message>\n\nTe citaron en una conversación privada o encriptada entre %1$s y %2$s." Agregar cuenta nueva Cuentas @@ -432,8 +380,6 @@ Seleccionar cuenta Agregar cuenta nueva Cuenta activa - Tiene clave privada - Solo de lectura, sin clave privada Volver Seleccionar Compartir enlace del navegador @@ -454,14 +400,12 @@ Silenciar hilo Reactivar hilo Reportar - Eliminar No mostrar de nuevo Spam o estafas Groserías o conducta que incita al odio Suplantación de identidad malintencionada Desnudez o contenido gráfico Comportamiento ilegal - Malware Si bloqueas a un usuario, se ocultará su contenido en tu app. Tus notas todavía son visibles públicamente, incluso para las personas que bloquees. Los usuarios bloqueados aparecen en la pantalla \"Filtros de seguridad\". Reportar abuso @@ -489,7 +433,6 @@ Elegir hora programada Programación para… Se publica en %1$s - Se venció hace %1$s Hora Programar publicación Cancelar programación @@ -564,7 +507,6 @@ Autor Solicitudes Aprobaciones - Ninguna comunidad coincide con este filtro. Reglas verificables (opcional) Publica un documento de reglas legibles automáticamente (NIP-9B) junto con la comunidad. Los clientes que lo admiten bloquean las publicaciones que no coinciden antes de enviarlas. Guardar límites @@ -629,7 +571,6 @@ Transmitir en vivo… Transmisión fallida: %1$s Error al silenciar: %1$s - Se requiere acceso al micrófono para hablar en esta sala. Sin permisos Nests Mantiene la reproducción de audio mientras una sala está abierta. @@ -640,7 +581,6 @@ Unirse a nest Anfitrión Abrir - Chat reciente Nadie se encuentra en la sala en este momento. %1$d escuchando Anfitrión @@ -668,8 +608,6 @@ Público Manos Todavía no hay nadie en el público. - Enviar - Di algo… Aún no hay mensajes. Sé el primero en chatear. Reaccionar Editar sala @@ -686,7 +624,6 @@ Elige en qué servidores host de MoQ quieres que Amethyst publique tus nests. La primera entrada es predeterminada cuando creas un nuevo espacio. Tus servidores Guardado como un evento reemplazable para que otros clientes puedan leer tus preferencias. - Agregar un servidor de nest URL del relé (WebTransport) URL de autenticación (generación de JWT) Agregar @@ -707,9 +644,6 @@ Eliminar lista de marcadores Ver publicaciones Ver artículos - Ver enlaces - Ver hashtags - Aún no tienes ninguna lista de marcadores. Toca el nuevo botón de abajo para crear una. Publicaciones privadas Publicaciones privadas(%1$s) Publicaciones públicas @@ -720,16 +654,6 @@ Los metadatos de las listas de marcadores son visibles para cualquier usuario de Nostr. Solo los miembros privados están cifrados. Mover a público Mover a privado - Servicio de conexión a billetera - Autoriza a un secreto de Nostr para pagar zaps sin salir de la app. Mantén el secreto seguro y usa un relé privado si es posible. - Clave pública de conexión a billetera - Relé de conexión a billetera - Secreto de conexión a billetera - Clave secreta de conexión a billetera - clave privada nsec / hex - Conectada - No conectada - Avanzado: introduce manualmente los detalles de la conexión Cantidad de zap rápido Aparece al presionar el botón de zap. Toca una cantidad para eliminarla. Si la dejas vacía, se abrirá el cuadro de diálogo para introducir una cantidad cada vez. Privacidad de zaps @@ -737,14 +661,8 @@ Conectar billetera Ver fuente de relés Destinar cantidad en sats - Publicar encuesta - Campos obligatorios: - Destinatarios de zaps - Descripción de encuesta principal… - Opción Opción %s Descripción de opción de encuesta - Campos opcionales: Zap mínimo Zap máximo Consenso @@ -753,11 +671,8 @@ Opción múltiple Fecha y hora de cierre de la encuesta La encuesta se cierra en %1$s - Cerrar después de - días No se puede votar Encuesta cerrada para votos nuevos - Monto del zap Solo se permite un voto por usuario en este tipo de encuesta "Buscando evento %1$s" Enviar zap @@ -791,17 +706,12 @@ No zap No hay rastro en Nostr, solo en Lightning Anónimo - Publicar como una nueva identidad temporal. Tu cuenta no quedará vinculada a esta respuesta. - Esta respuesta se publicará desde una nueva identidad anónima Servidor de archivos Elegir un servidor para subir este archivo - Dirección o @usuario de Lightning Servidores multimedia Configura tus servidores preferidos para subir contenido multimedia. - No tienes ningún servidor NIP-96 configurado. Puedes usar la lista de Amethyst o agregar uno de la lista a continuación ↓ No tienes ningún servidor Blossom configurado. Puedes usar la lista de Amethyst o agregar uno de la lista a continuación ↓ Servidores multimedia recomendados - Servidores multimedia integrados Lista predeterminada de Amethyst. Puedes agregarlos individualmente o añadir la lista. Usar lista predeterminada Agregar servidor multimedia @@ -818,50 +728,21 @@ Cifrando Listo Error - Tus relés (NIP-95) - Los archivos están alojados en tus relés. Nuevo NIP: comprueba si son compatibles. Opciones de privacidad - Configuración de Tor/Orbot - Conéctate a través de tu configuración de Orbot Ajustar Configuración de Tor - ¿Desconectarse de tu Orbot/Tor? - Los datos se transferirán de inmediato en la red normal Sí No - Lista de seguidos Todos los seguidos - Siguiendo a través de proxy A mi alrededor Global Lista de silenciados Conjuntos de seguimiento - Marcadores etiquetados - Marcadores generales - Público - Privado - Mixto - Al parecer, aún no tienes ningún conjunto de seguimiento. - \nToca abajo para actualizar o toca los botones de agregar para crear uno nuevo. - Agregar autor a conjunto de seguimiento Agregar o quitar usuario de las listas, o crear una nueva lista con este usuario. - Miembros privados - Perfiles públicos - Perfiles privados - miembro - miembros - Sin miembros Vacío - %1$s no se encuentra en esta lista %1$s no es miembro Tus listas y %1$s - Tus conjuntos de seguimiento - No se han encontrado conjuntos de seguimiento, o no tienes ningún conjunto de seguimiento. Toca abajo para actualizar o utiliza el menú para crear uno. - Hubo un problema al recuperar: %1$s - Crear nueva lista - Nueva lista con membresía de %1$s - Crea un nuevo conjunto de seguimiento y añade a %1$s como miembro de %2$s. Nueva lista de seguimiento Nuevo paquete de seguimiento Copiar/Clonar lista de seguimiento @@ -881,14 +762,6 @@ Estás cambiando el nombre de a.. El puerto predeterminado es 9050 - ## Conéctate a través de Tor con Orbot - \n\n1. Instala [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android). - \n2. Inicia Orbot. - \n3. En Orbot, comprueba el puerto Socks. La opción predeterminada es 9050. - \n4. Si es necesario, cambia el puerto en Orbot. - \n5. Configura el puerto Socks en la pantalla. - \n6. Presiona y activa el botón para usar Orbot como proxy. - Puerto Socks de Orbot Motor de Tor activo Usar la versión interna u Orbot @@ -930,8 +803,6 @@ Ocultar su IP en todas las conexiones Crea el tuyo Número de puerto inválido - Usar Orbot - Desconectar Tor/Orbot Mensajes privados Te notifica cuando llega un mensaje privado Zaps recibidos @@ -963,23 +834,12 @@ Bluetooth Llamada de voz Notificar: - Unirse a la conversación - ID de usuario o grupo - npub, nevent o hexadecimal - Crear - Unirse Hoy Advertencia de contenido Esta publicación incluye contenido delicado que algunas personas pueden considerar ofensivo o perturbador. - Ocultar siempre el contenido delicado - Mostrar siempre el contenido delicado - Mostrar siempre advertencias sobre contenido Ocultar Mostrar Advertir - Recomendaciones: - Filtrar el spam de desconocidos - Avisar cuando las publicaciones tengan reportes de tus seguidos Filtrar spam Oculta las publicaciones de desconocidos que sean exactamente iguales 5 o más veces. Advertir sobre reportes @@ -996,18 +856,15 @@ Relé de escritura La cantidad en bytes que se enviaron a este relé, incluyendo filtros y eventos La cantidad en bytes que se recibieron de este relé, incluyendo filtros y eventos - Se produjo un error al intentar obtener información sobre el relé de %1$s Propietario Versión Software Contacto NIP compatibles Grasps compatibles - Tarifas de admisión Admisión Suscripción Publicación - Pagos %1$s URL de pagos Público objetivo Políticas y enlaces @@ -1015,7 +872,6 @@ Limitaciones Países Idiomas - Etiquetas Temas Todos los países Todos los idiomas @@ -1028,48 +884,34 @@ Abrir Leer Escribir - RTT Red Tipo NIP compatibles Requisitos - Última comprobación %1$d ms Kinds aceptados Suscripciones activas - Eventos de outbox pendientes Suscripciones REQ (%1$d) Suscripciones COUNT (%1$d) - Longitud del mensaje - Suscripciones - Filtros - Longitud del ID de la suscripción Prefijo mínimo Etiquetas de evento máximas - Longitud del contenido Retención de eventos Tamaño de contenido Conectividad Control de acceso PoW mínima - Autenticación Se requiere autorización - Pago Se requiere pago Longitud máxima del mensaje Suscripciones máximas Filtros máximos por suscripción Límite máximo (devolución de eventos) - Límite predeterminado (devolución de eventos) Longitud máxima de subID Token de Cashu Canjear - Enviar a billetera de zaps - Abrir en billetera de Cashu Copiar token Abrir en otra app La dirección de Lightning no está configurada - Token copiado al portapapeles EN VIVO FUERA DE LÍNEA TERMINÓ @@ -1109,7 +951,6 @@ negentropy, …) stay searchable in every locale and aren't sent to translators. --> Zona peligrosa Siempre - Solo Wi-Fi WiFi sin medición Nunca Completo @@ -1133,7 +974,6 @@ Elegir el estilo de publicación Estilo de galería de perfil Elige el estilo de galería - Cargar imagen Spammers Silenciado. Hacer clic para reactivar el sonido. Sonido activado. Hacer clic para silenciar. @@ -1144,28 +984,19 @@ La dirección de Nostr se verificó No se pudo verificar la dirección de Nostr Verificando dirección de Nostr - Seleccionar o deseleccionar todo Predeterminados Restablecer valores predeterminados - Seleccionar un relé para continuar - Reenviar zaps a: - Los clientes compatibles reenviarán los zaps a la dirección de Lightning o al perfil de usuario indicados a continuación en lugar de a los tuyos. Revelar ubicación como Agrega un Geohash de tu ubicación al mensaje. El público sabrá que te encuentras a menos de 5 km (3 mi) de la ubicación actual. Publicación con ubicación exclusiva Solo los seguidores de la ubicación la verán. Tus seguidores generales no la verán. Publicación exclusiva de hashtag - Solo los seguidores del hashtag la verán. Tus seguidores generales no la verán. Cargando ubicación Sin permisos de ubicación Agrega una advertencia de contenido delicado antes de mostrarlo. Esto es ideal para cualquier contenido NSFW o que a algunas personas les pueda resultar ofensivo o perturbador. Motivo (opcional) - Función nueva - La activación de este modo requiere que Amethyst envíe un mensaje NIP-17 (mensajes directos sellados, de grupo y “GiftWrapped\"). NIP-17 es nuevo y la mayoría de los clientes aún no lo han implementado. Comprueba que el destinatario use un cliente compatible. - Activar Público Nuevo grupo público o privado - Relé Privado Para Asunto @@ -1177,14 +1008,12 @@ Explicación para los miembros Cambio de nombre para los nuevos objetivos. Pegar desde el portapapeles - Conectar a nueva billetera NWC Billetera no encontrada Para la interfaz de la aplicación Tema oscuro, claro o del sistema Cargar automáticamente imágenes y GIF Reproducir automáticamente videos y GIF Mostrar vistas previas de URL - Cuándo cargar imágenes Copiar stack Copiar al portapapeles Copiar npub al portapapeles @@ -1195,46 +1024,24 @@ Contenido multimedia agregado Contenido multimedia agregado a la galería del perfil Creado - Reglas Iniciar sesión con Amber Actualiza tu estado - Error al analizar el mensaje de error Los votos se calculan según la cantidad de zaps. Puedes establecer una cantidad mínima para evitar spammers y una máxima para que los zappers grandes no puedan dominar la encuesta. Usa la misma cantidad en ambos campos para asegurarte de que cada voto tenga el mismo valor. Déjalos vacíos para aceptar cualquier cantidad. No se pudo enviar el zap Mensaje para el usuario Mensaje %1$s OK - No se pudo llegar a %1$s: %2$s - Error al ensamblar la url NIP-11 para %1$s: %2$s - No se pudo contactar %1$s: %2$s - Error al analizar la respuesta de %1$s: %2$s - El relé rechazó la solicitud %1$s: %2$s - No se pudo llegar a %1$s: %2$s - Error al analizar el resultado de %1$s: %2$s - %1$s falló con el código %2$s - Activo para: - Inicio - Mensajes directos - Chats - Global - Búsqueda Dividir y reenviar zaps Los clientes compatibles dividirán y reenviarán los zaps a los usuarios que se agreguen aquí en lugar de a ti. Buscar y agregar usuario Nombre de usuario o para mostrar Lightning no está configurado El usuario %1$s no tiene una dirección de Lightning configurada para recibir sats. - Porcentaje - 25 - Dividir zaps con - Reenviar zaps a - No se encontraron billeteras de Lightning Pagado Billetera %1$s Error al abrir la aplicación firmante No se pudo encontrar la aplicación firmante. Comprueba si no se desinstaló la aplicación. Solicitud de firma rechazada - Solicitud de firma rechazada Asegúrate de que la aplicación firmante haya autorizado esta transacción. No se encontraron billeteras para pagar una factura de Lightning (error: %1$s). Instala una billetera de Lightning para usar zaps. No se encontraron billeteras para pagar una factura de Lightning. Instala una billetera de Lightning para usar zaps. @@ -1245,36 +1052,19 @@ Seleccionar una opción No se pudo pagar la factura No se pudo retirar - No se pudo configurar Wallet Connect - Error al analizar la cadena de conexión NIP-47. Comprueba si esto es correcto con el proveedor de la billetera: %1$s. Error: %2$s - Error al analizar la cadena de conexión NIP-47. Comprueba si esto es correcto con el proveedor de la billetera: %1$s. No se pudo canjear Cashu La Mint proporcionó el siguiente mensaje de error: %1$s - Los tokens de Cashu ya se gastaron. Cashu recibido Se enviaron %1$s sats a tu billetera (comisión: %2$s sats). No se encontró ninguna billetera de Cashu compatible en el sistema No se puede obtener la factura de los servidores del destinatario El proveedor de conexión de billetera devolvió el siguiente error: %1$s - No se pudo conectar a Tor - No está disponible la descarga de documentos del relé No se pudo ensamblar la LNUrl desde la dirección de Lightning \"%1$s\". Comprueba la configuración del usuario. - El servicio de Lightning del destinatario en %1$s no está disponible. Se calculó a partir de la dirección de Lightning \"%2$s\". Error: %3$s. Comprueba si el servidor está activo y si la dirección de Lightning es correcta. - No se pudo resolver %1$s. Comprueba si tienes conexión, si el servidor está activo y si la dirección de Lightning \"%2$s\" es correcta. - No se pudo resolver %1$s. Comprueba si tienes conexión, si el servidor está activo y si la dirección de Lightning \"%2$s\" es correcta..\n\nLa excepción fue: %3$s - No se pudo obtener la factura de %1$s No se pudo obtener la factura de %1$s: %2$s - Error al analizar JSON desde la dirección de Lightning. Comprueba la configuración de Lightning del usuario. Error al analizar JSON desde %1$s. Comprueba la configuración de Lightning del usuario. - No se encontró la URL de devolución de llamada en la configuración del servidor de la dirección de Lightning del usuario. No se encontró la URL de devolución de llamada en la respuesta de %1$s. - Error al analizar JSON desde la recuperación de factura de la dirección de Lightning. Comprueba la configuración de Lightning del usuario. - Error al analizar JSON desde la recuperación de factura de %1$s. Comprueba la configuración de Lightning del usuario. Cantidad de factura incorrecta (%1$s sats) de %2$s. Debería haber sido %3$s. No se pudo crear una factura de Lightning antes de enviar el zap. La billetera de Lightning del destinatario envió el siguiente error: %1$s. - No se pudo crear una factura de Lightning. Mensaje de %1$s: %2$s. - No se pudo crear una factura de Lightning antes de enviar el zap. No se encontró el elemento pr en el JSON resultante. - No se pudo crear una factura de Lightning desde %1$s: no se encontró el elemento pr en el JSON resultante. Usuario de solo lectura No hay reacciones configuradas Seleccionar una aplicación UnifiedPush @@ -1292,13 +1082,11 @@ Envía un mensaje al vendedor Hola, %1$s, ¿esto todavía está disponible? Hola, ¿esto todavía está disponible? - Vender un artículo Título iPhone 13 Estado Categoría Precio (en sats) - 1000 Ubicación Ciudad, estado, país. Nuevo @@ -1327,20 +1115,13 @@ Otros Error al subir contenido multimedia No se pudo abrir el archivo comprimido - Error al comprimir el contenido multimedia: %1$s Error de subida: %1$s El servidor no proporcionó una URL después de la subida No se pudo descargar el contenido subido desde el servidor No se pudo comprobar el archivo descargado después de subir: %1$s - No se pudo preparar el archivo local para subir: %1$s Error al subir a %1$s: %2$s - Error al subir: %1$s Error al eliminar: %1$s El contenido multimedia es demasiado grande para NIP-95 - No se puede subir imagen en miniatura - No se pudo preparar la información del encabezado: %1$s - Compresión cancelada - La compresión no pudo devolver un archivo Muchos servidores no aceptan archivos cifrados en cuentas gratuitas. Puedes volver a intentarlo sin cifrado. Reintentar sin cifrado Advertencia: Sin cifrado, cualquiera con el enlace del archivo puede ver el contenido. @@ -1354,34 +1135,25 @@ Mejor calidad en tamaños de archivos más pequeños, pero no todos los dispositivos admiten la reproducción H.265. Editar borrador Iniciar sesión con código QR - Ruta Inicio - Buscar Descubrir Mensajes Notificaciones - Global Cortos Ajedrez Billetera - Saldo Enviar Recibir Transacciones - No hay billetera conectada - Configure una conexión de Nostr Wallet Connect (NWC) en la configuración de zaps para usar la billetera. - Configurar billetera sats Pegar una factura BOLT-11 Pagar - Filtros de seguridad Importar seguidos Nueva publicación Nuevos cortos: imágenes o videos Nueva nota comunitaria Nuevo producto - Nueva publicación geoexclusiva Abrir todas las reacciones a esta publicación Cerrar todas las reacciones a esta publicación Responder @@ -1407,29 +1179,22 @@ Relé %1$s Ampliar lista de relés Opciones de notas - Selector de lista de relés Encuesta Desactivar encuesta Factura de Bitcoin Cancelar factura de Bitcoin - Cancelar la venta de un artículo Recaudación de zaps Cancelar zapraiser Ubicación Eliminar ubicación - Divisiones de zaps - Cancelar división de zap Agregar advertencia de contenido Eliminar advertencia de contenido Mostrar npub como código QR Dirección inválida Amethyst recibió un URI para abrir pero era inválido: %1$s Relés de buzón de entrada para mensajes directos - Relés: %1$s - Usando relés normales Configura tus relés de buzón de entrada privados Esta configuración permite que todo el mundo sepa qué relés usar cuando te envíen mensajes. Sin ellos, es posible que no recibas algunos mensajes. - Algunas buenas opciones son:\n - inbox.nostr.wine (de pago)\n - you.nostr1.com (relés personales; de pago) Algunas buenas opciones son:\n - auth.nostr1.com (free)\n - inbox.nostr.wine (paid)\n - relay.0xchat.com (free) Inserta entre 1 y 3 relés para que te sirvan de buzón de entrada privado. Los relés del buzón de entrada para mensajes directos deberían aceptar cualquier mensaje de cualquier persona, pero solo te permiten descargarlos. Configurar ahora @@ -1438,7 +1203,6 @@ La creación de una lista de relés específicamente diseñada para la búsqueda y el etiquetado de usuarios mejorará estos resultados. Inserta entre 1 y 3 relés para usarlos al buscar contenido o etiquetar usuarios. Asegúrate de que los relés que elijas implementen NIP-50. Algunas buenas opciones son: \n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com - Subida de mensaje directo Configuración de relés Relés de inicio públicos Este tipo de relé almacena todo tu contenido. Amethyst enviará tus publicaciones aquí y otros usarán estos relés para encontrar tu contenido. Inserta entre 1 y 3 relés. Pueden ser personales, de pago o públicos. @@ -1448,12 +1212,8 @@ Inserta entre 1 y 3 relés para que te sirvan de buzón de entrada privado. Otros usarán estos relés para enviarte mensajes directos. Los relés del buzón de entrada para mensajes directos deberían aceptar cualquier mensaje de cualquier persona, pero solo te permiten descargarlos. Algunas buenas opciones son:\n - inbox.nostr.wine (de pago)\n - you.nostr1.com (relés personales; de pago) Relés privados Inserta entre 1 y 3 relés para almacenar eventos que nadie más pueda ver, como los borradores o la configuración de la app. Lo ideal es que estos relés sean locales o requieran autenticación antes de descargar el contenido de cada usuario. - Relés generales - Amethyst usa estos relés para descargar publicaciones por ti. Relés conectados Lista actual de relés en uso - Relés recomendados - Agrega los siguientes relés a la lista de relés generales para recibir publicaciones de los usuarios de la lista. Relés de búsqueda Lista de relés que se usarán al buscar contenido o usuarios. El etiquetado y la búsqueda no funcionarán si no hay opciones disponibles. Asegúrate de que implementen NIP-50. Relés locales @@ -1480,11 +1240,8 @@ Esta versión fue posible gracias a: Versión %1$s ¡Gracias! - Límite máximo Escrituras restringidas Bifurcación de - BIFURCACIÓN - Repositorio Git: %1$s Web: Clon: OTS: %1$s @@ -1492,20 +1249,13 @@ Hay prueba de que esta publicación se firmó en algún momento antes de %1$s. La prueba se marcó en la cadena de bloques de Bitcoin en esa fecha y hora. Editar publicación Propuesta para mejorar una publicación - Resumen de cambios - Correcciones rápidas… Aceptar la sugerencia Iniciar video en una ventana emergente Descargar - Letra activada - Letra desactivada - Mensaje sellado desactivado. Haz clic para activar el mensaje sellado. - Mensaje sellado activado. Haz clic para desactivar el mensaje sellado. Enviar Reproducir nombre de usuario como audio Marcador Escanear código QR - Ir al proveedor externo de billeteras Alby No es posible responder a un borrador de nota No es posible citar un borrador de nota No es posible reaccionar a un borrador de nota @@ -1546,28 +1296,23 @@ Almacenamiento insuficiente: el servidor no dispone de almacenamiento suficiente para procesar correctamente la solicitud. Bucle detectado: el servidor detecta un bucle infinito al procesar la solicitud. Autenticación de red requerida: el cliente debe estar autenticado para acceder a la red. - Servidores NIP-96 - Agrega tantos servidores como quieras. Puedes elegir cuál usar más tarde al subir tu foto. Servidores Blossom Agrega tantos servidores como quieras. Puedes elegir cuál usar más tarde al subir tu foto. Agregar servidor NIP-96 Agregar un servidor Blossom Borrar todo ¿Seguro quieres eliminar todos los borradores? - Stack: Archivo torrent Descargar Error al abrir el archivo No hay aplicaciones torrent instaladas para abrir y descargar el archivo. El evento no tiene suficiente información para crear un enlace magnético - Mis listas/conjuntos Selecciona una lista para filtrar el feed Cerrar sesión al bloquear dispositivo Mensaje privado Mensaje público Relé de chat - Relé al que todos los usuarios de este chat se conectan Compartir imagen… Buscar hashtag: #%1$s No traducir del @@ -1583,4 +1328,10 @@ + + El servicio de Lightning del destinatario en %1$s no está disponible. Se calculó a partir de la dirección de Lightning \"%2$s\". Error: %3$s. Comprueba si el servidor está activo y si la dirección de Lightning es correcta. + No se pudo resolver %1$s. Comprueba si tienes conexión, si el servidor está activo y si la dirección de Lightning \"%2$s\" es correcta..\n\nLa excepción fue: %3$s + Error al analizar JSON desde la recuperación de factura de %1$s. Comprueba la configuración de Lightning del usuario. + No se pudo crear una factura de Lightning. Mensaje de %1$s: %2$s. + No se pudo crear una factura de Lightning desde %1$s: no se encontró el elemento pr en el JSON resultante. diff --git a/amethyst/src/main/res/values-es-rUS/strings.xml b/amethyst/src/main/res/values-es-rUS/strings.xml index 8ab8c1c55b..03c52ebaba 100644 --- a/amethyst/src/main/res/values-es-rUS/strings.xml +++ b/amethyst/src/main/res/values-es-rUS/strings.xml @@ -32,8 +32,6 @@ Otro Acoso Violencia - Desconocido - Ícono de relé Autor desconocido Copiar texto Copiar ID del autor @@ -48,12 +46,9 @@ Reportar spam o estafa Reportar suplantación de identidad - Reportar contenido explícito Reportar comportamiento ilegal Reportar malware - Reportar mod Malware - Mod Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder responder Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder impulsar publicaciones Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para indicar que te gustan las publicaciones. @@ -73,10 +68,8 @@ El firmante no autorizó un descifrado necesario para realizar esta operación. Activa el descifrado NIP-44 en tu aplicación de firmante e inténtalo de nuevo No se ha encontrado el firmante. ¿Se desinstaló la app del firmante? Comprueba si el firmante está instalado y tiene esta cuenta. Cierra sesión y vuelve a iniciar sesión en la app del firmante si cambió. - Fallo en el comportamiento del firmante El firmante externo devolvió una carga útil que no concuerda con la solicitud. Es posible que haya un error, ya sea en Amethyst o en el firmante. Zaps - Total vistas Impulsar Impulsada editada @@ -89,9 +82,7 @@ Agregar "respondiendo a " " y " - "en el canal " Banner del perfil - El pago se realizó correctamente Error al analizar el mensaje de error " Siguiendo" " Seguidores" @@ -164,7 +155,6 @@ No hay suficiente saldo en una moneda que acepte este destinatario. Recarga tu billetera de Cashu primero. Disponible para este destinatario: %1$s sats Comisión de red - tu app de billetera Transacción: %1$s Propinas mediante Lightning Nota para el destinatario @@ -178,16 +168,13 @@ Prefijo visible 😎 Agregar a publicación - "Error al analizar la vista previa de %1$s : %2$s" "Vista previa de imagen de tarjeta para %1$s" Artículo - Nuevo canal Nombre del canal Mi grupo genial URL de imagen Url de imagen (opcional) Descripción - No se encontró la descripción "Quiénes somos…" ¿Qué estás pensando? Escribir un mensaje… @@ -197,42 +184,25 @@ Crear Cambiar nombre Cancelar - Error al subir la imagen - Dirección del relé - Publicaciones - Bytes Error Errores Porcentaje de conexiones exitosas al relé - El número de errores de conexión en esta sesión - Tus noticias - Feed de mensajes privados - Feed del chat público - Feed global - Feed de búsqueda Buscar y agregar usuario - Agregar un usuario Agregar un relé - Nombre - Nombre (para @etiquetar) Mi nombre de @etiqueta Nombre para mostrar Mi nombre para mostrar Avestruz Maravillosa ¡Te damos la bienvenida, Avestruz! Nombre de usuario - Mi nombre de usuario Quién soy URL del avatar URL del banner URL del sitio web Pronombres - Dirección de Lightning - URL de Lightning (obsoleta) Los relés de origen pueden ser obsoletos Aviso de relé obsoleto Guardar en el teléfono - Guardar en la galería Imagen guardada en la galería Comenzó la descarga del video… Comenzó la descarga del contenido multimedia… @@ -248,15 +218,12 @@ Subir archivo Tomar una foto Grabar un mensaje - Grabar un mensaje Haz clic y mantén presionado para grabar un mensaje Volver a grabar Grabación Grabando %1$s - Subiendo… Error de carga Error al cargar el mensaje de voz - Estado inesperado de carga NIP-95 aún no es compatible con mensajes de voz Error al cargar voz: %1$s Ninguna @@ -268,8 +235,6 @@ El usuario no tiene configurada una dirección de Lightning para recibir sats "responde aquí… " En este chat - Copia el ID de la nota al portapapeles para compartirla en Nostr - Copiar el ID del canal (nota) al portapapeles Edita los metadatos del canal Unirse Conocidos @@ -281,7 +246,6 @@ Respuestas Tuyo Galería - "Seguidos" "Reportes" "%1$s informes" Más opciones @@ -289,11 +253,8 @@ Sitio web Dirección de Lightning Copia el ID Nsec (tu contraseña) en el portapapeles para hacer una copia de seguridad - Copiar la clave secreta al portapapeles Mostrar código QR de clave privada Mostrar código QR de clave privada cifrada - Copia la clave pública al portapapeles para compartirla - Copiar la clave pública (NPub) al portapapeles Enviar un mensaje directo Edita los metadatos del usuario Seguir @@ -322,8 +283,6 @@ ¿Cómo debemos llamarte? ¿No tienes una cuenta de Nostr? ¿Ya tienes una cuenta de Nostr? - Crear una cuenta nueva - Generar una clave nueva Cargando feed Cargando cuenta encriptado @@ -339,13 +298,7 @@ segundos El feed está vacío. Actualizar - creado - con la descripción de - e imagen - cambió el nombre del chat a Nuevo perfil de chat: - descripción a - e imagen a Salir Dejar de seguir Canal creado @@ -382,7 +335,6 @@ Dirección de Nostr nunca ahora - segundos h m d @@ -390,7 +342,6 @@ Groserías o lenguaje que incita al odio Reportar lenguaje que incita al odio Reportar desnudos o pornografía - otros Marcar todos los conocidos como leídos Marcar todos los nuevos como leídos Marcar todos como leídos @@ -411,8 +362,6 @@ Error de autenticación El sistema biométrico no pudo autenticar al propietario de este teléfono El sistema biométrico no pudo autenticar al propietario de este teléfono. Error: %1$s - Error - "Creado por %1$s" "Imagen de premio de insignia por %1$s" \"Imagen de premio de insignia Recibiste un nuevo premio de insignia @@ -420,7 +369,6 @@ Texto de la nota copiado al portapapeles \@npub del autor copiado al portapapeles ID de la nota (@note1) copiado al portapapeles - Seleccionar texto "<No se pudo desencriptar el mensaje privado>\n\nTe citaron en una conversación privada o encriptada entre %1$s y %2$s." Agregar cuenta nueva Cuentas @@ -432,8 +380,6 @@ Seleccionar cuenta Agregar cuenta nueva Cuenta activa - Tiene clave privada - Solo de lectura, sin clave privada Volver Seleccionar Compartir enlace del navegador @@ -454,14 +400,12 @@ Silenciar hilo Reactivar hilo Reportar - Eliminar No mostrar de nuevo Spam o estafas Groserías o conducta que incita al odio Suplantación de identidad malintencionada Desnudez o contenido gráfico Comportamiento ilegal - Malware Si bloqueas a un usuario, se ocultará su contenido en tu app. Tus notas todavía son visibles públicamente, incluso para las personas que bloquees. Los usuarios bloqueados aparecen en la pantalla \"Filtros de seguridad\". Reportar abuso @@ -489,7 +433,6 @@ Elegir hora programada Programación para… Se publica en %1$s - Se venció hace %1$s Hora Programar publicación Cancelar programación @@ -564,7 +507,6 @@ Autor Solicitudes Aprobaciones - Ninguna comunidad coincide con este filtro. Reglas verificables (opcional) Publica un documento de reglas legibles automáticamente (NIP-9B) junto con la comunidad. Los clientes que lo admiten bloquean las publicaciones que no coinciden antes de enviarlas. Guardar límites @@ -629,7 +571,6 @@ Transmitir en vivo… Transmisión fallida: %1$s Error al silenciar: %1$s - Se requiere acceso al micrófono para hablar en esta sala. Sin permisos Nests Mantiene la reproducción de audio mientras una sala está abierta. @@ -640,7 +581,6 @@ Unirse a nest Anfitrión Abrir - Chat reciente Nadie se encuentra en la sala en este momento. %1$d escuchando Anfitrión @@ -668,8 +608,6 @@ Público Manos Todavía no hay nadie en el público. - Enviar - Di algo… Aún no hay mensajes. Sé el primero en chatear. Reaccionar Editar sala @@ -686,7 +624,6 @@ Elige en qué servidores host de MoQ quieres que Amethyst publique tus nests. La primera entrada es predeterminada cuando creas un nuevo espacio. Tus servidores Guardado como un evento reemplazable para que otros clientes puedan leer tus preferencias. - Agregar un servidor de nest URL del relé (WebTransport) URL de autenticación (generación de JWT) Agregar @@ -707,9 +644,6 @@ Eliminar lista de marcadores Ver publicaciones Ver artículos - Ver enlaces - Ver hashtags - Aún no tienes ninguna lista de marcadores. Toca el nuevo botón de abajo para crear una. Publicaciones privadas Publicaciones privadas(%1$s) Publicaciones públicas @@ -720,16 +654,6 @@ Los metadatos de las listas de marcadores son visibles para cualquier usuario de Nostr. Solo los miembros privados están cifrados. Mover a público Mover a privado - Servicio de conexión a billetera - Autoriza a un secreto de Nostr para pagar zaps sin salir de la app. Mantén el secreto seguro y usa un relé privado si es posible. - Clave pública de conexión a billetera - Relé de conexión a billetera - Secreto de conexión a billetera - Clave secreta de conexión a billetera - clave privada nsec / hex - Conectada - No conectada - Avanzado: introduce manualmente los detalles de la conexión Cantidad de zap rápido Aparece al presionar el botón de zap. Toca una cantidad para eliminarla. Si la dejas vacía, se abrirá el cuadro de diálogo para introducir una cantidad cada vez. Privacidad de zaps @@ -737,14 +661,8 @@ Conectar billetera Ver fuente de relés Destinar cantidad en sats - Publicar encuesta - Campos obligatorios: - Destinatarios de zaps - Descripción de encuesta principal… - Opción Opción %s Descripción de opción de encuesta - Campos opcionales: Zap mínimo Zap máximo Consenso @@ -753,11 +671,8 @@ Opción múltiple Fecha y hora de cierre de la encuesta La encuesta se cierra en %1$s - Cerrar después de - días No se puede votar Encuesta cerrada para votos nuevos - Monto del zap Solo se permite un voto por usuario en este tipo de encuesta "Buscando evento %1$s" Enviar zap @@ -791,17 +706,12 @@ No zap No hay rastro en Nostr, solo en Lightning Anónimo - Publicar como una nueva identidad temporal. Tu cuenta no quedará vinculada a esta respuesta. - Esta respuesta se publicará desde una nueva identidad anónima Servidor de archivos Elegir un servidor para subir este archivo - Dirección o @usuario de Lightning Servidores multimedia Configura tus servidores preferidos para subir contenido multimedia. - No tienes ningún servidor NIP-96 configurado. Puedes usar la lista de Amethyst o agregar uno de la lista a continuación ↓ No tienes ningún servidor Blossom configurado. Puedes usar la lista de Amethyst o agregar uno de la lista a continuación ↓ Servidores multimedia recomendados - Servidores multimedia integrados Lista predeterminada de Amethyst. Puedes agregarlos individualmente o añadir la lista. Usar lista predeterminada Agregar servidor multimedia @@ -818,50 +728,21 @@ Cifrando Listo Error - Tus relés (NIP-95) - Los archivos están alojados en tus relés. Nuevo NIP: comprueba si son compatibles. Opciones de privacidad - Configuración de Tor/Orbot - Conéctate a través de tu configuración de Orbot Ajustar Configuración de Tor - ¿Desconectarse de tu Orbot/Tor? - Los datos se transferirán de inmediato en la red normal Sí No - Lista de seguidos Todos los seguidos - Siguiendo a través de proxy A mi alrededor Global Lista de silenciados Conjuntos de seguimiento - Marcadores etiquetados - Marcadores generales - Público - Privado - Mixto - Al parecer, aún no tienes ningún conjunto de seguimiento. - \nToca abajo para actualizar o toca los botones de agregar para crear uno nuevo. - Agregar autor a conjunto de seguimiento Agregar o quitar usuario de las listas, o crear una nueva lista con este usuario. - Miembros privados - Perfiles públicos - Perfiles privados - miembro - miembros - Sin miembros Vacío - %1$s no se encuentra en esta lista %1$s no es miembro Tus listas y %1$s - Tus conjuntos de seguimiento - No se han encontrado conjuntos de seguimiento, o no tienes ningún conjunto de seguimiento. Toca abajo para actualizar o utiliza el menú para crear uno. - Hubo un problema al recuperar: %1$s - Crear nueva lista - Nueva lista con membresía de %1$s - Crea un nuevo conjunto de seguimiento y añade a %1$s como miembro de %2$s. Nueva lista de seguimiento Nuevo paquete de seguimiento Copiar/Clonar lista de seguimiento @@ -881,14 +762,6 @@ Estás cambiando el nombre de a.. El puerto predeterminado es 9050 - ## Conéctate a través de Tor con Orbot - \n\n1. Instala [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android). - \n2. Inicia Orbot. - \n3. En Orbot, comprueba el puerto Socks. La opción predeterminada es 9050. - \n4. Si es necesario, cambia el puerto en Orbot. - \n5. Configura el puerto Socks en la pantalla. - \n6. Presiona y activa el botón para usar Orbot como proxy. - Puerto Socks de Orbot Motor de Tor activo Usar la versión interna u Orbot @@ -930,8 +803,6 @@ Oculta tu IP en todas las conexiones Crea el tuyo Número de puerto inválido - Usar Orbot - Desconectar Tor/Orbot Mensajes privados Te notifica cuando llega un mensaje privado Zaps recibidos @@ -963,23 +834,12 @@ Bluetooth Llamada de voz Notificar: - Unirse a la conversación - ID de usuario o grupo - npub, nevent o hexadecimal - Crear - Unirse Hoy Advertencia de contenido Esta publicación incluye contenido delicado que algunas personas pueden considerar ofensivo o perturbador. - Ocultar siempre el contenido delicado - Mostrar siempre el contenido delicado - Mostrar siempre advertencias sobre contenido Ocultar Mostrar Advertir - Recomendaciones: - Filtrar el spam de desconocidos - Avisar cuando las publicaciones tengan reportes de tus seguidos Filtrar spam Oculta las publicaciones de desconocidos que sean exactamente iguales 5 o más veces. Advertir sobre reportes @@ -996,18 +856,15 @@ Relé de escritura La cantidad en bytes que se enviaron a este relé, incluyendo filtros y eventos La cantidad en bytes que se recibieron de este relé, incluyendo filtros y eventos - Se produjo un error al intentar obtener información sobre el relé de %1$s Propietario Versión Software Contacto NIP compatibles Grasps compatibles - Comisiones de admisión Admisión Suscripción Publicación - Pagos %1$s URL de pagos Público objetivo Políticas y enlaces @@ -1015,7 +872,6 @@ Limitaciones Países Idiomas - Etiquetas Temas Todos los países Todos los idiomas @@ -1028,48 +884,34 @@ Abrir Leer Escribir - RTT Red Tipo NIP compatibles Requisitos - Última comprobación %1$d ms Kinds aceptados Suscripciones activas - Eventos de outbox pendientes Suscripciones REQ (%1$d) Suscripciones COUNT (%1$d) - Longitud del mensaje - Suscripciones - Filtros - Longitud del ID de la suscripción Prefijo mínimo Etiquetas de evento máximas - Longitud del contenido Retención de eventos Tamaño de contenido Conectividad Control de acceso PoW mínima - Autenticación Se requiere autorización - Pago Se requiere pago Longitud máxima del mensaje Suscripciones máximas Filtros máximos por suscripción Límite máximo (devolución de eventos) - Límite predeterminado (devolución de eventos) Longitud máxima de subID Token de Cashu Canjear - Enviar a billetera de zaps - Abrir en billetera de Cashu Copiar token Abrir en otra app La dirección de Lightning no está configurada - Token copiado al portapapeles EN VIVO FUERA DE LÍNEA TERMINÓ @@ -1109,7 +951,6 @@ negentropy, …) stay searchable in every locale and aren't sent to translators. --> Zona peligrosa Siempre - Solo Wi-Fi WiFi sin medición Nunca Completo @@ -1133,7 +974,6 @@ Elegir el estilo de publicación Estilo de galería de perfil Elige el estilo de galería - Cargar imagen Spammers Silenciado. Hacer clic para reactivar el sonido. Sonido activado. Hacer clic para silenciar. @@ -1144,28 +984,19 @@ La dirección de Nostr se verificó No se pudo verificar la dirección de Nostr Verificando dirección de Nostr - Seleccionar o deseleccionar todo Predeterminados Restablecer valores predeterminados - Seleccionar un relé para continuar - Reenviar zaps a: - Los clientes compatibles reenviarán los zaps a la dirección de Lightning o al perfil de usuario indicados a continuación en lugar de a los tuyos. Revelar ubicación como Agrega un Geohash de tu ubicación al mensaje. El público sabrá que te encuentras a menos de 5 km (3 mi) de la ubicación actual. Publicación con ubicación exclusiva Solo los seguidores de la ubicación la verán. Tus seguidores generales no la verán. Publicación exclusiva de hashtag - Solo los seguidores del hashtag la verán. Tus seguidores generales no la verán. Cargando ubicación Sin permisos de ubicación Agrega una advertencia de contenido delicado antes de mostrarlo. Esto es ideal para cualquier contenido NSFW o que a algunas personas les pueda resultar ofensivo o perturbador. Motivo (opcional) - Función nueva - La activación de este modo requiere que Amethyst envíe un mensaje NIP-17 (mensajes directos sellados, de grupo y “GiftWrapped\"). NIP-17 es nuevo y la mayoría de los clientes aún no lo han implementado. Comprueba que el destinatario use un cliente compatible. - Activar Público Nuevo grupo público o privado - Relé Privado Para Asunto @@ -1177,14 +1008,12 @@ Explicación para los miembros Cambio de nombre para los nuevos objetivos. Pegar desde el portapapeles - Conectar a nueva billetera NWC Billetera no encontrada Para la interfaz de la aplicación Tema oscuro, claro o del sistema Cargar automáticamente imágenes y GIF Reproducir automáticamente videos y GIF Mostrar vistas previas de URL - Cuándo cargar imágenes Copiar stack Copiar al portapapeles Copiar npub al portapapeles @@ -1195,46 +1024,24 @@ Contenido multimedia agregado Contenido multimedia agregado a la galería del perfil Creado - Reglas Iniciar sesión con Amber Actualiza tu estado - Error al analizar el mensaje de error Los votos se calculan según la cantidad de zaps. Puedes establecer una cantidad mínima para evitar spammers y una máxima para que los zappers grandes no puedan dominar la encuesta. Usa la misma cantidad en ambos campos para asegurarte de que cada voto tenga el mismo valor. Déjalos vacíos para aceptar cualquier cantidad. No se pudo enviar el zap Mensaje para el usuario Mensaje %1$s OK - No se pudo llegar a %1$s: %2$s - Error al ensamblar la url NIP-11 para %1$s: %2$s - No se pudo contactar %1$s: %2$s - Error al analizar la respuesta de %1$s: %2$s - El relé rechazó la solicitud %1$s: %2$s - No se pudo llegar a %1$s: %2$s - Error al analizar el resultado de %1$s: %2$s - %1$s falló con el código %2$s - Activo para: - Inicio - Mensajes directos - Chats - Global - Búsqueda Dividir y reenviar zaps Los clientes compatibles dividirán y reenviarán los zaps a los usuarios que se agreguen aquí en lugar de a ti. Buscar y agregar usuario Nombre de usuario o para mostrar Lightning no está configurado El usuario %1$s no tiene una dirección de Lightning configurada para recibir sats. - Porcentaje - 25 - Dividir zaps con - Reenviar zaps a - No se encontraron billeteras de Lightning Pagado Billetera %1$s Error al abrir la aplicación firmante No se pudo encontrar la aplicación firmante. Comprueba si no se desinstaló la aplicación. Solicitud de firma rechazada - Solicitud de firma rechazada Asegúrate de que la aplicación firmante haya autorizado esta transacción. No se encontraron billeteras para pagar una factura de Lightning (error: %1$s). Instala una billetera de Lightning para usar zaps. No se encontraron billeteras para pagar una factura de Lightning. Instala una billetera de Lightning para usar zaps. @@ -1245,36 +1052,19 @@ Seleccionar una opción No se pudo pagar la factura No se pudo retirar - No se pudo configurar Wallet Connect - Error al analizar la cadena de conexión NIP-47. Comprueba si esto es correcto con el proveedor de la billetera: %1$s. Error: %2$s - Error al analizar la cadena de conexión NIP-47. Comprueba si esto es correcto con el proveedor de la billetera: %1$s. No se pudo canjear Cashu La Mint proporcionó el siguiente mensaje de error: %1$s - Los tokens de Cashu ya se gastaron. Cashu recibido Se enviaron %1$s sats a tu billetera (comisión: %2$s sats). No se encontró ninguna billetera de Cashu compatible en el sistema No se puede obtener la factura de los servidores del destinatario El proveedor de conexión de billetera devolvió el siguiente error: %1$s - No se pudo conectar a Tor - No está disponible la descarga de documentos del relé No se pudo ensamblar la LNUrl desde la dirección de Lightning \"%1$s\". Comprueba la configuración del usuario. - El servicio de Lightning del destinatario en %1$s no está disponible. Se calculó a partir de la dirección de Lightning \"%2$s\". Error: %3$s. Comprueba si el servidor está activo y si la dirección de Lightning es correcta. - No se pudo resolver %1$s. Comprueba si tienes conexión, si el servidor está activo y si la dirección de Lightning \"%2$s\" es correcta. - No se pudo resolver %1$s. Comprueba si tienes conexión, si el servidor está activo y si la dirección de Lightning \"%2$s\" es correcta..\n\nLa excepción fue: %3$s - No se pudo obtener la factura de %1$s No se pudo obtener la factura de %1$s: %2$s - Error al analizar JSON desde la dirección de Lightning. Comprueba la configuración de Lightning del usuario. Error al analizar JSON desde %1$s. Comprueba la configuración de Lightning del usuario. - No se encontró la URL de devolución de llamada en la configuración del servidor de la dirección de Lightning del usuario. No se encontró la URL de devolución de llamada en la respuesta de %1$s. - Error al analizar JSON desde la recuperación de factura de la dirección de Lightning. Comprueba la configuración de Lightning del usuario. - Error al analizar JSON desde la recuperación de factura de %1$s. Comprueba la configuración de Lightning del usuario. Cantidad de factura incorrecta (%1$s sats) de %2$s. Debería haber sido %3$s. No se pudo crear una factura de Lightning antes de enviar el zap. La billetera de Lightning del destinatario envió el siguiente error: %1$s. - No se pudo crear una factura de Lightning. Mensaje de %1$s: %2$s. - No se pudo crear una factura de Lightning antes de enviar el zap. No se encontró el elemento pr en el JSON resultante. - No se pudo crear una factura de Lightning desde %1$s: no se encontró el elemento pr en el JSON resultante. Usuario de solo lectura No hay reacciones configuradas Seleccionar una aplicación UnifiedPush @@ -1292,13 +1082,11 @@ Envía un mensaje al vendedor Hola, %1$s, ¿esto todavía está disponible? Hola, ¿esto todavía está disponible? - Vender un artículo Título iPhone 13 Estado Categoría Precio (en sats) - 1000 Ubicación Ciudad, estado, país. Nuevo @@ -1327,20 +1115,13 @@ Otros Error al subir contenido multimedia No se pudo abrir el archivo comprimido - Error al comprimir el contenido multimedia: %1$s Error de subida: %1$s El servidor no proporcionó una URL después de la subida No se pudo descargar el contenido subido desde el servidor No se pudo comprobar el archivo descargado después de subir: %1$s - No se pudo preparar el archivo local para subir: %1$s Error al subir a %1$s: %2$s - Error al subir: %1$s Error al eliminar: %1$s El contenido multimedia es demasiado grande para NIP-95 - No se puede subir imagen en miniatura - No se pudo preparar la información del encabezado: %1$s - Compresión cancelada - La compresión no pudo devolver un archivo Muchos servidores no aceptan archivos cifrados en cuentas gratuitas. Puedes volver a intentarlo sin cifrado. Reintentar sin cifrado Advertencia: Sin cifrado, cualquiera con el enlace del archivo puede ver el contenido. @@ -1354,34 +1135,25 @@ Mejor calidad en tamaños de archivos más pequeños, pero no todos los dispositivos admiten la reproducción H.265. Editar borrador Iniciar sesión con código QR - Ruta Inicio - Buscar Descubrir Mensajes Notificaciones - Global Cortos Ajedrez Billetera - Saldo Enviar Recibir Transacciones - No hay billetera conectada - Configure una conexión de Nostr Wallet Connect (NWC) en la configuración de zaps para usar la billetera. - Configurar billetera sats Pegar una factura BOLT-11 Pagar - Filtros de seguridad Importar seguidos Nueva publicación Nuevos cortos: imágenes o videos Nueva nota comunitaria Nuevo producto - Nueva publicación geoexclusiva Abrir todas las reacciones a esta publicación Cerrar todas las reacciones a esta publicación Responder @@ -1407,29 +1179,22 @@ Relé %1$s Ampliar lista de relés Opciones de notas - Selector de lista de relés Encuesta Desactivar encuesta Factura de Bitcoin Cancelar factura de Bitcoin - Cancelar la venta de un artículo Recaudación de zaps Cancelar zapraiser Ubicación Eliminar ubicación - Divisiones de zaps - Cancelar división de zap Agregar advertencia de contenido Eliminar advertencia de contenido Mostrar npub como código QR Dirección inválida Amethyst recibió un URI para abrir pero era inválido: %1$s Relés de buzón de entrada para mensajes directos - Relés: %1$s - Usando relés normales Configura tus relés de buzón de entrada privados Esta configuración permite que todo el mundo sepa qué relés usar cuando te envíen mensajes. Sin ellos, es posible que no recibas algunos mensajes. - Algunas buenas opciones son:\n - inbox.nostr.wine (de pago)\n - you.nostr1.com (relés personales; de pago) Algunas buenas opciones son:\n - auth.nostr1.com (free)\n - inbox.nostr.wine (paid)\n - relay.0xchat.com (free) Inserta entre 1 y 3 relés para que te sirvan de buzón de entrada privado. Los relés del buzón de entrada para mensajes directos deberían aceptar cualquier mensaje de cualquier persona, pero solo te permiten descargarlos. Configurar ahora @@ -1438,7 +1203,6 @@ La creación de una lista de relés específicamente diseñada para la búsqueda y el etiquetado de usuarios mejorará estos resultados. Inserta entre 1 y 3 relés para usarlos al buscar contenido o etiquetar usuarios. Asegúrate de que los relés que elijas implementen NIP-50. Algunas buenas opciones son: \n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com - Subida de mensaje directo Configuración de relés Relés de inicio públicos Este tipo de relé almacena todo tu contenido. Amethyst enviará tus publicaciones aquí y otros usarán estos relés para encontrar tu contenido. Inserta entre 1 y 3 relés. Pueden ser personales, de pago o públicos. @@ -1448,12 +1212,8 @@ Inserta entre 1 y 3 relés para que te sirvan de buzón de entrada privado. Otros usarán estos relés para enviarte mensajes directos. Los relés del buzón de entrada para mensajes directos deberían aceptar cualquier mensaje de cualquier persona, pero solo te permiten descargarlos. Algunas buenas opciones son:\n - inbox.nostr.wine (de pago)\n - you.nostr1.com (relés personales; de pago) Relés privados Inserta entre 1 y 3 relés para almacenar eventos que nadie más pueda ver, como los borradores o la configuración de la app. Lo ideal es que estos relés sean locales o requieran autenticación antes de descargar el contenido de cada usuario. - Relés generales - Amethyst usa estos relés para descargar publicaciones por ti. Relés conectados Lista actual de relés en uso - Relés recomendados - Agrega los siguientes relés a la lista de relés generales para recibir publicaciones de los usuarios de la lista. Relés de búsqueda Lista de relés que se usarán al buscar contenido o usuarios. El etiquetado y la búsqueda no funcionarán si no hay opciones disponibles. Asegúrate de que implementen NIP-50. Relés locales @@ -1480,11 +1240,8 @@ Esta versión fue posible gracias a: Versión %1$s ¡Gracias! - Límite máximo Escrituras restringidas Bifurcación de - BIFURCACIÓN - Repositorio Git: %1$s Web: Clon: OTS: %1$s @@ -1492,20 +1249,13 @@ Hay prueba de que esta publicación se firmó en algún momento antes de %1$s. La prueba se marcó en la cadena de bloques de Bitcoin en esa fecha y hora. Editar publicación Propuesta para mejorar una publicación - Resumen de cambios - Correcciones rápidas… Aceptar la sugerencia Iniciar video en una ventana emergente Descargar - Letra activada - Letra desactivada - Mensaje sellado desactivado. Haz clic para activar el mensaje sellado. - Mensaje sellado activado. Haz clic para desactivar el mensaje sellado. Enviar Reproducir nombre de usuario como audio Marcador Escanear código QR - Ir al proveedor externo de billeteras Alby No es posible responder a un borrador de nota No es posible citar un borrador de nota No es posible reaccionar a un borrador de nota @@ -1546,28 +1296,23 @@ Almacenamiento insuficiente: el servidor no dispone de almacenamiento suficiente para procesar correctamente la solicitud. Bucle detectado: el servidor detecta un bucle infinito al procesar la solicitud. Autenticación de red requerida: el cliente debe estar autenticado para acceder a la red. - Servidores NIP-96 - Agrega tantos servidores como quieras. Puedes elegir cuál usar más tarde al subir tu foto. Servidores Blossom Agrega tantos servidores como quieras. Puedes elegir cuál usar más tarde al subir tu foto. Agregar servidor NIP-96 Agregar un servidor Blossom Borrar todo ¿Seguro quieres eliminar todos los borradores? - Stack: Archivo torrent Descargar Error al abrir el archivo No hay aplicaciones torrent instaladas para abrir y descargar el archivo. El evento no tiene suficiente información para crear un enlace magnético - Mis listas/conjuntos Selecciona una lista para filtrar el feed Cerrar sesión al bloquear dispositivo Mensaje privado Mensaje público Relé de chat - Relé al que todos los usuarios de este chat se conectan Compartir imagen… Buscar hashtag: #%1$s No traducir del @@ -1583,4 +1328,10 @@ + + El servicio de Lightning del destinatario en %1$s no está disponible. Se calculó a partir de la dirección de Lightning \"%2$s\". Error: %3$s. Comprueba si el servidor está activo y si la dirección de Lightning es correcta. + No se pudo resolver %1$s. Comprueba si tienes conexión, si el servidor está activo y si la dirección de Lightning \"%2$s\" es correcta..\n\nLa excepción fue: %3$s + Error al analizar JSON desde la recuperación de factura de %1$s. Comprueba la configuración de Lightning del usuario. + No se pudo crear una factura de Lightning. Mensaje de %1$s: %2$s. + No se pudo crear una factura de Lightning desde %1$s: no se encontró el elemento pr en el JSON resultante. diff --git a/amethyst/src/main/res/values-es/strings.xml b/amethyst/src/main/res/values-es/strings.xml index 6a985205a4..bbbfb8b8d1 100644 --- a/amethyst/src/main/res/values-es/strings.xml +++ b/amethyst/src/main/res/values-es/strings.xml @@ -6,15 +6,12 @@ Clave secreta (nsec) copiada al portapapeles Copiar mi clave secreta Autenticación fallida - Error - Credo por %1$s Imagen del Badge para %1$s Has recibido un nuevo Badge Badge otorgado a Texto de nota copiado al portapapeles \@npub del autor copiado al portapapeles ID de nota copiada (@note1) al portapapeles - Seleccionar texto Apunta al código QR Mostrar el QR Imagen de Perfil @@ -30,8 +27,6 @@ Spam Suplantación de identidad Comportamiento ilegal - Desconocido - Icono del transmisor Autor desconocido Copiar texto Copiar PubKey del usuario @@ -40,7 +35,6 @@ Bloquear y ocultar usuario Reportar Spam / Estafa Reportar suplantación de identidad - Reportar contenido explícito Reportar comportamiento ilegal Inicie sesión con una clave privada para poder responder Inicie sesión con una clave privada para poder publicar posts @@ -48,7 +42,6 @@ Falta la configuración de Zaps por defecto. Mantén pulsado unos segundos para cambiarla Inicie sesión con una clave privada para poder enviar Zaps Zaps - Total vistas Impulsar boosted Cita @@ -56,7 +49,6 @@ Añadir "respondiendo a " " y " - "en canal " Banner de perfil " Siguiendo" " Seguidores" @@ -71,9 +63,7 @@ ¡Muchas gracias! Cantidad en Sats Enviar Sats - "Error al analizar la vista previa de %1$s : %2$s" "Imagen de vista previa para %1$s" - Nuevo canal Nombre del canal Mi grupo genial URL de imagen @@ -84,34 +74,20 @@ Guardar Crear Cancelar - No se pudo cargar la imagen - Dirección del transmisor - Publicaciones Errores - Tus noticias - Fuente de mensajes privados - Fuente de chat público - Fuente global - Fuente de búsqueda Anadir transmisor Nombre para mostrar Mi nombre para mostrar Nombre de usuario - Mi nombre de usuario Sobre mí URL del avatar URL del banner Dirección web - Dirección LN - Dirección LN (antiguo) Imagen guardada en la galería Error al guardar la imagen Cargar imagen - Cargando… El usuario no tiene una configuración de dirección Lightning para recibir sats "responde aquí… " - Copia la nota-ID para compartir - Copia la nota-ID del canal Edita los metadatos del canal Unirse Conocidos @@ -121,16 +97,12 @@ Conversaciones Notas Respuestas - Siguiendo Reportes Más opciones " Retransmisores" Sitio web Dirección Lightning Copia la ID de Nsec (su contraseña) en el portapapeles para hacer una copia de seguridad - Copiar clave privada al portapapeles - Copia la clave pública al portapapeles para compartir - Copie la clave pública (NPub) al portapapeles Enviar un mensaje directo Edita los metadatos del usuario Seguir @@ -149,18 +121,11 @@ Se requiere la aceptación de los términos Se requiere la clave Acceso - Generar una nueva clave Cargando el tablón… "Error al cargar las respuestas: " Intentar otra vez Tablón vacío Actualizar - Creado - con descripción de - y foto - cambió el nombre del chat a - descripción a - e imagen a Dejar Dejar de seguir Canal creado @@ -183,7 +148,6 @@ Blasfemias / Discurso de odio Denuncia discurso de odio Reportar desnudos / Porno - otros Selecciona Compartir enlace del navegador Compartir diff --git a/amethyst/src/main/res/values-fa-rIR/strings.xml b/amethyst/src/main/res/values-fa-rIR/strings.xml index fe33baf38b..0a8279c039 100644 --- a/amethyst/src/main/res/values-fa-rIR/strings.xml +++ b/amethyst/src/main/res/values-fa-rIR/strings.xml @@ -20,8 +20,6 @@ جعل هویت رفتار ناهنجار سایر - ناشناس - آیکن رله نویسنده ناشناس کپی متن کپی شناسه نویسنده @@ -35,12 +33,9 @@ گزارش اسپم/کلاهبرداری گزارش جعل هویت - گزارش محتوای نامناسب گزارش رفتار ناهنجار گزارش بدافزار - گزارش مود بدافزار - مود با کلید خصوصی وارد شوید تا بتوانید پاسخ دهید با کلید خصوصی وارد شوید تا بتوانید یادداشت را بازنشر کنید با کلید خصوصی وارد شوید تا بتوانید یادداشت را لایک کنید @@ -51,7 +46,6 @@ دارید از کلید عمومی استفاده می کنید و با کلید عمومی فقط می توان خواند. با کلید خصوصی وارد شوید تا بتوانید کلمه یا جمله ای را پنهان کنید. دارید از کلید عمومی استفاده می کنید و با کلید عمومی فقط می توان خواند. با کلید خصوصی وارد شوید تا بتوانید کلمه یا جمله ای را آشکار کنید زپ - دیدن تعداد بازنشر بازنشر شده ویرایش شده @@ -64,9 +58,7 @@ افزودن " پاسخ به" " و " - "در کانال " بنر پروفایل - پرداخت موفق خطا در تفسیر پیغام خطا "دنبال شونده" "دنبال کننده" @@ -88,9 +80,7 @@ پیشوند نمایان 😎 افزودن به یادداشت - " %1$s : %2$s خطا در تبدیل" "%1$s پیش نمایش تصویر کارت برای" - کانال جدید نام کانال گروه باحال من آدرس تصویر @@ -102,33 +92,18 @@ ذخیره ساختن لغو - تصویر بارگذاری نشد - آدرس رله - یادداشت ها - بایت خطاها - تعداد خطاهای اتصال در این نوبت - خبرنامه اصلی - پیام خصوصی - گفتگوی عمومی - خبرنامه همگانی - جستجو در خبرنامه افزودن رله - نام نمایش نام نام من استریچ باحالیان خوش آمدی استریچ! نام کاربری - نام کاربری من درباره من آدرس آواتار آدرس بنر آدری وبسایت ضمیرها - آدرس لایتنینگ - آدرس لایتنینگ(نقل شده) - در گالری ذخیره کن تصویر در گالری ذخیره شد بارگیری ویدئو آغاز شد… بارگیری رسانه آغاز شد… @@ -136,11 +111,8 @@ ویدئو در گالری گوشی ذخیره شد ویدئو ذخیره نشد بارگذاری تصویر - …در حال بارگذاری این کاربر آدرس لایتنینگ برای دریافت ساتوشی تنظیم نکرده است "…اینجا پاسخ دهید " - شناسه یادداشت را برای اشتراک گذاری در کلیپبورد ذخیره می کند - ذخیره شناسه کانال در کلیپبورد متادیتای کانال را ذخیره می کند پیوستن شناس @@ -152,18 +124,14 @@ پاسخ ها مال شما گالری - "دنبال شوندگان" "گزارش ها" انتخاب های بیشتر "رله ها" وبسایت آدرس لایتنینگ شناسه کلید خصوصی (پسوردتان) را در کلیپبورد کپی می کند( - کپی کردن کلید خصوصی در کلیپبورد نمایش کد QR کلید خصوصی نمایش کد QR کلید خصوصی رمزنگاری شده - کلید عمومی را برای اشتراک گذاری در کلیپبورد ذخیره می کند - کپی کردن کلید عمومی در کلیپبورد ارسال پیام مستقیم متادیتای کاربر را ویرایش می کند دنبال کردن @@ -192,8 +160,6 @@ شما را چی صدا بزنیم؟ حساب کاربری ناستر ندارید؟ از قبل حساب کاربری ناستر دارید؟ - ایجاد حساب کاربری جدید - ساختن جفت کلید جدید در حال بارگیری خبرنامه بارگذاری حساب کاربری @@ -203,13 +169,7 @@ هنوز هیچ اعلانی نیست. خبرنامه خالیست تازه‌سازی - ساخته شد - با توصیف - و تصویر - نام گفتگو تغییر کرد به نمایه جدید گفتگو: - تصویر - و تصویر به ترک کردن دنبال نکردن کانال ساخته شد @@ -242,7 +202,6 @@ ناسزا / نفرت پراکنی گزارش نفرت پراکنی گزارش برهنگی / پورن - سایر همه شناس ها خوانده شده کن همه جدیدها را خوانده شده کن همه را خوانده شده کن @@ -262,23 +221,18 @@ احراز هویت انجام نشد مشخصات بیومتریک نتوانست مالک این تلفن را احراز هویت کند مشخصات بیومتریک نتوانست مالک این تلفن را احراز هویت کند. خطا: %1$s - خطا - "ساخته شده توسط %1$s" "تصویر مدال پاداش برای %1$s" یک مدال پاداش دریافت کردید مدال پاداش داده شد به یادداشت در کلیپبورد کپی شد \@npubنویسنده در کلیپبورد کپی شد (@note1)شناسه یادداشت در کلیپبورد کپی شد - انتخاب متن "<پیام خصوصی رمزگشایی نشد>\\n\nدر یک پیام خصوصی/رمزنگاری شده بین %1$s و %2$s نام شما آمده بود." افزودن حساب کاربری جدید حساب های کاربری انتخاب حساب کارگری افزودن حساب کاربری جدید حساب کاربری فعال - کلید خصوصی دارد - فقط خواندن، کلید خصوصی ندارد بازگشت انتخاب اشتراک گذاری لینک مرورگر @@ -296,14 +250,12 @@ حذف بلاک گزارش - حذف دوباره نشان نده اسپم یا کلاهبرداری محتوای نفرت پراکنی یا ناسزا جعل هویت بدخواهانه محتوای برهنگی یا نمایان رفتار ناهنجار - نرم‌افزار خرابکار بلاک کردن کاربر محتوای ایشان را در اپ شما پنهان می کند. یادداشت های شما همچنان بطور عمومی دیده می شوند که شامل کاربران بلاک شده توسط شما نیز هست. کاربران بلاک شده در صفحه فیلترهای ایمنی فهرست می شوند. گزارش سواستفاده @@ -323,30 +275,15 @@ افزودن به علامت گذاشته های عمومی برداشتن از علامت گذاشته های خصوصی برداشتن از علامت گذاشته های خصوصی - خدمات اتصال به کیف پول - به رمز ناستر اجازه بده زپ را بدون ترک اپ برداخت کند. این رمز را امن نگه دارید و درصورت امکان از رله خصوصی استفاده کنید - کلید عمومی اتصال به کیف پول - رله اتصال به کیف پول - رمز اتصال به کیف پول - نمایش کلید خصوصی - nsec / hex کلید خصوصی مبلغ وثیقه به ساتوشی - ارسال نظرسنجی - قسمت های الزامی: - دریافت کنندگان زپ - توضیحات اولیه نظرسنجی… گزینه ها %s توضیح گزینه های نظرسنجی - قسمت های اختیاری: حداقل زپ حداکثر زپ توافق نظر (0–100)% - بسته شدن پس از - روز نمی توان رای داد این نظرسنجی برای رای جدید بسته شده است - مبلغ زپ فقط یک رای به ازای هر کاربر در این نوع نظرسنجی مجاز است "جستجوی رویداد %1$s" افزودن پیام عمومی @@ -380,12 +317,9 @@ هیچ ردی در نوستر نمی ماند، فقط در شبکه لایتنینگ انجام می شود سرور فایل یک سرور برای بارگذاری این فایل انتخاب کنید - آدرس لایتنینگ یا @User سرورهای رسانه سرورهای مورد علاقه خود برای بارگزاری رسانه را انتخاب کنید. - هیچ مجموعه سرور NIP-96 ندارید. می توانید از لیست امتیست استفاده کنید، یا از لیست زیر اضافه کنید↓ هیچ سروری برای Blossom ندارید. می توانید از لیست امتیست استفاده کنید، یا از لیست زیر اضافه کنید↓ - سرورهای داخلی رسانه لیست پیش فرض امتیست. می توانید تک به تک یا تمام لیست را اضافه کنید. استفاده از لیست پیش فرض افزودن سرور رسانه @@ -398,31 +332,16 @@ در حال هش کردن انجام شد خطا - رله های شما (NIP-95) - فایل ها در رله های شما میزبانی می شوند. NIPجدید: بررسی کنید آیا پشتیبانی می کنند یا خیر گزینه های حریم خصوصی - Tor/Orbot تنظیمات - از طریق تنظیم Orbot متصل شوید تنظیم تنظیمات تور - قطع اتصال از Orbot/Tor? - داده های شما بلافاصله در شبکه معمولی منتقل می شوند بله خیر - لیست دنبال ها همه دنبال ها اطراف من همگانی لیست خموش درگاه پیش فرض 9050 است - ## از طریق Tor با Orbot متصل شوید - \n\n1. نصب کنید [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. شروع Orbot - \n3. در Orbot, پورت Socksرا علامت بزنید.مقدار پیش فرض 9050 است. - \n4. اگر لازم است پورت Orbot را تغییر دهید - \n5. پورت Socks را در این صفحه پیکربندی کنید - \n6. دکمه Activate را بفشارید تا از Orbot به عنوان پراکسی استفده نمایید - درگاه Orbot Socks موتور فعال تور استفاده از نسخه درونی یا Orbot @@ -464,8 +383,6 @@ IP خود را در تمام ارتباطات پنهان کن خودت را بساز شماره پورت نامعتبر - استفاده از Orbot - قطع اتصال Tor/Orbot پیام خصوصی وقتی پیام خصوصی دریافت شود اعلان می کند زپ دریافت شده @@ -475,20 +392,9 @@ برای %1$s اعلان: - پیوستن به گفتگو - شناسه گروه یا کاربر - npub, nevent یا hex - ساختن - پیوستن امروز هشدار محتوا این یادداشت حاوی محتوای حساس است که ممکن است از نظر برخی توهین آمیز یا مشوش کننده باشد - همیشه محتوای حساس را پنهان کن - همیشه محتوای حساس را نشان بده - همیشه هشدار محتوا را نشان بده - توصیه ها: - اسپم غریبه ها را فیلتر کن - اگر یادداشت توسط افرادی که فالو می کنید گزارش شده هشدار بده نماد جدید واکنش هیچ نوع واکنشی انتخاب نشده. نگه دارید تا تغییر دهید زپ گیری @@ -499,38 +405,25 @@ نوشتن به رله مقدار بایتی که به این رله فرستاده شده، شامل فیلترها و رویدادها مقدار بایتی که از این رله فرستاده شده، شامل فیلترها و رویدادها - در تلاش برای گرفتن اطلاعات رله از %1$s خطایی رخ داد مالک نگارش نرم‌افزار مخاطب NIP های پشتیبانی شده - کارمزد تراکنش Url پرداخت ها محدودیت ها کشورها زبان‌ها - برچسب‌ها سیاست ارسال محتوا خطاها و هشدارهای از این رله - طول پیام - اشتراک - فیلترها - طول شناسه اشتراک حداقل پیشوند حداکثر تعداد برچسب رویداد - طول محتوا حداقل PoW - احراز هویت - پرداخت توکن Cashu بازپرداخت - ارسال به کیف پول زپ - باز کردن در کیف پول Cashu کپی کردن توکن در یک اپلیکیشن دیگر باز کن آدرس لایتنینگ تنظیم نشده است - توکن به کلیپبورد کپی شد زنده آفلاین تمام شد @@ -554,7 +447,6 @@ (translated) row titles. Marked translatable="false" so protocol terms (blossom, nsec, negentropy, …) stay searchable in every locale and aren't sent to translators. --> همیشه - فقط Wifi وای فای بی اندازه هرگز کامل @@ -578,7 +470,6 @@ قیافه پست را انتخاب کن سبک گالری نمایه انتخاب سبک گالری - بارگیری تصویر اسپمر بیصدا شده. برای لغو کلیک کنید باصدا. برای بیصدا کردن کلیک کنید @@ -586,12 +477,8 @@ آدرس ناستر تایید شده بود آدرس ناستر تایید نشد بررسی آدرس ناستر - انتخاب یا لغو انتخاب همه پیش‌فرض بازگشت به حالت پیش فرض - برای ادامه یک رله انتخاب کنید - باز ارسال زپ ها به: - کلاینت هایی که این قابلیت را دارند زپ ها را به جای شما به LNAddress یا نمایه کاربر زیر می فرستند افشای مکان به عنوان یک هش جغرافیایی از مکان شما به این یادداشت می افزاید. دیگران خواهند دانست که شما در فاصله 5 کیلومتری (3 مایلی) این مکان هستید. پست اختصاصی مکان @@ -599,9 +486,6 @@ بارگیری مکان اجازه ثبت مکان داده نشده پیش از نمایش محتوای شما، هشدار محتوای حساس به آن می افزاید. این برای هرگونه محتوای نامناسب برای محیط کار یا هر محتوای دیگری که برخی ممکن است توهین آمیز یا مشوش کننده بدانند خوب است. - ویژگی جدید - برای فعال سازی این حالت لازم است اماتیست یک پیغام NIP-17 بفرستد (پیغام های GiftWrapped, Sealed Direct and Group). مطمئن شوید که گیرنده از کلاینتی سازگاز استفاده می کند. - فعال‌سازی عمومی گروه خصوصی یا عمومی جدید خصوصی @@ -620,7 +504,6 @@ بارگیری خودکار تصاویر و جیف ها پخش خودکار ویدئوها و جیف ها نشان دادن پیش نمایش URL - هنگام بارگیری تصاویر کپی استک کپی به کلیپ‌بورد کپی کلید عمومی در کلیپبورد @@ -631,45 +514,23 @@ رسانه افزوده شد رسانه به گالری نمایه شما افزوده شد ایجاد شده در - قوانین ورود با Amber بارگذاری وضعیت - خطا در تفسیر پیغام خطا آراء با مبلغ زپ سنجیده می شوند. می توانید برای جلوگیری از اسپم یک مبلغ حداقل تعیین کنید و برای جلوگیری از دستکاری نتیجه با زپ های بزرگ یک مبلغ حداکثر تعیین کنید. برای اینکه همه آراء ارزش یکسان داشته باشند در هر دو قسمت یک مبلغ را بزنید. یا این قسمت را خالی بگذارید تا هر مبلغ زپی را بپذیرد. زپ فرستاده نمی شود پیام به کاربر پیغام %1$s قبول - به %1$s نرسید: %2$s - آدرس NIP-11 ساخته نشد به دلیل %1$s: %2$s - به %1$s نتوانست برسد: %2$s - پاسخ %1$s تفسیر نشد: %2$s - رله درخواست %1$s را رد کرد: %2$s - به %1$s نرسید: %2$s - نتایج %1$s تفسیر نشد: %2$s - %1$s کد %2$s را انجام نداد - فعال برای: - خانه - پیام های خصوصی - گپ - همگانی - جستجو تقسیم و فرستادن زپ ها کلاینت هایی که این ویژگی را دارند زپ ها را تقسیم کرده و به جای شما کاربرانی که اینجا افزوده اید می فرستند جستجو و افزودن کاربر نام کاربری یا نام نمایشی تنظیمات لایتنینگ موجود نیست کاربر %1$s آدرس لایتنینگ برای دریافت ساتوشی تنظیم نکرده است - درصد - ۲۵ - تقسیم زپ با - بازفرستادن زپ به - کیف پول لایتنینگی یافت نشد پرداخت شد کیف پول %1$s خطا در بازکردن اپلیکیشن امضا کننده اپ امضا کننده یافت نشد. بررسی کنید که اپ حذف نشده باشد. - اپ امضا کننده رد کرد مطمئن شوید که اپ امضا کننده این تراکنش را تایید کرده است هیچ کیف پولی برای پرداخت صورتحساب لایتنینگ یافت نشد (خطا: %1$s). لطفا کیف پول لایتنینگی برای استفاده از زپ نصب کنید هیچ کیف پولی برای پرداخت صورتحساب لایتنینگ یافت نشد. لطفا یک کیف پول لایتنینگی برای استفاده از زپ نصب کنید @@ -680,36 +541,19 @@ یک گزینه را انتخاب کنید صورتحساب پرداخت نشد برداشت نشد - اتصال کیف پول برقرار نشد - خطا در تفسیر رشته اتصال NIP-47. بررسی کنید این مشکل مربوط به سازنده کیف پول شما مشکلی نباشد: %1$s. خطا: %2$s - خطا در تفسیر رشته اتصال NIP-47. بررسی کنید این مشکل مربوط به سازنده کیف پول شما مشکلی نباشد: %1$s. Cashu بازپرداخت نشد Mint پیام خطای روبرو را داد: %1$s - توکن Cashu خرج شده است. Cashu دریافت شد %1$s ساتوشی به کیف پول شما ارسال شد. (کارمزد: %2$s ساتوشی) هیچ کیف پول Cashu سازگاری در سیستم یافت نشد صورتحساب از سرور گیرنده دریافت نشد ارائه دهنده اتصال کیف پول شما خطای روبرو را داد: %1$s - نمی توان به Tor وصل شد - بارگیری اسناد رله در دسترس نیست LNUrl از آدرس لایتنینگ \"%1$s\" بدست نیامد. تنظیمات کاربر را بررسی کنید. - خدمات لایتنینگ %1$s گیرنده دردسترس نیست. از آدرس لایتنینگ \"%2$s\" محاسبه شد. خطا: %3$s. بررسی کنید آیا سرور کار می کند و آیا آدرس لایتنینگ صحیح است. - مشکل %1$s حل نشد. بررسی کنید که به اینترنت متصل باشید، سرور کار کند و آدرس لایتنینگ %2$s صحیح باشد. - مشکل %1$s حل نشد. بررسی کنید که به اینترنت متصل باشید، سرور کار کند و آدرس لایتنینگ %2$s صحیح باشد. \n\nخطای %3$s - صورتحساب از %1$s گرفته نشد صورتحساب از %1$s گرفته نشد: %2$s - خطا در تفسیر JSON از آدرس لایتنینگ. تنظیمات لایتنینگ کاربر را بررسی کنید. خطا در تفسیر JSON از %1$s. تنظیمات لایتنینگ کاربر را بررسی کنید - URL بازخوانی در پیکربندی سرور آدرس لایتنینگ یافت نشد فراخوانی URL از پاسخ %1$s یافت نشد - خطا در تفسیر JSON از فراخوان صورتحساب آدرس لایتنینگ. تنظیمات لایتنینگ کاربر را بررسی کنید. - خطا در تفسیر JSON از دریافت صورتحساب %1$s. تنظیمات لایتنینگ کاربر را بررسی کنید. مبلغ نادرست صورتحساب (%1$s ساتوشی)از %2$s. می بایست %3$s ساتوشی باشد. نمی توان صورتحساب لایتنینگ را پیش از زپ زدن ارسال کرد. کیف پول لایتنینگی گیرنده خطای روبرو را داد: %1$s - صورت حساب لایتنینگ ساخته نشد. پیغام از %1$s: %2$s - نمی توان صورتحساب لایتنینگ را پیش از زپ زدن ارسال کرد. المنت pr در JSON بدست آمده یافت نشد. - نمی توان صورتحساب لایتنینگ از %1$s ساخت. المنت pr در JSON بدست آمده یافت نشد. کاربر با امکان خواندن فقط هیچ واکنشی تنظیم نشده است یک اپلیکیشن UnifiedPush انتخاب کنید @@ -727,13 +571,11 @@ به فروشنده پیغام دهید سلام %1$s، هنوز موجوده؟ سلام، هنوز موجوده؟ - چیزی بفروشید عنوان آیفون 13 شرایط دسته بندی قیمت (به ساتوشی) - 1000 موقعیت مکانی شهر، استان، کشور جدید @@ -762,20 +604,13 @@ سایر رسانه بارگذاری نشد فایل فشرده باز نشد - خطا در فشرده سازی رسانه: %1$s خطای بارگیری: %1$s سرور پس از بارگذاری URL نداد فایل بارگذاری شده از سرور بارگیری نشد فایل بارگیری شده پس از بارگذاری بررسی نشد: %1$s - فایل محلی برای بارگذاری آماده نشد: %1$s بارگذاری نشد %1$s: %2$s - بارگذاری نشد: %1$s حذف نشد: %1$s رسانه برای NIP-95 بسیار بزرگ است - ریزتصویر بارگیری نشد - اطلاعات سربرگ آماده نشد: %1$s - فشرده سازی لغو شد - فشرده سازی فایل خروجی نساخت کیفیت رسانه کیفیت کم را انتخاب کنید تا رسانه را به شکل فایل کوچکتری ذخیره کند، کیفیت بالا برای ذخیره به شکل فایل بزرگتر و نافشرده برای بارگذاری رسانه بدون فشرده سازی است. پایین @@ -784,16 +619,12 @@ نافشرده ویرایش پیش‌نویس ورود با کد QR - مسیر خانه - جستجو کاوش پیغام‌ها اعلان‌ها - سراسری کوتاه - فیلترهای ایمنی نوشته جدید رسانه های کوتاه جدید: تصاویر یا ویدئوها یادداشت جدید در انجمن @@ -808,32 +639,22 @@ رله %1$s گسترش لیست رله گزینه های یادداشت - انتخابگر لیست رله نظرسنجی غیرفعال کردن نظرسنجی صورت حساب بیتکوین لغو صورت حساب بیتکوین - لغو فروش زپ ریزون لغو زپ ریزون موقعیت مکانی حذف موقعیت مکانی - تقسیم زپ - لغو تقسیم زپ افزودن هشدار محتوا حذف هشدار محتوا کلید عمومی را به شکل کد QR نشان بده آدرس نامعتبر امتیست آدرسی برای باز کردن دریافت کرد ولی آدرس نامعتبر بود: %1$s رله های صندوق دریافت پیام خصوصی - رله ها: %1$s - استفاده از رله های معمولی تنظیم رله های صندوق دریافت خصوصی با این تنظیمات همه می توانند بدانند که هنگام ارسال پیام به شما از کدام رله ها استفاده کنند. بدون این تنظیمات ممکن است برخی پیام ها را از دست بدهید. - گزینه های خوب: -- inbox.nostr.wine (پولی) -- auth.nostr1.com (رایگان) -- you.nostr1.com (رله شخصی - پولی) گزینه های خوب: - inbox.nostr.wine (پولی) - auth.nostr1.com (رایگان) @@ -845,7 +666,6 @@ ساخت لیستی از رله های مخصوص جستجو و تگ کردن کاربر باعث بهبود این نتایج خواهد شد. بین ۱-۳ رله بیافزایید تا هنگام جستجوی محتوا یا تگ کردن کاربران از آنها استفاده شود. حتما رله های انتخابی باید NIP-50 را پیاده‌سازی کرده باشند. انتخاب های مناسب: \n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com - بارگذاری پیام خصوصی تنظیمات رله رله های خانه/ صندوق خروجی عمومی این نوع از رله تمام محتوای شما را ذخریه می کند. امتیست پست های شما را اینجا می فرستد و دیگران از این رله ها برای یافتن محتوای شما استفاده می کنند. بین ۱-۳ رله وارد کنید. این رله ها ممکن است رله های شخصی، پولی، یا عمومی باشند. @@ -858,10 +678,6 @@ - you.nostr1.com (رله پولی یا شخصی) رله های خصوصی خانه بین ۱-۳ رله وارد کنید برای ذخیره رویدادهایی که هیچ کس دیگر نمی بیند ، به عنوان مثال پیش نویس های شما و یا تنظیمات اپلیکیشن. در حالت ایده آل، این رله ها یا محلی هستند یا پیش از بارگیری محتوای کاربر به احراز هویت نیاز دارند. - رله های کلی - امتیست از این رله ها استفاده می کند تا پست ها را برایتان بارگیری کند. - رله های پیشنهادی - رله های روبرو را به لیست رله های کلی خود بیافزایید تا پست های کاربران لیست شده را دریافت کنید. رله های جستجو لیست رله هایی که هنگام جستجوی محتوا یا کاربران مورد استفاده قرار می گیرند. اگر انتخابی در موجود نباشد، تگ کردن یا جستجو کار نخواهد کرد. حتما مطمئن شوید این رله ها را NIP-50 پیاده‌سازی کرده باشند. رله های محلی @@ -873,11 +689,8 @@ این نسخه نرم‌افزار پیشکش از: نسخه %1$s متشکریم! - حداکثر نوشتن محدود انشعاب شده از - انشعاب - مخزن گیت: %1$s وب: نسخه برداری: OTS: %1$s @@ -885,20 +698,13 @@ مدرکی وجود دارد که ثابت کند این پست پیش از %1$s امضا شده است. این مدرک در بلاکچین بیتکوین در آن تاریخ و زمان ثبت شده است. ویرایش نوشته پیشنهاد برای بهبود یک نوشته - خلاصه تغییرات - اصلاحات سریع… پذیرش پیشنهاد ویديو را در قاب جدا باز کن بارگيری - روشن کردن متن - متن خاموش - پیام مهروموم شده خاموش است. برای روشن کردن کلیک کنید. - پیام مهروموم شده روشن است. برای خاموش کردن کلیک کنید. ارسال نام کاربری را به شکل صوتی بخوان. Pushpin کد QR را اسکن کنید - رفتن به البی، ارائه دهنده کیف پول شخص ثالث. پاسخ به پیش نویس یادداشت ممکن نیست. نقل قول از پیش نویس یادداشت ممکن نیست. واکنش به پیش نویس یادداشت ممکن نیست. @@ -939,15 +745,12 @@ فضای ذخیره ناکافی - سرور فضای کافی برای پردازش موفق درخواست ندارد حلقه دیده شد - سرور یک حلقه بینهایت در پردازش این درخواست شناسایی کرد احراز هویت الزامی - کلاینت برای دسترسی به شبکه می بایست احراز هویت شده باشد - سرورهای NIP-96 - هر تعداد سرور که می خواهید اضافه کنید. می توانید بعدا هنگام بارگذاری تصویرتان انتخاب کنید که از کدام سرور استفاده شود سرورهای Blossom هر تعداد سرور که می خواهید اضافه کنید. می توانید بعدا هنگام بارگذاری تصویرتان انتخاب کنید که از کدام سرور استفاده شود یک سرور NIP-96 بیافزایید یک سرور Blossom بیافزایید حذف همه مطمئنید می خواهید حذف کنید؟ - استک: فایل تورنت بارگيری فایل باز نشد @@ -966,4 +769,10 @@ + + خدمات لایتنینگ %1$s گیرنده دردسترس نیست. از آدرس لایتنینگ \"%2$s\" محاسبه شد. خطا: %3$s. بررسی کنید آیا سرور کار می کند و آیا آدرس لایتنینگ صحیح است. + مشکل %1$s حل نشد. بررسی کنید که به اینترنت متصل باشید، سرور کار کند و آدرس لایتنینگ %2$s صحیح باشد. \n\nخطای %3$s + خطا در تفسیر JSON از دریافت صورتحساب %1$s. تنظیمات لایتنینگ کاربر را بررسی کنید. + صورت حساب لایتنینگ ساخته نشد. پیغام از %1$s: %2$s + نمی توان صورتحساب لایتنینگ از %1$s ساخت. المنت pr در JSON بدست آمده یافت نشد. diff --git a/amethyst/src/main/res/values-fa/strings.xml b/amethyst/src/main/res/values-fa/strings.xml index ac4b7bee32..a88b801455 100644 --- a/amethyst/src/main/res/values-fa/strings.xml +++ b/amethyst/src/main/res/values-fa/strings.xml @@ -20,8 +20,6 @@ جعل هویت رفتار ناهنجار سایر - ناشناس - آیکن رله نویسنده ناشناس کپی متن کپی شناسه نویسنده @@ -35,12 +33,9 @@ گزارش اسپم/کلاهبرداری گزارش جعل هویت - گزارش محتوای نامناسب گزارش رفتار ناهنجار گزارش بدافزار - گزارش مود بدافزار - مود با کلید خصوصی وارد شوید تا بتوانید پاسخ دهید با کلید خصوصی وارد شوید تا بتوانید یادداشت را بازنشر کنید با کلید خصوصی وارد شوید تا بتوانید یادداشت را لایک کنید @@ -51,7 +46,6 @@ دارید از کلید عمومی استفاده می کنید و با کلید عمومی فقط می توان خواند. با کلید خصوصی وارد شوید تا بتوانید کلمه یا جمله ای را پنهان کنید. دارید از کلید عمومی استفاده می کنید و با کلید عمومی فقط می توان خواند. با کلید خصوصی وارد شوید تا بتوانید کلمه یا جمله ای را آشکار کنید زپ - دیدن تعداد بازنشر بازنشر شده ویرایش شده @@ -64,9 +58,7 @@ افزودن " پاسخ به" " و " - "در کانال " بنر پروفایل - پرداخت موفق خطا در تفسیر پیغام خطا "دنبال شونده" "دنبال کننده" @@ -81,9 +73,7 @@ !خیلی ممنون مبلغ به ساتوشی ارسال ساتوشی - " %1$s : %2$s خطا در تبدیل" "%1$s پیش نمایش تصویر کارت برای" - کانال جدید نام کانال گروه باحال من آدرس تصویر @@ -94,32 +84,18 @@ ذخیره ساختن لغو - تصویر بارگذاری نشد - آدرس رله - یادداشت ها - بایت خطاها - تعداد خطاهای اتصال در این نوبت - خبرنامه اصلی - پیام خصوصی - گفتگوی عمومی - خبرنامه همگانی - جستجو در خبرنامه افزودن رله نمایش نام نام من استریچ باحالیان خوش آمدی استریچ! نام کاربری - نام کاربری من درباره من آدرس آواتار آدرس بنر آدری وبسایت ضمیرها - آدرس لایتنینگ - آدرس لایتنینگ(نقل شده) - در گالری ذخیره کن تصویر در گالری ذخیره شد بارگیری ویدئو آغاز شد… بارگیری رسانه آغاز شد… @@ -127,11 +103,8 @@ ویدئو در گالری گوشی ذخیره شد ویدئو ذخیره نشد بارگذاری تصویر - …در حال بارگذاری این کاربر آدرس لایتنینگ برای دریافت ساتوشی تنظیم نکرده است "…اینجا پاسخ دهید " - شناسه یادداشت را برای اشتراک گذاری در کلیپبورد ذخیره می کند - ذخیره شناسه کانال در کلیپبورد متادیتای کانال را ذخیره می کند پیوستن شناس @@ -142,18 +115,14 @@ یادداشت ها پاسخ ها گالری - "دنبال شوندگان" "گزارش ها" انتخاب های بیشتر "رله ها" وبسایت آدرس لایتنینگ شناسه کلید خصوصی (پسوردتان) را در کلیپبورد کپی می کند( - کپی کردن کلید خصوصی در کلیپبورد نمایش کد QR کلید خصوصی نمایش کد QR کلید خصوصی رمزنگاری شده - کلید عمومی را برای اشتراک گذاری در کلیپبورد ذخیره می کند - کپی کردن کلید عمومی در کلیپبورد ارسال پیام مستقیم متادیتای کاربر را ویرایش می کند دنبال کردن @@ -182,8 +151,6 @@ شما را چی صدا بزنیم؟ حساب کاربری ناستر ندارید؟ از قبل حساب کاربری ناستر دارید؟ - ایجاد حساب کاربری جدید - ساختن جفت کلید جدید در حال بارگیری خبرنامه بارگذاری حساب کاربری " :خطا در بارگیری پاسخ ها" @@ -191,12 +158,6 @@ هنوز هیچ اعلانی نیست. خبرنامه خالیست تازه‌سازی - ساخته شد - با توصیف - و تصویر - نام گفتگو تغییر کرد به - تصویر - و تصویر به ترک کردن دنبال نکردن کانال ساخته شد @@ -222,7 +183,6 @@ ناسزا / نفرت پراکنی گزارش نفرت پراکنی گزارش برهنگی / پورن - سایر همه شناس ها خوانده شده کن همه جدیدها را خوانده شده کن همه را خوانده شده کن @@ -242,23 +202,18 @@ احراز هویت انجام نشد مشخصات بیومتریک نتوانست مالک این تلفن را احراز هویت کند مشخصات بیومتریک نتوانست مالک این تلفن را احراز هویت کند. خطا: %1$s - خطا - "ساخته شده توسط %1$s" "تصویر مدال پاداش برای %1$s" یک مدال پاداش دریافت کردید مدال پاداش داده شد به یادداشت در کلیپبورد کپی شد \@npubنویسنده در کلیپبورد کپی شد (@note1)شناسه یادداشت در کلیپبورد کپی شد - انتخاب متن "<پیام خصوصی رمزگشایی نشد>\\n\nدر یک پیام خصوصی/رمزنگاری شده بین %1$s و %2$s نام شما آمده بود." افزودن حساب کاربری جدید حساب های کاربری انتخاب حساب کارگری افزودن حساب کاربری جدید حساب کاربری فعال - کلید خصوصی دارد - فقط خواندن، کلید خصوصی ندارد بازگشت انتخاب اشتراک گذاری لینک مرورگر @@ -276,14 +231,12 @@ حذف بلاک گزارش - حذف دوباره نشان نده اسپم یا کلاهبرداری محتوای نفرت پراکنی یا ناسزا جعل هویت بدخواهانه محتوای برهنگی یا نمایان رفتار ناهنجار - نرم‌افزار خرابکار بلاک کردن کاربر محتوای ایشان را در اپ شما پنهان می کند. یادداشت های شما همچنان بطور عمومی دیده می شوند که شامل کاربران بلاک شده توسط شما نیز هست. کاربران بلاک شده در صفحه فیلترهای ایمنی فهرست می شوند. گزارش سواستفاده @@ -303,30 +256,15 @@ افزودن به علامت گذاشته های عمومی برداشتن از علامت گذاشته های خصوصی برداشتن از علامت گذاشته های خصوصی - خدمات اتصال به کیف پول - به رمز ناستر اجازه بده زپ را بدون ترک اپ برداخت کند. این رمز را امن نگه دارید و درصورت امکان از رله خصوصی استفاده کنید - کلید عمومی اتصال به کیف پول - رله اتصال به کیف پول - رمز اتصال به کیف پول - نمایش کلید خصوصی - nsec / hex کلید خصوصی مبلغ وثیقه به ساتوشی - ارسال نظرسنجی - قسمت های الزامی: - دریافت کنندگان زپ - توضیحات اولیه نظرسنجی… گزینه ها %s توضیح گزینه های نظرسنجی - قسمت های اختیاری: حداقل زپ حداکثر زپ توافق نظر (0–100)% - بسته شدن پس از - روز نمی توان رای داد این نظرسنجی برای رای جدید بسته شده است - مبلغ زپ فقط یک رای به ازای هر کاربر در این نوع نظرسنجی مجاز است "جستجوی رویداد %1$s" افزودن پیام عمومی @@ -360,12 +298,9 @@ هیچ ردی در نوستر نمی ماند، فقط در شبکه لایتنینگ انجام می شود سرور فایل یک سرور برای بارگذاری این فایل انتخاب کنید - آدرس لایتنینگ یا @User سرورهای رسانه سرورهای مورد علاقه خود برای بارگزاری رسانه را انتخاب کنید. - هیچ مجموعه سرور NIP-96 ندارید. می توانید از لیست امتیست استفاده کنید، یا از لیست زیر اضافه کنید↓ هیچ سروری برای Blossom ندارید. می توانید از لیست امتیست استفاده کنید، یا از لیست زیر اضافه کنید↓ - سرورهای داخلی رسانه لیست پیش فرض امتیست. می توانید تک به تک یا تمام لیست را اضافه کنید. استفاده از لیست پیش فرض افزودن سرور رسانه @@ -378,31 +313,16 @@ در حال هش کردن انجام شد خطا - رله های شما (NIP-95) - فایل ها در رله های شما میزبانی می شوند. NIPجدید: بررسی کنید آیا پشتیبانی می کنند یا خیر گزینه های حریم خصوصی - Tor/Orbot تنظیمات - از طریق تنظیم Orbot متصل شوید تنظیم تنظیمات تور - قطع اتصال از Orbot/Tor? - داده های شما بلافاصله در شبکه معمولی منتقل می شوند بله خیر - لیست دنبال ها همه دنبال ها اطراف من همگانی لیست خموش درگاه پیش فرض 9050 است - ## از طریق Tor با Orbot متصل شوید - \n\n1. نصب کنید [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. شروع Orbot - \n3. در Orbot, پورت Socksرا علامت بزنید.مقدار پیش فرض 9050 است. - \n4. اگر لازم است پورت Orbot را تغییر دهید - \n5. پورت Socks را در این صفحه پیکربندی کنید - \n6. دکمه Activate را بفشارید تا از Orbot به عنوان پراکسی استفده نمایید - درگاه Orbot Socks موتور فعال تور استفاده از نسخه درونی یا Orbot @@ -444,8 +364,6 @@ IP خود را در تمام ارتباطات پنهان کن خودت را بساز شماره پورت نامعتبر - استفاده از Orbot - قطع اتصال Tor/Orbot پیام خصوصی وقتی پیام خصوصی دریافت شود اعلان می کند زپ دریافت شده @@ -454,20 +372,9 @@ از %1$s برای %1$s اعلان: - پیوستن به گفتگو - شناسه گروه یا کاربر - npub, nevent یا hex - ساختن - پیوستن امروز هشدار محتوا این یادداشت حاوی محتوای حساس است که ممکن است از نظر برخی توهین آمیز یا مشوش کننده باشد - همیشه محتوای حساس را پنهان کن - همیشه محتوای حساس را نشان بده - همیشه هشدار محتوا را نشان بده - توصیه ها: - اسپم غریبه ها را فیلتر کن - اگر یادداشت توسط افرادی که فالو می کنید گزارش شده هشدار بده نماد جدید واکنش هیچ نوع واکنشی انتخاب نشده. نگه دارید تا تغییر دهید زپ گیری @@ -478,37 +385,24 @@ نوشتن به رله مقدار بایتی که به این رله فرستاده شده، شامل فیلترها و رویدادها مقدار بایتی که از این رله فرستاده شده، شامل فیلترها و رویدادها - در تلاش برای گرفتن اطلاعات رله از %1$s خطایی رخ داد مالک نگارش نرم‌افزار مخاطب NIP های پشتیبانی شده - کارمزد تراکنش Url پرداخت ها محدودیت ها کشورها زبان‌ها - برچسب‌ها سیاست ارسال محتوا خطاها و هشدارهای از این رله - طول پیام - اشتراک - فیلترها - طول شناسه اشتراک حداقل پیشوند حداکثر تعداد برچسب رویداد - طول محتوا حداقل PoW - احراز هویت - پرداخت توکن Cashu بازپرداخت - ارسال به کیف پول زپ - باز کردن در کیف پول Cashu کپی کردن توکن آدرس لایتنینگ تنظیم نشده است - توکن به کلیپبورد کپی شد زنده آفلاین تمام شد @@ -528,7 +422,6 @@ ترجیحات اپ تنظیمات همیشه - فقط Wifi وای فای بی اندازه هرگز کامل @@ -552,7 +445,6 @@ قیافه پست را انتخاب کن سبک گالری نمایه انتخاب سبک گالری - بارگیری تصویر اسپمر بیصدا شده. برای لغو کلیک کنید باصدا. برای بیصدا کردن کلیک کنید @@ -560,12 +452,8 @@ آدرس ناستر تایید شده بود آدرس ناستر تایید نشد بررسی آدرس ناستر - انتخاب یا لغو انتخاب همه پیش‌فرض بازگشت به حالت پیش فرض - برای ادامه یک رله انتخاب کنید - باز ارسال زپ ها به: - کلاینت هایی که این قابلیت را دارند زپ ها را به جای شما به LNAddress یا نمایه کاربر زیر می فرستند افشای مکان به عنوان یک هش جغرافیایی از مکان شما به این یادداشت می افزاید. دیگران خواهند دانست که شما در فاصله 5 کیلومتری (3 مایلی) این مکان هستید. پست اختصاصی مکان @@ -573,9 +461,6 @@ بارگیری مکان اجازه ثبت مکان داده نشده پیش از نمایش محتوای شما، هشدار محتوای حساس به آن می افزاید. این برای هرگونه محتوای نامناسب برای محیط کار یا هر محتوای دیگری که برخی ممکن است توهین آمیز یا مشوش کننده بدانند خوب است. - ویژگی جدید - برای فعال سازی این حالت لازم است اماتیست یک پیغام NIP-17 بفرستد (پیغام های GiftWrapped, Sealed Direct and Group). مطمئن شوید که گیرنده از کلاینتی سازگاز استفاده می کند. - فعال‌سازی عمومی گروه خصوصی یا عمومی جدید خصوصی @@ -592,7 +477,6 @@ بارگیری خودکار تصاویر و جیف ها پخش خودکار ویدئوها و جیف ها نشان دادن پیش نمایش URL - هنگام بارگیری تصاویر کپی استک کپی به کلیپ‌بورد کپی کلید عمومی در کلیپبورد @@ -603,45 +487,23 @@ رسانه افزوده شد رسانه به گالری نمایه شما افزوده شد ایجاد شده در - قوانین ورود با Amber بارگذاری وضعیت - خطا در تفسیر پیغام خطا آراء با مبلغ زپ سنجیده می شوند. می توانید برای جلوگیری از اسپم یک مبلغ حداقل تعیین کنید و برای جلوگیری از دستکاری نتیجه با زپ های بزرگ یک مبلغ حداکثر تعیین کنید. برای اینکه همه آراء ارزش یکسان داشته باشند در هر دو قسمت یک مبلغ را بزنید. یا این قسمت را خالی بگذارید تا هر مبلغ زپی را بپذیرد. زپ فرستاده نمی شود پیام به کاربر پیغام %1$s قبول - به %1$s نرسید: %2$s - آدرس NIP-11 ساخته نشد به دلیل %1$s: %2$s - به %1$s نتوانست برسد: %2$s - پاسخ %1$s تفسیر نشد: %2$s - رله درخواست %1$s را رد کرد: %2$s - به %1$s نرسید: %2$s - نتایج %1$s تفسیر نشد: %2$s - %1$s کد %2$s را انجام نداد - فعال برای: - خانه - پیام های خصوصی - گپ - همگانی - جستجو تقسیم و فرستادن زپ ها کلاینت هایی که این ویژگی را دارند زپ ها را تقسیم کرده و به جای شما کاربرانی که اینجا افزوده اید می فرستند جستجو و افزودن کاربر نام کاربری یا نام نمایشی تنظیمات لایتنینگ موجود نیست کاربر %1$s آدرس لایتنینگ برای دریافت ساتوشی تنظیم نکرده است - درصد - ۲۵ - تقسیم زپ با - بازفرستادن زپ به - کیف پول لایتنینگی یافت نشد پرداخت شد کیف پول %1$s خطا در بازکردن اپلیکیشن امضا کننده اپ امضا کننده یافت نشد. بررسی کنید که اپ حذف نشده باشد. - اپ امضا کننده رد کرد مطمئن شوید که اپ امضا کننده این تراکنش را تایید کرده است هیچ کیف پولی برای پرداخت صورتحساب لایتنینگ یافت نشد (خطا: %1$s). لطفا کیف پول لایتنینگی برای استفاده از زپ نصب کنید هیچ کیف پولی برای پرداخت صورتحساب لایتنینگ یافت نشد. لطفا یک کیف پول لایتنینگی برای استفاده از زپ نصب کنید @@ -652,36 +514,19 @@ یک گزینه را انتخاب کنید صورتحساب پرداخت نشد برداشت نشد - اتصال کیف پول برقرار نشد - خطا در تفسیر رشته اتصال NIP-47. بررسی کنید این مشکل مربوط به سازنده کیف پول شما مشکلی نباشد: %1$s. خطا: %2$s - خطا در تفسیر رشته اتصال NIP-47. بررسی کنید این مشکل مربوط به سازنده کیف پول شما مشکلی نباشد: %1$s. Cashu بازپرداخت نشد Mint پیام خطای روبرو را داد: %1$s - توکن Cashu خرج شده است. Cashu دریافت شد %1$s ساتوشی به کیف پول شما ارسال شد. (کارمزد: %2$s ساتوشی) هیچ کیف پول Cashu سازگاری در سیستم یافت نشد صورتحساب از سرور گیرنده دریافت نشد ارائه دهنده اتصال کیف پول شما خطای روبرو را داد: %1$s - نمی توان به Tor وصل شد - بارگیری اسناد رله در دسترس نیست LNUrl از آدرس لایتنینگ \"%1$s\" بدست نیامد. تنظیمات کاربر را بررسی کنید. - خدمات لایتنینگ %1$s گیرنده دردسترس نیست. از آدرس لایتنینگ \"%2$s\" محاسبه شد. خطا: %3$s. بررسی کنید آیا سرور کار می کند و آیا آدرس لایتنینگ صحیح است. - مشکل %1$s حل نشد. بررسی کنید که به اینترنت متصل باشید، سرور کار کند و آدرس لایتنینگ %2$s صحیح باشد. - مشکل %1$s حل نشد. بررسی کنید که به اینترنت متصل باشید، سرور کار کند و آدرس لایتنینگ %2$s صحیح باشد. \n\nخطای %3$s - صورتحساب از %1$s گرفته نشد صورتحساب از %1$s گرفته نشد: %2$s - خطا در تفسیر JSON از آدرس لایتنینگ. تنظیمات لایتنینگ کاربر را بررسی کنید. خطا در تفسیر JSON از %1$s. تنظیمات لایتنینگ کاربر را بررسی کنید - URL بازخوانی در پیکربندی سرور آدرس لایتنینگ یافت نشد فراخوانی URL از پاسخ %1$s یافت نشد - خطا در تفسیر JSON از فراخوان صورتحساب آدرس لایتنینگ. تنظیمات لایتنینگ کاربر را بررسی کنید. - خطا در تفسیر JSON از دریافت صورتحساب %1$s. تنظیمات لایتنینگ کاربر را بررسی کنید. مبلغ نادرست صورتحساب (%1$s ساتوشی)از %2$s. می بایست %3$s ساتوشی باشد. نمی توان صورتحساب لایتنینگ را پیش از زپ زدن ارسال کرد. کیف پول لایتنینگی گیرنده خطای روبرو را داد: %1$s - صورت حساب لایتنینگ ساخته نشد. پیغام از %1$s: %2$s - نمی توان صورتحساب لایتنینگ را پیش از زپ زدن ارسال کرد. المنت pr در JSON بدست آمده یافت نشد. - نمی توان صورتحساب لایتنینگ از %1$s ساخت. المنت pr در JSON بدست آمده یافت نشد. کاربر با امکان خواندن فقط هیچ واکنشی تنظیم نشده است یک اپلیکیشن UnifiedPush انتخاب کنید @@ -699,13 +544,11 @@ به فروشنده پیغام دهید سلام %1$s، هنوز موجوده؟ سلام، هنوز موجوده؟ - چیزی بفروشید عنوان آیفون 13 شرایط دسته بندی قیمت (به ساتوشی) - 1000 موقعیت مکانی شهر، استان، کشور جدید @@ -734,20 +577,13 @@ سایر رسانه بارگذاری نشد فایل فشرده باز نشد - خطا در فشرده سازی رسانه: %1$s خطای بارگیری: %1$s سرور پس از بارگذاری URL نداد فایل بارگذاری شده از سرور بارگیری نشد فایل بارگیری شده پس از بارگذاری بررسی نشد: %1$s - فایل محلی برای بارگذاری آماده نشد: %1$s بارگذاری نشد %1$s: %2$s - بارگذاری نشد: %1$s حذف نشد: %1$s رسانه برای NIP-95 بسیار بزرگ است - ریزتصویر بارگیری نشد - اطلاعات سربرگ آماده نشد: %1$s - فشرده سازی لغو شد - فشرده سازی فایل خروجی نساخت کیفیت رسانه کیفیت کم را انتخاب کنید تا رسانه را به شکل فایل کوچکتری ذخیره کند، کیفیت بالا برای ذخیره به شکل فایل بزرگتر و نافشرده برای بارگذاری رسانه بدون فشرده سازی است. پایین @@ -756,15 +592,11 @@ نافشرده ویرایش پیش‌نویس ورود با کد QR - مسیر خانه - جستجو کاوش پیغام‌ها اعلان‌ها - سراسری کوتاه - فیلترهای ایمنی نوشته جدید رسانه های کوتاه جدید: تصاویر یا ویدئوها یادداشت جدید در انجمن @@ -779,32 +611,22 @@ رله %1$s گسترش لیست رله گزینه های یادداشت - انتخابگر لیست رله نظرسنجی غیرفعال کردن نظرسنجی صورت حساب بیتکوین لغو صورت حساب بیتکوین - لغو فروش زپ ریزون لغو زپ ریزون موقعیت مکانی حذف موقعیت مکانی - تقسیم زپ - لغو تقسیم زپ افزودن هشدار محتوا حذف هشدار محتوا کلید عمومی را به شکل کد QR نشان بده آدرس نامعتبر امتیست آدرسی برای باز کردن دریافت کرد ولی آدرس نامعتبر بود: %1$s رله های صندوق دریافت پیام خصوصی - رله ها: %1$s - استفاده از رله های معمولی تنظیم رله های صندوق دریافت خصوصی با این تنظیمات همه می توانند بدانند که هنگام ارسال پیام به شما از کدام رله ها استفاده کنند. بدون این تنظیمات ممکن است برخی پیام ها را از دست بدهید. - گزینه های خوب: -- inbox.nostr.wine (پولی) -- auth.nostr1.com (رایگان) -- you.nostr1.com (رله شخصی - پولی) گزینه های خوب: - inbox.nostr.wine (پولی) - auth.nostr1.com (رایگان) @@ -816,7 +638,6 @@ ساخت لیستی از رله های مخصوص جستجو و تگ کردن کاربر باعث بهبود این نتایج خواهد شد. بین ۱-۳ رله بیافزایید تا هنگام جستجوی محتوا یا تگ کردن کاربران از آنها استفاده شود. حتما رله های انتخابی باید NIP-50 را پیاده‌سازی کرده باشند. انتخاب های مناسب: \n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com - بارگذاری پیام خصوصی تنظیمات رله رله های خانه/ صندوق خروجی عمومی این نوع از رله تمام محتوای شما را ذخریه می کند. امتیست پست های شما را اینجا می فرستد و دیگران از این رله ها برای یافتن محتوای شما استفاده می کنند. بین ۱-۳ رله وارد کنید. این رله ها ممکن است رله های شخصی، پولی، یا عمومی باشند. @@ -829,10 +650,6 @@ - you.nostr1.com (رله پولی یا شخصی) رله های خصوصی خانه بین ۱-۳ رله وارد کنید برای ذخیره رویدادهایی که هیچ کس دیگر نمی بیند ، به عنوان مثال پیش نویس های شما و یا تنظیمات اپلیکیشن. در حالت ایده آل، این رله ها یا محلی هستند یا پیش از بارگیری محتوای کاربر به احراز هویت نیاز دارند. - رله های کلی - امتیست از این رله ها استفاده می کند تا پست ها را برایتان بارگیری کند. - رله های پیشنهادی - رله های روبرو را به لیست رله های کلی خود بیافزایید تا پست های کاربران لیست شده را دریافت کنید. رله های جستجو لیست رله هایی که هنگام جستجوی محتوا یا کاربران مورد استفاده قرار می گیرند. اگر انتخابی در موجود نباشد، تگ کردن یا جستجو کار نخواهد کرد. حتما مطمئن شوید این رله ها را NIP-50 پیاده‌سازی کرده باشند. رله های محلی @@ -844,11 +661,8 @@ این نسخه نرم‌افزار پیشکش از: نسخه %1$s متشکریم! - حداکثر نوشتن محدود انشعاب شده از - انشعاب - مخزن گیت: %1$s وب: نسخه برداری: OTS: %1$s @@ -856,19 +670,12 @@ مدرکی وجود دارد که ثابت کند این پست پیش از %1$s امضا شده است. این مدرک در بلاکچین بیتکوین در آن تاریخ و زمان ثبت شده است. ویرایش نوشته پیشنهاد برای بهبود یک نوشته - خلاصه تغییرات - اصلاحات سریع… پذیرش پیشنهاد بارگيری - روشن کردن متن - متن خاموش - پیام مهروموم شده خاموش است. برای روشن کردن کلیک کنید. - پیام مهروموم شده روشن است. برای خاموش کردن کلیک کنید. ارسال نام کاربری را به شکل صوتی بخوان. Pushpin کد QR را اسکن کنید - رفتن به البی، ارائه دهنده کیف پول شخص ثالث. پاسخ به پیش نویس یادداشت ممکن نیست. نقل قول از پیش نویس یادداشت ممکن نیست. واکنش به پیش نویس یادداشت ممکن نیست. @@ -909,19 +716,21 @@ فضای ذخیره ناکافی - سرور فضای کافی برای پردازش موفق درخواست ندارد حلقه دیده شد - سرور یک حلقه بینهایت در پردازش این درخواست شناسایی کرد احراز هویت الزامی - کلاینت برای دسترسی به شبکه می بایست احراز هویت شده باشد - سرورهای NIP-96 - هر تعداد سرور که می خواهید اضافه کنید. می توانید بعدا هنگام بارگذاری تصویرتان انتخاب کنید که از کدام سرور استفاده شود سرورهای Blossom هر تعداد سرور که می خواهید اضافه کنید. می توانید بعدا هنگام بارگذاری تصویرتان انتخاب کنید که از کدام سرور استفاده شود یک سرور NIP-96 بیافزایید یک سرور Blossom بیافزایید حذف همه مطمئنید می خواهید حذف کنید؟ - استک: فایل تورنت بارگيری فایل باز نشد هیچ اپ تورنتی برای باز کردن و بارگیری فایل نصب نیست. لیستی را برای فیلتر خبرنامه انتخاب کنید با قفل کردن دستگاه از حساب کاربری خارج شو + خدمات لایتنینگ %1$s گیرنده دردسترس نیست. از آدرس لایتنینگ \"%2$s\" محاسبه شد. خطا: %3$s. بررسی کنید آیا سرور کار می کند و آیا آدرس لایتنینگ صحیح است. + مشکل %1$s حل نشد. بررسی کنید که به اینترنت متصل باشید، سرور کار کند و آدرس لایتنینگ %2$s صحیح باشد. \n\nخطای %3$s + خطا در تفسیر JSON از دریافت صورتحساب %1$s. تنظیمات لایتنینگ کاربر را بررسی کنید. + صورت حساب لایتنینگ ساخته نشد. پیغام از %1$s: %2$s + نمی توان صورتحساب لایتنینگ از %1$s ساخت. المنت pr در JSON بدست آمده یافت نشد. diff --git a/amethyst/src/main/res/values-fi-rFI/strings.xml b/amethyst/src/main/res/values-fi-rFI/strings.xml index 469925eb50..6e2f19c28d 100644 --- a/amethyst/src/main/res/values-fi-rFI/strings.xml +++ b/amethyst/src/main/res/values-fi-rFI/strings.xml @@ -15,8 +15,6 @@ Roskaposti Väärennös Laiton toiminta - Tuntematon - Relekuvake Tuntematon tekijä Kopioi teksti Kopioi tekijän tunniste @@ -27,7 +25,6 @@ Ilmoita roskapostista / huijauksesta Ilmoita väärennöksestä - Ilmoita julkeasta sisällöstä Ilmoita laittomasta toiminnasta Kirjaudu sisään yksityisellä avaimella viestehin vastaamiseksi Kirjaudu sisään yksityisellä avaimella tehostaaksesi viestejä @@ -39,7 +36,6 @@ Käytät julkista avainta ja julkiset avaimet ovat vain luku -tilassa. Kirjaudu yksityisellä avaimella, jotta voit piilottaa sanan tai lauseen Käytät julkista avainta ja julkiset avaimet ovat vain luettavissa. Kirjaudu yksityisellä avaimella, jotta voit näyttää sanan tai lauseen Zapit - Katselukerrat Tehosta tehostettu Lainaa @@ -47,9 +43,7 @@ Lisää "vastaus kohteeseen " " ja " - "kanavassa " Profiilin banneri - Maksu onnistui Virhe virhesanomaa tulkittaessa " Seuratut" " Seuraajat" @@ -64,9 +58,7 @@ Kiitos paljon! Määrä satseissa Lähetä satseja - "Virhe tulkittaessa esikatselua kohteelle %1$s : %2$s" "Esikatsele kortin kuvaa kohteelle %1$s" - Uusi kanava Kanavan nimi Oma upea ryhmäni Kuvan URL @@ -77,35 +69,20 @@ Tallenna Luo Peruuta - Kuvan lataus epäonnistui - Releosoite - Viestit - Tavua Virheet - Kotisyöte - Yksityinen viestisyöte - Julkinen chat-syöte - Maailmanlaajuinen syöte - Hae syötettä Lisää rele Näyttönimi Oma näyttönimeni Käyttäjänimi - Oma käyttäjänimeni Tietoja minusta Avatarin URL Bannerin URL Verkkosivuston URL - LN-osoite - LN-URL (vanhentunut) Kuva tallennettu galleriaan Kuvan tallennus epäonnistui Lataa kuva - Ladataan… Käyttäjällä ei ole asetettuna Lightning-osoitetta satsien vastaanottamiseksi "vastaa tähän.. " - Kopioi viestin tunniste leikepöydälle Nostressa jakamista varten - Kopioi kanavan tunniste (viesti) leikepöydälle Muokkaa kanavan metatietoja Liity Tunnetut @@ -115,16 +92,12 @@ Keskustelut Viestit Vastaukset - "Seuratut" "Ilmiannetut" Lisää vaihtoehtoja " Releet" Verkkosivusto Lightning-osoite Kopioi Nsec-tunniste (salasanasi) leikepöydälle varmuuskopiointia varten - Kopioi yksityinen avain leikepöydälle - Kopioi julkinen avain leikepöydälle jakamista varten - Kopioi julkinen avain (NPub) leikepöydälle Lähetä suora viesti Muokkaa käyttäjän metatietoja Seuraa @@ -144,7 +117,6 @@ Käyttöehtojen hyväksyminen on pakollista Avain on pakollinen Kirjaudu sisään - Luo uusi avain Ladataan syöte Ladataan tiliä @@ -153,12 +125,6 @@ Yritä uudelleen Syöte on tyhjä. Päivitä - luotu - kuvaus - ja kuva - muutti keskustelun nimen kohteeksi - kuvaus kohteeksi - ja kuva kohteeksi Poistu Lopeta seuraaminen Kanava luotu @@ -181,7 +147,6 @@ Loukkaava kielenkäyttö / vihapuhe Ilmoita vihapuheesta Ilmoita alastomuudesta / pornosta - muut Merkitse kaikki Tunnetut luetuiksi Merkitse kaikki Uudet luetuiksi Merkitse kaikki luetuiksi @@ -191,23 +156,18 @@ Tunnistautuminen epäonnistui Biometriikka ei pystynyt tunnistamaan tämän puhelimen omistajaa Biometriikka ei pystynyt tunnistamaan tämän puhelimen omistajaa. Virhe: %1$s - Virhe - "Luonut %1$s" "Merkki kohteelle %1$s" Olet saanut uuden merkin Merkki myönnetty kohteelle Viestin teksti kopioitu leikepöydälle Käyttäjän @npub kopioitu leikepöydälle Viestin tunniste (@note1) kopioitu leikepöydälle - Valitse teksti "<Ei voitu purkaa yksityisviestiä>\n\nSinut mainittiin yksityisessä/salatussa keskustelussa kohteiden %1$s ja %2$s välillä." Lisää uusi tili Tilit Valitse tili Lisää uusi tili Aktiivinen tili - Sisältää salaisen avaimen - Vain julkisavain, ei salaista avainta Takaisin Valitse Jaa selaimen linkki @@ -224,7 +184,6 @@ Poista Estä Ilmoita - Poista Älä näytä uudelleen Roskaposti tai huijaus Loukkaava kielenkäyttö tai vihamielinen käytös @@ -249,29 +208,14 @@ Lisää julkisiin kirjanmerkkeihin Poista yksityisistä kirjanmerkeistä Poista julkisista kirjanmerkeistä - Lompakkoyhteyspalvelu - Valtuuttaa Nostr-salaisuuden maksamaan zapeja ilman sovelluksesta poistumista. Pidä salaisuutesi turvassa ja käytä yksityistä relettä, jos mahdollista. - Lompakkoyhteyden julkinen avain - Lompakkoyhteyden rele - Lompakkoyhteyden salainen avain - Näytä salainen avain - nsec / heksadesimaalinen salainen avain Luvattu määrä satseissa - Luo äänestys - Vaaditut kohdat: - Zap-vastaanottajat - Pääasiallinen äänestyksen kuvaus… Vaihtoehto %s Vaihtoehdon kuvaus - Valinnaiset kohdat: Vähimmäiszap Enimmäiszap Konsensus - Sulje äänestys - päivän kuluttua Ei voi äänestää Äänestys on suljettu uusilta ääniltä - Zap-määrä Vain yksi ääni käyttäjää kohti tällä äänestystyypillä "Etsitään tapahtumaa %1$s" Lisää julkinen viesti @@ -300,31 +244,13 @@ Ei-Zap Ei jälkiä Nostrissa, vain Lightningissa Tiedostopalvelin - LnAddress tai @Käyttäjä - Omat releet (NIP-95) - Tiedostot ovat isännöityinä omilla releilläsi. Uusi NIP: tarkista, tukevatko ne sitä - Tor/Orbot-asetus - Yhdistä Orbot-asetuksesi kautta - Haluatko todella katkaista Orbot/Tor-yhteytesi? - Tietosi siirtyvät välittömästi tavalliseen verkkoon Kyllä Ei - Seuraa-lista Kaikki seuraajat Maailmanlaajuinen Mykistä lista - ## Yhdistä Torin kautta Orbotin avulla - \n\n1. Asenna [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Käynnistä Orbot - \n3. Orbotissa tarkista Socks-portti. Oletusarvo on 9050 - \n4. Tarvittaessa vaihda porttia Orbotissa - \n5. Aseta Socks-portti tällä näytöllä - \n6. Paina Aktivoi-painiketta käyttääksesi Orbotia välityspalvelimena - Orbot Socks-portti Virheellinen porttinumero - Käytä Orbotia - Katkaise Tor/Orbot-yhteys Yksityisviestit Ilmoittaa sinulle, kun yksityinen viesti saapuu Saapuneet Zapit @@ -333,20 +259,9 @@ saaja: %1$s Ilmoitus: - Liity keskusteluun - Käyttäjän tai ryhmän tunniste - npub, nevent tai heksadesimaali - Luo - Liity Tänään Sisältövaroitus Tämä viesti sisältää herkkää sisältöä, joka voi olla loukkaavaa tai häiritsevää joillekin ihmisille - Piilota aina herkkä sisältö - Näytä aina herkkä sisältö - Näytä aina sisältövaroitukset - Suosittelee: - Suodata roskapostia tuntemattomilta - Varoita, kun seurattavasi ovat raportoineet viestejä Uusi reaktiosymboli Ei valittu reaktiotyyppejä. Pidä pitkään painettuna vaihtaaksesi. Zapkerääjä @@ -355,36 +270,23 @@ Zapraiser %1$s. %2$s satsiin tavoitteesta Lue releestä Kirjoita releeseen - Virhe yritettäessä hakea rele-tietoja %1$s:stä Omistaja Versio Ohjelmisto Yhteystiedot Tuetut NIPit - Pääsymaksut Maksut URL Rajoitukset Maat Kielet - Tagit Julkaisupolitiikka - Viestin pituus - Tilaukset - Suodattimet - Tilaustunnuksen pituus Vähimmäisliite Maksimi tapahtumien tagit - Sisällön pituus Vähimmäis PoW - Autentikointi - Maksu Cashu-tunnus Lunasta - Lähetä zap-lompakkoon - Avaa Cashu-lompakossa Kopioi tunnus Ei Lightning-osoitetta asetettuna - Kopioitu tunnus leikepöydälle POISSA PÄÄTTYNYT AJOITETTU @@ -406,7 +308,6 @@ (translated) row titles. Marked translatable="false" so protocol terms (blossom, nsec, negentropy, …) stay searchable in every locale and aren't sent to translators. --> Aina - Vain WiFi Ei koskaan Järjestelmä Vaalea @@ -419,7 +320,6 @@ URL-esikatselu Immersiivinen vieritys Piilota navigointipalkit vieritettäessä - Lataa kuva Roskapostittajat Ääni pois päältä. Napsauta palauttaaksesi äänet Ääni päällä. Napsauta vaimentaaksesi @@ -427,17 +327,10 @@ Nostr-osoite varmennettiin Nostr-osoite ei läpäissyt varmennusta Tarkistetaan Nostr-osoite - Valitse/Poista valinta kaikista Oletus - Valitse rele jatkaaksesi - Ohjaa zappit kohteeseen: - Sovelluksien tukeminen ohjaa zappit alla olevaan LN-osoitteeseen tai käyttäjäprofiiliin sen sijaan, että ne menisivät sinulle Näytä sijaintina Lisää sijaintisi Geohashinä viestiin. On julkisesti nähtävänä, että olet 5 km (3 mailin) säteellä nykyisestä sijainnista Lisää herkkä sisältö -varoitus ennen sisällön näyttämistä. Tämä on suositeltua kaikelle aikuissisällölle tai sisällölle, jota jotkut saattavat pitää loukkaavana tai häiritsevänä - Uusi ominaisuus - Tämän tilan aktivoiminen vaatii Amethystin lähettämään NIP-17-viestin (Lahjapakatut, Suljetut suorat ja ryhmäviestit). NIP-17 on uusi, ja useimmat asiakkaat eivät ole vielä toteuttaneet sitä. Varmista, että vastaanottaja käyttää yhteensopivaa asiakasta. - Aktivoi Julkinen Yksityinen Vastaanottaja @@ -453,44 +346,26 @@ Lataa kuvat ja GIF-animaatiot automaattisesti Toista videot ja GIF-animaatiot automaattisesti Näytä URL-esikatselut - Koska kuvat ladataan Kopioi leikepöydälle Kopioi URL leikepöydälle Kopioi viestin tunniste leikepöydälle Luotu - Säännöt Kirjaudu sisään Amberilla Päivitä tilaasi - Virhe tulkittaessa virhesanomaa Äänet painotetaan zappin määrän perusteella. Voit asettaa minimimäärän roskapostin välttämiseksi ja maksimimäärän suurten zappereiden estämiseksi. Käytä samaa määrää molemmissa kentissä, jotta jokainen ääni arvostetaan samalla määrällä. Jätä se tyhjäksi hyväksyäksesi minkä tahansa määrän. Zapin lähettäminen ei onnistunut Viesti käyttäjälle Ok - Kohdetta %1$s ei tavoitettu: %2$s - Kohdetta %1$s ei tavoitettu: %2$s - Tuloksen jäsentäminen epäonnistui %1$s: %2$s - %1$s epäonnistui koodilla %2$s - Aktiivinen kohteelle: - Koti - YVt - Keskustelut - Yleinen - Haku Jaa ja ohjaa zapit Asiakkaiden tukeminen jakaa ja välittää zapit käyttäjille, jotka on lisätty tähän sinun sijasta Etsi ja lisää käyttäjä Käyttäjänimi tai näyttönimi Lightning asetukset puuttuvat Käyttäjällä %1$s ei ole Lightning-osoitetta määritettynä vastaanottamaan satseja - Prosenttiosuus - Zappien jakaminen - Ohjaa zappit kohteeseen - Lightning-lompakkoja ei löytynyt Maksettu Lompakko %1$s Virhe avattaessa allekirjoitussovellusta Allekirjoittajasovellusta ei löytynyt. Tarkista, että sovellusta ei ole poistettu - Allekirjoittajasovellus hylätty Varmista, että allekirjoittajasovellus on valtuuttanut tämän tapahtuman Ei löytynyt lompakkoja Lightning-laskun maksamiseksi (käyttäjä: %1$s). Asenna Lightning-lompakko zapatäksesi Ei löytynyt lompakkoja Lightning-laskun maksamiseksi. Asenna Lightning-lompakko zapatäksesi @@ -501,27 +376,15 @@ Valitse vaihtoehto Laskua ei voitu maksaa Ei voitu perua - Wallet Connectin asennus epäonnistui - Virhe jäsennettäessä NIP-47 yhteyttä. Tarkista, onko tämä oikein lompakon tarjoajallasi: %1$s. Virhe: %2$s Cashu epäonnistui lunastuksessa Paja (mint) antoi seuraavan virheilmoituksen: %1$s - Cashu tunnukset on jo käytetty. Cashu vastaanotettu Yhteensopivaa Cashu-lompakkoa ei löytynyt järjestelmästä Laskua ei voi noutaa vastaanottimen palvelimilta Lompakkosi yhteyden tarjoaja palautti seuraavan virheen: %1$s - Toriin ei saatu yhteyttä - Reledokumenttia ei saatu ladattua Ei voitu koota LNUrlia Lightning-osoitteesta \"%1$s\". Tarkista käyttäjän asetukset - Vastaanottajan Lightning-palvelu osoitteessa %1$s ei ole käytettävissä. Se laskettiin Lightning-osoitteesta \"%2$s\". Virhe: %3$s. Tarkista, onko palvelin ylhäällä ja onko Lightning-osoite oikein - Ei voitu selvittää %1$s. Tarkista, oletko yhteydessä, onko palvelin ylhäällä ja onko Lightning-osoite %2$s oikein - Ei voitu noutaa laskua kohteesta %1$s - Virhe jäsennettäessä JSONia Lightning-osoitteesta. Tarkista käyttäjän Lightning-asetukset - Takaisinkutsun URL-osoitetta ei löydy käyttäjän Lightning-osoitteen palvelimen asetuksista - Virhe jäsennettäessä JSONia Lightning-osoitteen laskun noudossa. Tarkista käyttäjän Lightning-asetukset Virheellinen laskun määrä (%1$s satsia) kohteesta %2$s. Sen olisi pitänyt olla %3$s Ei voitu luoda Lightning-laskua ennen zapin lähettämistä. Vastaanottajan Lightning-lompakko lähetti seuraavan virheen: %1$s - Ei voitu luoda Lightning-laskua ennen zapin lähettämistä. Elementtiä pr ei löydy vastauksena tulleesta JSONista. Vain luku -käyttäjä Ei reaktioita asetettu Valitse UnifiedPush-sovellus @@ -538,7 +401,6 @@ Lähetä myyjälle viesti Hei %1$s, onko tämä vielä saatavilla? Hei, onko tämä vielä saatavilla? - Myy esine Otsikko Kunto Kategoria @@ -571,11 +433,9 @@ Muu Median lataus epäonnistui Pakattua tiedostoa ei voitu avata - Virhe mediaa pakkattaessa: %1$s Lähetysvirhe: %1$s Palvelin ei antanut URL-osoitetta latauksen jälkeen Mediaa ei voitu ladata palvelimelta - Paikallista tiedostoa ei voitu valmistella ladattavaksi: %1$s @@ -588,4 +448,6 @@ + + Vastaanottajan Lightning-palvelu osoitteessa %1$s ei ole käytettävissä. Se laskettiin Lightning-osoitteesta \"%2$s\". Virhe: %3$s. Tarkista, onko palvelin ylhäällä ja onko Lightning-osoite oikein diff --git a/amethyst/src/main/res/values-fr-rCA/strings.xml b/amethyst/src/main/res/values-fr-rCA/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-fr-rCA/strings.xml +++ b/amethyst/src/main/res/values-fr-rCA/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-fr-rFR/strings.xml b/amethyst/src/main/res/values-fr-rFR/strings.xml index 8e2aa46148..8d9e758e96 100644 --- a/amethyst/src/main/res/values-fr-rFR/strings.xml +++ b/amethyst/src/main/res/values-fr-rFR/strings.xml @@ -8,6 +8,14 @@ Montrer quand même Ce message a été masqué car il mentionne vos utilisateurs ou mots cachés Post signalé inapproprié par + + Ce message a plus de %1$d hashtag + Ce message a plus de %1$d hashtags + + + +%1$d\nréponse + +%1$d\nréponses + L\'événement est en cours de chargement ou ne peut pas être trouvé dans votre liste de relais 👀 Image du canal @@ -24,12 +32,11 @@ Autre Harcèlement Violence - inconnu - Icône de relais Auteur inconnu Copier le texte Copier la clé publique de l\'utilisateur Copier l\'ID de la note + Copier le JSON brut Diffuser Horodater Horodatage : Confirmations en attente @@ -39,30 +46,30 @@ Signaler Spam / Arnaque Signaler une falsification d\'identité - Signaler un contenu choquant Signaler un comportement illégal Signaler un programme malveillant - Signaler le mod Programme malveillant - Mod Connectez vous avec une clé privée pour pouvoir répondre Connectez vous avec une clé privée pour pouvoir booster des posts Connectez vous avec une clé privée pour pouvoir aimer des posts Aucun montant sélectionné pour le zap. Appui long pour modifier + a zappé %1$s sats + Anonyme + raid en cours + a créé un clip Connectez vous avec une clé privée pour pouvoir envoyer des zaps Connectez-vous avec une clé privée pour Suivre Connectez-vous avec une clé privée pour ne plus Suivre Vous utilisez une clé publique et les clés publiques sont en lecture seule. Connectez-vous avec une clé privée pour pouvoir masquer un mot ou une phrase Vous utilisez une clé publique et les clés publiques sont en lecture seule. Connectez-vous avec une clé privée pour pouvoir afficher un mot ou une phrase - Vous utilisez une clé publique et les clés publiques sont en lecture seule. Connectez-vous avec une clé privée pour pouvoir modifier les paramètres Vous utilisez une clé publique et les clés publiques sont en lecture seule. Connectez-vous avec une clé privée pour pouvoir téléverser Vous utilisez une clé publique et les clés publiques sont en lecture seule. Connectez-vous avec une clé privée pour pouvoir signer des événements Déchiffrement non autorisé Le signataire n\'a pas autorisé le décryptage nécessaire pour effectuer cette opération. Activez les décryptions NIP-44 dans votre application signataire et réessayez Signataire introuvable L\'application de signature a-t-elle été désinstallée ? Vérifiez si le signataire est installé et a ce compte. Déconnectez-vous et reconnectez-vous de l\'application signataire a changé. + Le signataire externe a renvoyé des données qui sont étranges pour la requête. Il peut y avoir un bug sur Amethyst ou le signataire. Zaps - Nombre de vues Boost boosté modifié @@ -75,9 +82,7 @@ Ajouter "répondre à " " et " - "dans le canal " Bannière du profil - Paiement Réussi Erreur d\'analyse du message d\'erreur " Abonnements" " Abonnés" @@ -88,7 +93,50 @@ Déconnexion Voir plus Facturer Lightning + Expiré + À + Demande de facture… + Confirmer le paiement + Payer %1$s via %2$s? + Payer cette facture via %1$s? + Montant (sats) + Saisissez un montant valide pour cette offre. + Plage autorisée : %1$s–%2$s sats + Budget + Budget de dépenses + Montant (sats) + Requête + Budget approuvé + Unique + Quotidien + Hebdomadaire + Mensuel + Payer uniquement + Payez et zappez à partir d\'un portefeuille qui a pré-autorisé votre compte. Dépensez seulement - pas de solde ou d\'historique. Payer + Envoyer le paiement + Recevoir sur + Payer depuis + Autre application de portefeuille + Portefeuille On-chain + Portefeuille Cashu + Lightning + Offre CLINK + On-chain + Cashu + Montant + Prix fixé par l\'offre + Reçu de Zap + Paiement direct en Lightning — aucun reçu zap n\'est publié sur Nostr. + Un reçu zap on-chain est publié sur Nostr afin que le destinataire puisse trouver le paiement. + Paiement envoyé ! + Paiement échoué + Essayer à nouveau + Terminé + Payer %1$s sats + Payer + Frais de réseau + Transaction : %1$s Pourboire Lightning Note au destinataire Merci beaucoup ! @@ -101,78 +149,62 @@ Préfixe visible 😎 Ajouter au message - "Erreur d'analyse de l'aperçu pour %1$s : %2$s" "Aperçu de l'image pour %1$s" Article - Nouveau canal Nom de canal Mon groupe spectaculaire Url de l\'image Url de l\'image (Optionnel) Description - Description introuvable "à propos…" Quoi de neuf ? Rédiger un message… Envoyer Sauvegarder + Envoyer Créer Renommer Annuler - Échec du téléchargement de l\'image - Adresse du relais - Publications - Octets Erreur Erreurs Pourcentage de connexions réussies vers le relais - Le nombre d\'erreurs de connexion dans cette session - Vos notifications - Flux de messages privés - Flux de chat public - Flux mondial - Flux de recherche Rechercher et ajouter un utilisateur - Ajouter un utilisateur Ajouter un relais - Nom - Nom (pour @tagging) Mon nom @tag Nom visible du public Mon nom visible du public Ostrich McGénial Bienvenue Ostrich! Nom d\'utilisateur - Mon nom d\'utilisateur Biographie URL de l\'avatar URL de la bannière URL de site Pronoms - Adresse LN - URL LN (obsolete) Enregistrer sur le téléphone - Enregistrer dans la Galerie Image enregistrée dans la galerie Le téléchargement de la vidéo a démarré… Le téléchargement du média a démarré… + Épingler en haut + Détacher + Épinglé en haut Échec de l\'enregistrement de l\'image Vidéo enregistrée dans la galerie vidéo du téléphone Impossible d\'enregistrer la vidéo + PDF enregistré dans Téléchargements/Amethyst + Échec de l\'enregistrement du PDF Charger une image Téléverser un fichier Prendre une photo Enregistrer une vidéo + Aucune application de caméra trouvée sur cet appareil Enregistrer un message - Enregistrer un message Cliquez et maintenez pour enregistrer un message Ré-enregistrer Enregistrer Enregistrement %1$s - Chargement… Erreur d\'envoi Échec de l\'envoi du message vocal - Erreur lors de l\'envoi NIP-95 n\'est pas encore supporté pour les messages vocaux Échec de l\'envoi de la voix : %1$s Aucun @@ -183,8 +215,7 @@ Modifie votre niveau de voix. Remarque : les changements de hauteur de base peuvent potentiellement être inversés par des auditeurs déterminés. L\'utilisateur n\'a pas configuré d\'adresse Lightning pour recevoir des sats "répondre ici" - Copie l\'ID de note dans le presse-papiers pour le partage sur Nostr - Copier l\'ID de la chaîne (Note) dans le presse-papiers + Dans cette discussion Modifie les métadonnées du canal Joindre Connus @@ -198,7 +229,6 @@ Réponses Les vôtres Galerie - "Suivis" "Signalements" "%1$s rapports" Plus d\'options @@ -206,11 +236,8 @@ Site Web Adresse Lightning Copie l\'ID Nsec (votre mot de passe) dans le presse-papiers pour le sauvegarder - Copier la clé secrète dans le presse-papiers Afficher le QR code de la clé privée Afficher le QR code de la clé privée chiffrée - Copie la clé publique dans le presse-papiers pour la partager - Copier la clé publique (NPub) dans le presse-papiers Envoyer un message direct Modifie les métadonnées de l\'utilisateur Suivre @@ -239,10 +266,9 @@ Comment devrions-nous vous appeler ? Vous n\'avez pas de compte Nostr ? Vous avez déjà un compte Nostr ? - Créer un nouveau compte - Générer une nouvelle clé Chargement du flux Chargement du compte + chiffré "Erreur lors du chargement des réponses : " @@ -251,13 +277,7 @@ Ouvrir le sondage Le flux est vide. Rafraîchir - créé - avec le descriptif de - et photo - changé le nom du chat en Nouveau profil de tchat : - descriptif à - et image à Partir Ne plus suivre Canal créé @@ -299,7 +319,6 @@ Blasphème / Discours haineux Signaler Discours haineux Signaler Nudité / Porno - autres Marquer tous les Connus comme lu Marquer tous les Nouveaux comme lu Tout marquer comme lu @@ -320,8 +339,6 @@ Échec de l\'authentification La biométrie n\'a pas pu authentifier le propriétaire de ce téléphone La biométrie n\'a pas pu authentifier le propriétaire de ce téléphone. Erreur : %1$s - Erreur - "Créé par %1$s" "Image de badge pour %1$s" Image du badge de récompense Vous avez reçu un nouveau Badge @@ -329,19 +346,22 @@ Copie du contenu de la note dans le presse-papiers Copie du @npub utilisateur dans le presse-papiers Copie de l\'ID de la note (@note1) dans le presse-papiers - Sélectionner le Texte "<Impossible de déchiffrer le message privé>\n\nVous avez été cité dans une conversation privée/cryptée entre %1$s et %2$s." Ajouter un Nouveau Compte Comptes + Vous + Système Sélectionner un Compte Ajouter un Nouveau Compte Compte actif - Avec une clé privée - Lecture seule, pas de clé privée Retour Sélectionner Partager le Lien Navigateur Partager + Partager en tant qu\'image + Partager en tant qu\'URL de l\'image + Génération de l\'aperçu… + Partagé par Amethyst ID Author ID Note Copier le Texte @@ -355,15 +375,15 @@ Bloquer Supprimer Bloquer + Mettre le fil de discussion en sourdine + Rétablir le fil de discussion Signaler - Supprimer Ne plus montrer Spam ou arnaque Grossièreté ou contenu haineux Usurpation d\'identité Nudité ou contenu graphique Comportement illégal - Programme malveillant Bloquer un utilisateur cachera son contenu dans votre application. Vos notes sont toujours visibles publiquement, y compris pour les personnes que vous bloquez. Les utilisateurs bloqués sont listés sur l\'écran Filtres de Sécurité. Signaler un Abus @@ -379,13 +399,172 @@ Favoris Signets par défaut Vos favoris par défaut que de nombreux clients prennent en charge + Anciens signets + Vos anciens signets + Tout déplacer vers les nouveaux signets + Signets migrés avec succès Brouillons + Publications planifiées + Planifier + Dans 1 heure + Demain à 9 h + Lundi prochain à 9 h + Continuer quand même + Demain + Déconnecté + Envoyer maintenant + Aucune publication planifiée + Erreur : %1$s + Planifié + Envoi en cours… + Échoué + Envoyé + Annulé + + Vous avez %d message planifié qui n\'a pas encore été publié. La déconnexion le supprimera définitivement. + Vous avez %d messages planifiés qui n\'ont pas encore été publiés. La déconnexion les supprimera définitivement. + + + %d en file d\'attente + %d en file d\'attente + + Sondages + Ouvrir + Fermé + Badges + Communautés + Nouvelle communauté + Modifier la communauté + Nom de communauté + Description + Règles (optionnel) + Ajouter une image de couverture + Modérateurs + Ajouter un modérateur + Nom, npub, ou NIP-05 + Propriétaire + Relais + Auteur + Requêtes + Nom, npub, ou NIP-05 + Nouveau badge + Badge de récompense + Accepter + Refuser + Retirer du profil + Nom + Nom de badge lisible par l\'homme + Description + Pourquoi ce badge a-t-il été décerné ? + Téléverser une image + Choisissez une image carrée pour être la face de votre badge. + Chargement du badge… + Rechercher des utilisateurs + Nom, npub, ou NIP-05 + Retirer + Badge sans titre + Décerné à %1$d + Badges de profil + Badges · %1$d + Choisissez les badges que vous avez reçus qui apparaitront sur votre profil. + Vous n\'avez pas encore reçu de badge. + Applications · %1$d + Applications + Recommandez les applications Nostr que vous utilisez pour que les autres puissent les découvrir. + iOS + Images + Entraînements + Entraînement + Nouvel entraînement + Titre + Durée + Distance + Rythme + Vitesse + Calories + Pas + Rythme cardiaque + Rythme cardiaque maximum + Poids + Notes + Heures + Minutes + Secondes + Partagez vos entraînements + Course à pied + Marche + Cyclisme + Randonnée + Natation + Yoga + Méditation + Alimentation + Jeûne + Applications + Source : %1$s + v%1$s + Télécharger + À propos + Plateformes + Sujets + Liens + Dernière version + Soyez le premier à commenter. + par + Afficher les anciennes versions + Masquer les anciennes versions + Diffusions en direct + Lever la main + Fermer ce salon ? + Fermer le salon + Discuter + Hôte + Modérateur + Microphone désactivé + Parler maintenant + Microphone ouvert + parle actuellement + Annuler + Retour + Récemment terminé + Annuler + Annuler + Ajouter + Relais + Utiliser les valeurs par défaut d\'Amethyst + Ajouter serveur + Supprimer serveur + Vidéos + Musique + Listes de lecture + Épisodes + Podcasts + Voir les épisodes + Aucun épisode trouvé pour le moment + Titre + Titre de la piste + Artiste + Nom de l’artiste + Album (optionnel) + Durée en secondes (optionnel) + Paroles ou crédits (optionnel) + Supprimer cette piste + Publier une suppression NIP-09 pour cette piste de musique ? + Ajouter à la liste de lecture + Ajouter à la liste de lecture Favoris Privés Favoris Publics Ajouter aux Favoris Privés Ajouter aux Favoris Publics Supprimer des Favoris Privés Supprimer des Favoris Publics + ajouté par + Notes épinglées + Vos notes épinglées + Épingler sur le profil + Retirer du profil + Retirer de la liste + Fermer Listes de favoris Icône pour la liste de favoris Nouvelle liste de favoris @@ -395,14 +574,15 @@ Supprimer la liste de favoris Voir les publications Voir les articles - Voir les liens - Voir les hashtags - Vous n\'avez pas encore de liste de favoris. Appuyez sur le bouton ci-dessous pour en créer une. + Privé + Renommer + Dupliquer + Ajouter un hashtag + Basculer public/privé Publications privées Publications privées (%1$s) Publications publiques Publications publiques (%1$s) - Articles privés Articles privés (%1$s) Articles publics Articles publics (%1$s) @@ -411,6 +591,14 @@ Ajouter cet article aux favoris est un favori public ici est un favori privé ici + Privé — visible uniquement par les participants tagués + Rendre public + Les réponses à une note privée restent toujours privées + Visible par + Aucun récepteur pour le moment : vous seul serez en mesure de voir cette note. Ajoutez des personnes pour la partager. + Ajouter + Retirer l\'utilisateur des notifications + Rechercher et ajouter un utilisateur à notifier n\'est pas un favori ici Supprimer le favori de la liste Ajouter un favori à la liste @@ -420,39 +608,23 @@ Les métadonnées des listes de favoris peuvent être vues par n\'importe qui sur Nostr. Seuls vos membres privés sont chiffrés. Déplacer en public Déplacer en privé - Service Wallet Connect - Autorise un Nostr Secret à payer des zaps sans quitter l\'application. Gardez le secret en toute sécurité et utilisez un relais privé si possible - Clé publique Wallet Connect - Relais Wallet Connect - Secret Wallet Connect - Montrer la clé secrète - Clé privée nsec / hex - Connecté - Non connecté - Avancé : saisissez manuellement les détails de la connexion + Envoyer on-chain à la place + %1$s sats Confidentialité des Zaps Contrôle comment votre identité est affichée lorsque vous envoyez un zap. Connecter le portefeuille Montant engagé en Sats - Message Sondage - Champs requis: - Bénéficiaires du Zap - Description du sondage primaire… - Option Option %s Description de l\'option du Sondage - Champs optionnels : Zap minimum Zap maximum Consensus (0–100)% + Choix multiples Date & heure de clôture du sondage Le sondage se termine dans %1$s - Clôturer après - jours Impossible de voter Le Sondage est fermé aux nouveaux votes - Montant des Zap Un seul vote par utilisateur est autorisé sur ce type de sondage "Recherche de l'Événement %1$s" Envoyer Zap @@ -475,6 +647,8 @@ Utiliser l\'URL directe Description des contenus Un bateau bleu sur une plage de sable blanc au coucher du soleil + Suggestion par IA, modifiez-moi + Rejeter la suggestion d\'IA Type de Zap Zap Type pour toutes les options Public @@ -485,18 +659,18 @@ Le receveur et le public ne savent pas qui a envoyé le paiement Non-Zap Aucune trace sur Nostr, seulement sur le Lightning + Anonyme Serveur fichier Choisissez un serveur vers lequel téléverser ce fichier - Adresse LN ou @Utilisateur Serveurs média Définissez vos serveurs de téléversement de média préférés. - Vous n\'avez pas de serveur NIP-96 défini. Vous pouvez utiliser la liste d\'Amethyst, ou en ajouter un ci-dessous ↓ + Utiliser le cache local Blossom Vous n\'avez pas de serveur Blossom défini. Vous pouvez utiliser la liste d\'Amethyst, ou en ajouter un ci-dessous ↓ - Serveurs média intégrés Liste par défaut d\'Amethyst. Vous pouvez les ajouter individuellement ou ajouter la liste. Utiliser la liste par défaut Ajouter un serveur média Supprimer le serveur média + Adresse Non commencé Compression en cours Téléversement en cours @@ -505,36 +679,19 @@ Hachage Terminé Erreur - Vos relais (NIP-95) - Les fichiers sont hébergés par vos relais. Nouveau NIP: vérifiez s\'ils sont supportés Options de confidentialité - Configuration Tor/Orbot - Se connecter à travers la configuration Orbot Ajuster Paramètres Tor - Se déconnecter de Orbot/Tor? - Vos données seront immédiatement transférées sur le réseau classique Oui Non - Liste des Abonnés Tous les abonnements Tous les abonnements de l\'utilisateur Liste de suivi par défaut - Suivre via Proxy Autour de moi Général - Échecs Liste en Sourdine Listes de suivi Ce sont des listes de suivi conçues pour votre propre utilisation. Vous pouvez suivre des utilisateurs en privé ou publiquement - Marque-pages étiquetés - Marque-pages généraux - Public - Privé - Mixte - Il semble que vous n\'ayez pas encore de liste de suivi. - \n Appuyez ci-dessous pour actualiser, ou appuyez sur les boutons d\'ajout pour en créer un nouveau. - Nouveau Ajouter l\'auteur à la liste de suivi Ajouter ou supprimer un utilisateur des listes, ou créer une nouvelle liste avec cet utilisateur. @@ -543,23 +700,9 @@ %1$s est un membre privé Ajouter en tant que membre public Ajouter en tant que membre privé - Membres publics - Membres privés - Profils publics - Profils privés - membre - membres - Aucun membre Vide - %1$s n\'est pas dans cette liste %1$s n\'est pas un membre Vos listes et %1$s - Vos listes - Aucune liste de suivi n\'a été trouvée, ou vous n\'avez aucune liste de suivi. Appuyez ci-dessous pour rafraîchir, ou utilisez le menu pour en créer une. - Un problème est survenu lors de la récupération : %1$s - Créer une nouvelle liste - Nouvelle liste avec %1$s membres - Crée une nouvele liste de suivi et ajoute %1$s en tant que membre %2$s. Nouvelle liste de suivi Nouveau pack de suivi Copier/Cloner la liste de suivi @@ -579,14 +722,6 @@ Vous renommez depuis vers.. Le port par défaut est 9050 - ## Se connecter à travers Tor avec Orbot - \n\n1. Installe [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Démarre Orbot - \n3. Dans Orbot, vérifie le port Socks. Par défaut 9050 - \n4. Si nécessaire change le port dans Orbot - \n5. Configure le port Socks sur cet écran - \n6. Appuyer sur le bouton Activer pour utiliser Orbot comme proxy - Port Socks Orbot Activer le moteur Tor Utiliser la version interne ou Orbot @@ -628,8 +763,6 @@ Masque votre IP pour toutes les connexions Faites votre choix manuellement Numéro de port invalide - Utiliser Orbot - Déconnecter Tor/Orbot Messages privés Vous notifie lorsqu\'un message privé est reçu Zaps reçus @@ -641,32 +774,67 @@ Marquer comme lu Nouveaux messages Nouveaux zaps + Échecs + Vous avertit des événements liés aux parties d\'échecs + %1$s a accepté votre défi aux échecs + %1$s déplacé — votre tour + Réponses + Nouvelles réponses + Mentions + %1$s vous a mentionné + Nouvelles mentions + Appels entrants + Notifications pour les appels vocaux et vidéos entrants + Appel entrant + Appel vocal entrant\u2026 + Appel vidéo entrant\u2026 + Appel\u2026 + Connexion en cours\u2026 + Appel terminé + Appels + Accepter + Rejeter + Caméra activée + Caméra désactivée + Basculer de caméra + Haut-parleur + Écouteurs + Bluetooth + Appel vocal + Appel vidéo + Ajouter un participant + Rechercher des utilisateurs\u2026 + Permission requise + Amethyst a besoin d\'un accès à la caméra et au microphone pour démarrer un appel vidéo. Veuillez les activer dans les paramètres de l\'application. + Amethyst a besoin d\'un accès à la caméra et au microphone pour démarrer un appel vidéo. Veuillez les activer dans les paramètres de l\'application. + Ouvrir les paramètres + Annuler + Paramètres d\'appel + Activer les appels vocaux et vidéos + Lorsque désactivé, les boutons d\'appel sont masqués dans les écrans de discussion et tous les appels entrants sont ignorés. + Qualité vidéo + Ajouter un serveur TURN + Supprimer + URL du serveur + Nom d\'utilisateur + Voir les messages Notifier: - Rejoindre Conversation - Utilisateur ou Groupe ID - npub, nevent ou hex - Créer - Rejoindre Aujourd\'hui Avertissement de contenu Attention : %1$s Ce message contient du contenu sensible que certaines personnes peuvent trouver offensant ou dérangeant - Toujours cacher les contenus sensibles - Toujours afficher les contenus sensibles - Toujours afficher les avertissements de contenu Masquer Afficher Avertir - Recommendations: - Filtrer le spam des inconnus - Avertir lorsque les messages ont été rapportés par vos abonnés Filtrer les spams Masque les messages d\'inconnus qui étaient exactement les mêmes depuis 5 fois ou plus Avertir sur les rapports Affiche un message d\'avertissement lorsque des messages ont été rapportés 5 fois ou plus par vos abonnements Afficher le contenu sensible Affiche un message d\'avertissement lorsque l\'auteur du message l\'a marqué comme sensible + ∞ + Vous n\'avez pas encore bloqué d\'utilisateurs. Nouveau symbole de réaction Aucun type de réaction sélectionné. Appuyer longuement pour changer Collecte de Zaps @@ -678,22 +846,17 @@ Le nombre d\'octets qui ont été envoyés à ce relais, y compris les filtres et les événements Le nombre d\'octets qui ont été reçus depuis ce relais, y compris les filtres et les événements Événements enregistrés - Une erreur s\'est produite en récupérant les informations du relay depuis %1$s Propriétaire Utilisé par Clé de service - Exécution %1$s - Exécution %1$s (%2$s) Version Logiciel Contact NIPs supportés Grasps supportées - Frais d\'admission Admission Souscription Publication - Paiements %1$s URL de payments Audience cible Politiques & liens @@ -701,46 +864,40 @@ Limites Pays Langages - Étiquettes Sujets Tous les pays Toutes les langues Politique de publication Politique de confidentialité Termes & Conditions + À propos & Légal N/A Erreurs et Notifications de ce Relais + Réseau + Type + NIPs supportés Abonnements actifs Abonnements REQ (%1$d) Abonnements COUNT (%1$d) - Aucun abonnement actif pour ce relais %1$d auteurs %1$d ids depuis %1$s jusqu\'à %1$s limite %1$d - Longueur du message - Abonnements - Filtres - Longueur de l\'id de souscription Préfixe minimum Tags d\'événement maximum - Longueur du contenu Longueur maximale du contenu Rejeter plus anciens que Accepte jusqu\'à %1$s dans le futur Il y a %1$s - %1$s zeros %1$s bits Rétention de l\'événement Taille du contenu Connectivité Contrôle d\'accès PoW minimum - Authentification Authentification requise - Paiement Paiement requis Longueur du message maximum Souscription maximale @@ -749,18 +906,20 @@ Longueur maximale du SubID Jeton Cashu Échanger - Envoyer vers le portefeuille Zap - Ouvrir dans le portefeuille Cashu Copier le Jeton Ouvrir dans une autre application Adresse Lightning non définie - Jeton copié dans le presse-papiers EN DIRECT DÉCONNECTÉ TERMINÉ PLANIFIÉ + PRIVÉ La diffusion en direct est déconnectée La diffusion en direct est terminée + OUVERT + PRIVÉ + FERMÉ + PLANIFIÉ Se déconnecter supprime toutes vos informations locales. Assurez-vous d\'avoir vos clés privées sauvegardées pour éviter de perdre votre compte. Voulez-vous continuer ? Tags suivis Relais @@ -789,8 +948,8 @@ + Réinitialiser Toujours - Wifi uniquement WiFi illimité Jamais Complet @@ -814,7 +973,6 @@ Choisir le style du message Style de la galerie de profil Choisissez le style de la galerie - Charger l\'image Spammeurs Silencieux. Cliquer pour réactiver le son Son activé. Cliquer pour mettre en silencieux @@ -825,28 +983,34 @@ L\'adresse Nostr a été vérfiée La vérification de l\'adresse Nostr a échouée Vérification de l\'adresse Nostr - Tout sélectionner/désélectionner Défaut Rétablir les valeurs par défaut - Sélectionner un relay pour continuer - Transférer les Zaps à: - Les clients compatibles transmettront des zaps sur l\'adresse LN ou le profil Utilisateur ci-dessous au lieu du vôtre. Révéler la localisation comme Ajoute un Geohash de votre emplacement au message. Le public saura que vous êtes à moins de 5km de l\'emplacement actuel Post exclusif à la localisation Seuls les abonnés à cette localisation le verront. Vos abonnés généraux ne le verront pas. Message à hashtag-exclusif - Seuls les abonnés du hashtag le verront. Vos abonnés généraux ne le verront pas. + Privé + Piste inconnue + Chargement de la piste… + Téléverser une image de couverture + Modifier la liste de lecture + Modifier la liste de lecture + Titre + Description (optionnel) + Notes (optionnel) + Téléverser une image de couverture + Supprimer cette playlist + Déplacer la piste vers le haut + Déplacer la piste vers le bas + Retirer la piste de la playlist Chargement de la localisation Pas d\'autorisations de localisation Ajoute un avertissement de contenu sensible avant de montrer votre contenu. C\'est idéal pour tout contenu NSFW ou contenu que certaines personnes peuvent trouver offensant ou dérangeant Raison (optionnel) - Nouvelle Fonctionnalité - Pour activer ce mode, Amethyst doit envoyer un message NIP-17 (GiftWrapped, Sealed Direct et Group Messages). Le protocole NIP-17 est nouveau et la plupart des clients ne l\'ont pas encore mis en oeuvre. Assurez-vous que le destinataire utilise un client compatible. - Activer Public + Groupe Nouveau Groupe Public ou Privé - Relais Privé À Sujet @@ -858,70 +1022,47 @@ Explication aux membres Changement de nom pour les nouveaux objectifs. Coller depuis le presse-papiers - URI NIP-47 invalide - L\'URI %1$s n\'est pas une URI de connexion NIP-47 valide. - Se connecter à un nouveau portefeuille NWC Portefeuille introuvable Pour l\'interface de l\'App Sombre, Clair ou thème Système Charger automatiquement les images et les GIFs Lire automatiquement les vidéos et les GIFs + Lire automatiquement les vidéos lorsqu\'elles sont visibles à l\'écran Afficher la prévisualisation d\'URL - Quand charger les images Copier dans le presse-papiers Copier dans le presse-papiers + Copié dans le presse-papiers Copier le nprofile dans le presse-papiers Copier npub dans le presse-papiers Partager ou Enregistrer + Nouveau message Copier l\'URL dans le presse-papiers Copier l\'ID de la note dans le presse-papiers Ajouter un média à la galerie Média ajouté Média ajouté à votre galerie de profil Créé le - Règles - À propos de nous Lignes directrices Modérateurs Se connecter avec Amber Mettez à jour votre statut - Erreur d\'analyse du message d\'erreur Les votes sont pondérés par le montant du zap. Vous pouvez définir un montant minimum pour éviter les spammeurs et un montant maximum pour éviter qu\'un grand nombre de zappeurs ne prenne le contrôle du sondage. Utilisez le même montant dans les deux champs pour vous assurer que chaque vote a la même valeur. Laissez le champ vide pour accepter n\'importe quel montant. Impossible d\'envoyer un zap Contacter l\'utilisateur Message %1$s Ok - Impossible d\'atteindre %1$s: %2$s - Impossible d\'assembler l\'URL NIP-11 pour %1$s: %2$s - Impossible d\'accéder à %1$s: %2$s - Impossible d\'analyser la réponse depuis %1$s: %2$s - Le Relais a refusé la requête %1$s: %2$s - Impossible d\'atteindre %1$s: %2$s - Impossible d\'analyser le résultat de %1$s: %2$s - %1$s a échoué avec le code %2$s - Actif pour : - Accueil - MPs - Salons - Général - Rechercher Diviser et Transférer des Zaps Les clients supportés vont diviser et transférer les zaps aux utilisateurs ajoutés ici au lieu du vôtre Rechercher et Ajouter un Utilisateur Nom d\'utilisateur ou nom affiché Configuration lightning manquante L\'utilisateur %1$s n\'a pas configuré d\'adresse Lightning pour recevoir des sats - Pourcentage - 25 - Diviser les zaps avec - Transférer les zaps à - Portefeuilles Lightning introuvables Payé Portefeuille %1$s Erreur lors de l\'ouverture de l\'application de signature L\'application signataire est introuvable. Vérifiez que l\'application n\'a pas été désinstallée + Impossible de lire cette vidéo Requête de signature rejetée - Demande de signature rejetée Assurez-vous que l\'application signataire a autorisé cette transaction Aucun portefeuille trouvé pour payer une facture lightning (Erreur : %1$s). Veuillez installer un portefeuille Lightning pour utiliser les zaps Aucun portefeuille trouvé pour payer une facture lightning. Veuillez installer un portefeuille Lightning pour utiliser les zaps @@ -934,38 +1075,23 @@ Sélectionnez une option Impossible de payer la facture Impossible de retirer - Impossible de configurer Wallet Connect - Erreur lors de l\'analyse de l\'événement de connexion NIP-47. Vérifiez si tout est correct avec le prestataire de votre Portefeuille : %1$s. Erreur : %2$s - Erreur lors de l\'analyse de l\'événement de connexion NIP-47. Vérifiez si tout est correct avec le prestataire de votre Portefeuille : %1$s. Impossible d\'utiliser ce Cashu Le Mint a fourni le message d\'erreur suivant : %1$s - Les jetons de cashu sont déjà dépensés. Cashu reçu %1$s sats ont été envoyés à votre portefeuille. (Frais : %2$s sats) Aucun portefeuille Cashu compatible trouvé dans le système Impossible de récupérer la facture depuis les serveurs du destinataire Le fournisseur de connexion de votre portefeuille a retourné l\'erreur suivante : %1$s - Impossible de se connecter à Tor - Téléchargement du document relais indisponible Impossible d\'assembler LNUrl à partir de l\'adresse Lightning \"%1$s\". Vérifiez la configuration de l\'utilisateur - Le service lightning du récepteur à %1$s n\'est pas disponible. Il a été calculé à partir de l\'adresse lightning \"%2$s\". Erreur: %3$s. Vérifiez si le serveur est en ligne et si l\'adresse lightning est correcte - Impossible de résoudre %1$s. Vérifiez si vous êtes connecté, si le serveur est en ligne et si l\'adresse lightning %2$s est correcte - Impossible de résoudre %1$s. Vérifiez si vous êtes connecté, si le serveur est actif et si l\'adresse Lightning %2$s est correcte.\n\nL\'erreur était : %3$s - Impossible de récupérer la facture depuis %1$s Impossible de récupérer la facture à partir de %1$s: %2$s - Erreur lors de l\'analyse du JSON à partir de l\'Adresse Lightning. Vérifiez la configuration lightning de l\'utilisateur Erreur lors de l\'analyse du JSON de %1$s. Vérifiez la configuration lightning de l\'utilisateur - URL de callback introuvable dans la configuration serveur de l\'adresse lightning de l\'utilisateur URL de callback introuvable dans la réponse de %1$s - Erreur lors de l\'analyse du JSON à partir de la récupération de la facture de l\'Adresse Lightning. Vérifiez la configuration Lightning de l\'utilisateur - Erreur lors de l\'analyse du JSON de la facture de %1$s. Vérifiez la configuration lightning de l\'utilisateur Montant de la facture (%1$s sats) incorrect de %2$s. Il aurait dû être %3$s Impossible de créer une facture lightning avant d\'envoyer le zap. Le portefeuille lightning du destinataire a envoyé l\'erreur suivante : %1$s - Impossible de créer une facture lightning. Message de %1$s: %2$s - Impossible de créer une facture lightning avant d\'envoyer le zap. Élément pr introuvable dans le JSON résultant. - Impossible de créer une facture lightning avec %1$s. Élément pr introuvable dans le JSON résultant. Utilisateur en lecture seule Aucune réaction configurée + Notifications + Catégories Sélectionnez une application UnifiedPush Notification Push Depuis les applications UnifiedPush installées @@ -981,13 +1107,11 @@ Envoyer un message au vendeur Bonjour %1$s, est-ce toujours disponible ? Bonjour, est-ce toujours disponible ? - Vendre un Objet Titre iPhone 13 État Catégorie Prix (en Sats) - 1000 Emplacement Ville, État, Pays Neuf @@ -1016,20 +1140,13 @@ Autres Échec du téléversement du fichier Impossible d\'ouvrir le fichier compressé - Erreur lors de la compression du média : %1$s Erreur de téléversement : %1$s Le serveur n\'a pas fourni d\'URL après le téléversement Impossible de télécharger le média depuis le serveur Impossible de vérifier le fichier téléchargé après le téléversement : %1$s - Impossible de préparer le fichier local à téléverser: %1$s Impossible de téléverser vers %1$s: %2$s - Échec du téléversement: %1$s Échec de la suppression : %1$s Le média est trop volumineux pour NIP-95 - Impossible de charger la miniature - Impossible de préparer les informations d\'en-tête : %1$s - Compression annulée - La compression n\'a pas réussi à renvoyer un fichier Chiffrer les fichiers Qualité des médias Sélectionnez une qualité basse pour compresser vos médias en un fichier plus petit, avec moins de qualité ou sélectionnez qualité haute pour compresser en un fichier plus grand, avec une meilleure qualité. @@ -1039,25 +1156,20 @@ Non compressé Utiliser le codec H.265/HEVC Une meilleure qualité avec des tailles de fichier plus petites, mais tous les appareils ne supportent pas la lecture H.265. + Convertir GIF en MP4 Supprimer les métadonnées privées Modifier le brouillon Se connecter avec un QR Code - Route Accueil - Rechercher Découvrir Messages Notifications - Général Vidéos courtes Échecs Portefeuille - Solde Envoyer Recevoir Transactions - Aucun portefeuille connecté - Configurer le portefeuille sats Coller une facture BOLT-11 Payer @@ -1076,13 +1188,119 @@ Tout Zaps Non Zaps + Ajouter un portefeuille + Défaut + Définir comme défaut + Supprimer + Supprimer ce portefeuille ? + Nom du portefeuille + Mon portefeuille + Aucun portefeuille connecté + Ajouter une connexion NWC + Portefeuille Cashu (NIP-60) + Portefeuille Cashu + Recevoir + Montant (sats) + Copier la facture + Demande de facture + Rejeter la facture + Reçu + Envoyé + Paramètres du portefeuille Cashu + Importer une clé + Supprimer le portefeuille + Supprimer ce portefeuille ? + Payer la facture + Renommer + Renommer le portefeuille + Transactions On-chain + En attente + Public + Ce portefeuille est public + Compris + Copier l\'adresse - Filtres de Sécurité + Envoyer le zap on-chain + Fermer + À + Auteur du message + Destinataire + nom, NIP-05 ou npub + Changer le destinataire + Montant + sats + Commentaire (optionnel) + Priorité + Lent + Normal + Rapide + ~1 h + ~30 min + ~10 min Nouveau Message Nouveaux Shorts : images ou vidéos Nouvelle Note Communautaire Nouveau produit - Nouveau message géo-exclusif + Nouvel Article + Nouveau sondage + Nouvelle image + Nouvel événement de calendrier + Modifier l\'événement de calendrier + Verrouillé lors de l\'édition — modifier ceci créerait un nouvel événement à la place. + Nouveau calendrier + Modifier le calendrier + Mois + Semaine + Jour + À venir + Passé + Votre calendrier est vide + Rien de planifié + Aucun événement ce jour. Appuyez sur + pour en ajouter un. + Rien cette semaine + Aucun événement ne tombe cette semaine. + Titre + Résumé + Emplacement + URL de l\'image + Événement journée entière + Débute + Termine + Hashtags (séparés par des virgules) + Choisir la date + Choisir l\'heure + Le titre et le début sont requis. + La fin doit être après le début. + Mois précédent + Mois suivant + Semaine précédente + Semaine suivante + Jour précédent + Jour suivant + Ajouter au calendrier du téléphone + Aller à aujourd\'hui + + %1$s, %2$d événement + %1$s, %2$d événements + + %1$s, aucun événement + Le téléversement de l\'image a échoué + L\'image sélectionnée n\'a pas pu être téléversée. Réessayez ou collez une URL. + Participants (%1$d) + Chercher un nom, npub, ou nip-05 + Retirer le participant + Rappels du calendrier + Envoyer des rappels + Tous les calendriers + Vous n\'avez pas encore créé de calendriers. + Ouvrir dans la carte + Ouvrir le lien + Détails de l\'événement + Résumé (optionnel) + Prévisualiser + Modifier + Ajouter une image d\'en-tête + Le titre de votre article\u2026 Ouvrir toutes les réactions à ce message Fermer toutes les réactions à ce message Répondre @@ -1107,18 +1325,14 @@ Relais %1$s Développer la liste des relais Options de la note - Sélecteur de liste de relais Sondage Désactiver le Sondage Facture Bitcoin Annuler la Facture Bitcoin - Annuler la Vente d\'un Objet Collecte de Zaps Annuler la Collecte de Zaps Emplacement Retirer l\'Emplacement - Partage des Zaps - Annuler le partage des Zaps Ajouter un avertissement de contenu Retirer l\'avertissement de contenu Ajouter une date d\'expiration @@ -1133,11 +1347,8 @@ Adresse invalide Amethyst a reçu une URI à ouvrir mais cette URI était invalide : %1$s Relais de boîte de réception MP - Relais: %1$s - Utilisation des relais réguliers Configurer vos relais de messagerie privée Ce paramètre informe tout le monde les relais à utiliser pour vous envoyer des messages. Sans eux, vous risquez de manquer certains messages. - Les bonnes options sont:\n - inbox.nostr.wine (payant)\n - auth.nostr1.com (gratuit)\n - you.nostr1.com (relais personnels - payant) De bonnes options sont:\n - auth.nostr1.com (gratuit)\n - inbox.nostr.wine (payant)\n - relay.0xchat.com (gratuit) Insérez entre 1–3 relais pour utiliser de boîte de réception privée. Les relais de boîte de réception MP doivent accepter les messages de tout le monde, mais ne vous permet que de les télécharger. Configurer maintenant @@ -1155,7 +1366,6 @@ Créer une liste de relais spécialement conçue pour recevoir des notifications est crucial pour votre expérience Nostr. Insérez entre 1 et 3 relais qui reçoivent des notifications pour vous. Assurez-vous qu\'ils n\'exigent pas de paiement ou de web de confiance de la part de l\'expéditeur, sinon vous ne recevrez que des notifications des payeurs ou des utilisateurs à long terme De bonnes options sont :\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social - Téléversement de MP Paramètres du relais Relais publics d\'accueil L\'utilisateur publie son contenu sur ces relais @@ -1168,12 +1378,8 @@ Insérez de 1 à 3 relais pour servir de boîte de réception privée. Les autres utilisateurs utiliseront ces relais pour vous envoyer des MPs. Les relais de la boîte de réception MP doivent accepter tout message de tout le monde, mais ne vous permet que de les télécharger. De bonnes options sont:\n - inbox.nostr.wine (payant)\n - auth.nostr1.com (gratuit)\n - you.nostr1.com (relais personnels - payant) Relais privés Insérez entre 1 et 3 relais pour stocker des événements que personne d\'autre ne peut voir, comme vos Brouillons et/ou paramètres d\'application. Idéalement, ces relais sont soit locaux soit nécessitent une authentification avant de télécharger le contenu de chaque utilisateur. - Relais généraux - Amethyst utilise ces relais pour télécharger des messages pour vous. Relais connectés Liste actuelle des relais utilisés - Relais recommandés - Ajoutez les relais suivants à votre liste de relais généraux afin de recevoir les messages des utilisateurs listés. Relais de recherche Liste des relais à utiliser pour la recherche et l\'étiquetage des utilisateurs. L\'étiquetage et la recherche ne fonctionneront pas si aucune option n\'est disponible. Relais locaux @@ -1202,11 +1408,8 @@ Cette version vous a été apportée par : Version %1$s Merci ! - Limite maximale Écritures limitées Forké depuis - FORK - Dépôt Git : %1$s Web : Clone : OTS: %1$s @@ -1214,20 +1417,13 @@ Il y a une preuve que ce message a été signé avant %1$s. La preuve a été estampillée dans la blockchain Bitcoin à cette date et à cette heure. Modifier le Message Proposition pour améliorer votre publication - Récapitulatif des modifications - Corrections rapides … Accepter la Suggestion Lancer la vidéo dans une popup Télécharger - Paroles activées - Paroles désactivées - Message scellé désactivé. Cliquer pour activer le message scellé - Message scellé activé. Cliquer pour désactiver le message scellé Envoyer Écouter le nom d\'utilisateur Punaise Scanner le QR code - Accéder au fournisseur de portefeuille tiers Alby Sélectionner la date Il n\'est pas possible de répondre à un brouillon Il n\'est pas possible de citer un brouillon @@ -1269,23 +1465,18 @@ Stockage insuffisant - Le serveur n\'a pas assez d\'espace pour traiter la demande avec succès Boucle détectée - Le serveur détecte une boucle infinie lors du traitement de la requête Authentification réseau requise - Le client doit être authentifié pour accéder au réseau - Serveurs NIP-96 - Ajoutez autant de serveurs que vous le souhaitez. Vous pourrez choisir celui à utiliser plus tard lors du téléversement de votre image Serveurs Blossom Ajoutez autant de serveurs que vous le souhaitez. Vous pourrez choisir celui à utiliser plus tard lors du téléversement de votre image Ajouter un serveur NIP-96 Ajouter un serveur Blossom Tout supprimer Êtes-vous sûr de vouloir supprimer tous les brouillons ? - Pile : Fichier torrent Télécharger Échec de l\'ouverture du fichier Aucune application torrent installée pour ouvrir et télécharger le fichier. L\'événement ne possède pas assez d\'informations pour construire un lien magnet - Mes listes Mes listes - Utilisateurs Sélectionnez une liste pour filtrer le fil Flux Hashtags @@ -1296,7 +1487,6 @@ Message privé Message public Relais de chat - Le relais auquel tous les utilisateurs de ce chat se connectent Partager l\'image… Impossible de partager l\'image, veuillez réessayer plus tard… Partager la vidéo… @@ -1324,7 +1514,6 @@ Rapport d\'erreur trouvé Voulez-vous envoyer le rapport d\'erreur récent à Amethyst dans un MP ? Aucune information personnelle ne sera partagée Envoyer - Ce message disparaîtra dans %1$d jours Sélectionner un signataire Déjà dans la liste Membres privés @@ -1340,7 +1529,6 @@ Nom du pack Nom du nouveau pack Description du pack - Description du nouveau pack Liste de diffusion Pack de diffusion Supprimer la liste @@ -1354,13 +1542,9 @@ Réduire Agrandir Échec de la nouvelle tentative (%1$d) - +%1$d diffusions supplémentaires - " (%1$d en cours)" - Relais %1$d/%2$d Délai expiré Nouvelle tentative… Réessayer - Afficher Fermer %1$d/%2$d Diffusion @@ -1385,7 +1569,6 @@ Redémarrer Accepter Refuser - Nouveau jeu Nouvelle partie d\'échecs Chargement de la partie\u2026 Partie introuvable @@ -1440,12 +1623,8 @@ Sélectionnez les utilisateurs à suivre Profil à importer depuis recherche, npub1…, alice@exemple.com - Rechercher un autre - Importer plus - Continuer Ignorer pour le moment Tout sélectionner - Recommencer Annuler @@ -1456,4 +1635,10 @@ + + Le service lightning du récepteur à %1$s n\'est pas disponible. Il a été calculé à partir de l\'adresse lightning \"%2$s\". Erreur: %3$s. Vérifiez si le serveur est en ligne et si l\'adresse lightning est correcte + Impossible de résoudre %1$s. Vérifiez si vous êtes connecté, si le serveur est actif et si l\'adresse Lightning %2$s est correcte.\n\nL\'erreur était : %3$s + Erreur lors de l\'analyse du JSON de la facture de %1$s. Vérifiez la configuration lightning de l\'utilisateur + Impossible de créer une facture lightning. Message de %1$s: %2$s + Impossible de créer une facture lightning avec %1$s. Élément pr introuvable dans le JSON résultant. diff --git a/amethyst/src/main/res/values-fr/strings.xml b/amethyst/src/main/res/values-fr/strings.xml index 2272f85208..981e9e2438 100644 --- a/amethyst/src/main/res/values-fr/strings.xml +++ b/amethyst/src/main/res/values-fr/strings.xml @@ -21,8 +21,6 @@ Comportement illégal Autre Harcèlement - inconnu - Icône de relais Auteur inconnu Copier le texte Copier la clé publique de l\'utilisateur @@ -36,12 +34,9 @@ Signaler Spam / Arnaque Signaler une falsification d\'identité - Signaler un contenu choquant Signaler un comportement illégal Signaler un programme malveillant - Signaler le mod Programme malveillant - Mod Connectez vous avec une clé privée pour pouvoir répondre Connectez vous avec une clé privée pour pouvoir booster des posts Connectez vous avec une clé privée pour pouvoir aimer des posts @@ -52,7 +47,6 @@ Vous utilisez une clé publique et les clés publiques sont en lecture seule. Connectez-vous avec une clé privée pour pouvoir masquer un mot ou une phrase Vous utilisez une clé publique et les clés publiques sont en lecture seule. Connectez-vous avec une clé privée pour pouvoir afficher un mot ou une phrase Zaps - Nombre de vues Boost boosté modifié @@ -65,9 +59,7 @@ Ajouter "répondre à " " et " - "dans le canal " Bannière du profil - Paiement Réussi Erreur d\'analyse du message d\'erreur " Abonnements" " Abonnés" @@ -89,9 +81,7 @@ Préfixe visible 😎 Ajouter au message - "Erreur d'analyse de l'aperçu pour %1$s : %2$s" "Aperçu de l'image pour %1$s" - Nouveau canal Nom de canal Mon groupe spectaculaire Url de l\'image @@ -103,33 +93,18 @@ Sauvegarder Créer Annuler - Échec du téléchargement de l\'image - Adresse du relais - Publications - Octets Erreurs - Le nombre d\'erreurs de connexion dans cette session - Vos notifications - Flux de messages privés - Flux de chat public - Flux mondial - Flux de recherche Ajouter un relais - Nom Nom visible du public Mon nom visible du public Ostrich McGénial Bienvenue Ostrich! Nom d\'utilisateur - Mon nom d\'utilisateur Biographie URL de l\'avatar URL de la bannière URL de site Pronoms - Adresse LN - URL LN (obsolete) - Enregistrer dans la Galerie Image enregistrée dans la galerie Le téléchargement de la vidéo a démarré… Le téléchargement du média a démarré… @@ -137,11 +112,8 @@ Vidéo enregistrée dans la galerie vidéo du téléphone Impossible d\'enregistrer la vidéo Charger une image - Chargement… L\'utilisateur n\'a pas configuré d\'adresse Lightning pour recevoir des sats "répondre ici" - Copie l\'ID de note dans le presse-papiers pour le partage sur Nostr - Copier l\'ID de la chaîne (Note) dans le presse-papiers Modifie les métadonnées du canal Joindre Connus @@ -153,18 +125,14 @@ Réponses Les vôtres Galerie - "Suivis" "Signalements" Plus d\'options " Relais" Site Web Adresse Lightning Copie l\'ID Nsec (votre mot de passe) dans le presse-papiers pour le sauvegarder - Copier la clé secrète dans le presse-papiers Afficher le QR code de la clé privée Afficher le QR code de la clé privée chiffrée - Copie la clé publique dans le presse-papiers pour la partager - Copier la clé publique (NPub) dans le presse-papiers Envoyer un message direct Modifie les métadonnées de l\'utilisateur Suivre @@ -193,8 +161,6 @@ Comment devrions-nous vous appeler ? Vous n\'avez pas de compte Nostr ? Vous avez déjà un compte Nostr ? - Créer un nouveau compte - Générer une nouvelle clé Chargement du flux Chargement du compte "Erreur lors du chargement des réponses : " @@ -202,12 +168,6 @@ Aucune notification pour le moment. Le flux est vide. Rafraîchir - créé - avec le descriptif de - et photo - changé le nom du chat en - descriptif à - et image à Partir Ne plus suivre Canal créé @@ -233,7 +193,6 @@ Blasphème / Discours haineux Signaler Discours haineux Signaler Nudité / Porno - autres Marquer tous les Connus comme lu Marquer tous les Nouveaux comme lu Tout marquer comme lu @@ -254,23 +213,18 @@ Échec de l\'authentification La biométrie n\'a pas pu authentifier le propriétaire de ce téléphone La biométrie n\'a pas pu authentifier le propriétaire de ce téléphone. Erreur : %1$s - Erreur - "Créé par %1$s" "Image de badge pour %1$s" Vous avez reçu un nouveau Badge Le Badge a été décerné à Copie du contenu de la note dans le presse-papiers Copie du @npub utilisateur dans le presse-papiers Copie de l\'ID de la note (@note1) dans le presse-papiers - Sélectionner le Texte "<Impossible de déchiffrer le message privé>\n\nVous avez été cité dans une conversation privée/cryptée entre %1$s et %2$s." Ajouter un Nouveau Compte Comptes Sélectionner un Compte Ajouter un Nouveau Compte Compte actif - Avec une clé privée - Lecture seule, pas de clé privée Retour Sélectionner Partager le Lien Navigateur @@ -288,14 +242,12 @@ Supprimer Bloquer Signaler - Supprimer Ne plus montrer Spam ou arnaque Grossièreté ou contenu haineux Usurpation d\'identité Nudité ou contenu graphique Comportement illégal - Programme malveillant Bloquer un utilisateur cachera son contenu dans votre application. Vos notes sont toujours visibles publiquement, y compris pour les personnes que vous bloquez. Les utilisateurs bloqués sont listés sur l\'écran Filtres de Sécurité. Signaler un Abus @@ -315,30 +267,15 @@ Ajouter aux Favoris Publics Supprimer des Favoris Privés Supprimer des Favoris Publics - Service Wallet Connect - Autorise un Nostr Secret à payer des zaps sans quitter l\'application. Gardez le secret en toute sécurité et utilisez un relais privé si possible - Clé publique Wallet Connect - Relais Wallet Connect - Secret Wallet Connect - Montrer la clé secrète - Clé privée nsec / hex Montant engagé en Sats - Message Sondage - Champs requis: - Bénéficiaires du Zap - Description du sondage primaire… Option %s Description de l\'option du Sondage - Champs optionnels : Zap minimum Zap maximum Consensus (0–100)% - Clôturer après - jours Impossible de voter Le Sondage est fermé aux nouveaux votes - Montant des Zap Un seul vote par utilisateur est autorisé sur ce type de sondage "Recherche de l'Événement %1$s" Ajouter un message public @@ -372,12 +309,9 @@ Aucune trace sur Nostr, seulement sur le Lightning Serveur fichier Choisissez un serveur vers lequel téléverser ce fichier - Adresse LN ou @Utilisateur Serveurs média Définissez vos serveurs de téléversement de média préférés. - Vous n\'avez pas de serveur NIP-96 défini. Vous pouvez utiliser la liste d\'Amethyst, ou en ajouter un ci-dessous ↓ Vous n\'avez pas de serveur Blossom défini. Vous pouvez utiliser la liste d\'Amethyst, ou en ajouter un ci-dessous ↓ - Serveurs média intégrés Liste par défaut d\'Amethyst. Vous pouvez les ajouter individuellement ou ajouter la liste. Utiliser la liste par défaut Ajouter un serveur média @@ -390,31 +324,16 @@ Hachage Terminé Erreur - Vos relais (NIP-95) - Les fichiers sont hébergés par vos relais. Nouveau NIP: vérifiez s\'ils sont supportés Options de confidentialité - Configuration Tor/Orbot - Se connecter à travers la configuration Orbot Ajuster Paramètres Tor - Se déconnecter de Orbot/Tor? - Vos données seront immédiatement transférées sur le réseau classique Oui Non - Liste des Abonnés Tous les abonnements Autour de moi Général Liste en Sourdine Le port par défaut est 9050 - ## Se connecter à travers Tor avec Orbot - \n\n1. Installe [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Démarre Orbot - \n3. Dans Orbot, vérifie le port Socks. Par défaut 9050 - \n4. Si nécessaire change le port dans Orbot - \n5. Configure le port Socks sur cet écran - \n6. Appuyer sur le bouton Activer pour utiliser Orbot comme proxy - Port Socks Orbot Activer le moteur Tor Utiliser la version interne ou Orbot @@ -456,8 +375,6 @@ Masque votre IP pour toutes les connexions Faites votre choix manuellement Numéro de port invalide - Utiliser Orbot - Déconnecter Tor/Orbot Messages privés Vous notifie lorsqu\'un message privé est reçu Zaps reçus @@ -466,20 +383,9 @@ De %1$s pour %1$s Notifier: - Rejoindre Conversation - Utilisateur ou Groupe ID - npub, nevent ou hex - Créer - Rejoindre Aujourd\'hui Avertissement de contenu Ce message contient du contenu sensible que certaines personnes peuvent trouver offensant ou dérangeant - Toujours cacher les contenus sensibles - Toujours afficher les contenus sensibles - Toujours afficher les avertissements de contenu - Recommendations: - Filtrer le spam des inconnus - Avertir lorsque les messages ont été rapportés par vos abonnés Nouveau symbole de réaction Aucun type de réaction sélectionné. Appuyer longuement pour changer Collecte de Zaps @@ -490,37 +396,24 @@ Écrire sur le Relay Le nombre d\'octets qui ont été envoyés à ce relais, y compris les filtres et les événements Le nombre d\'octets qui ont été reçus depuis ce relais, y compris les filtres et les événements - Une erreur s\'est produite en récupérant les informations du relay depuis %1$s Propriétaire Version Logiciel Contact NIPs supportés - Frais d\'admission URL de payments Limites Pays Langages - Étiquettes Politique de publication Erreurs et Notifications de ce Relais - Longueur du message - Abonnements - Filtres - Longueur de l\'id de souscription Préfixe minimum Tags d\'événement maximum - Longueur du contenu PoW minimum - Authentification - Paiement Jeton Cashu Échanger - Envoyer vers le portefeuille Zap - Ouvrir dans le portefeuille Cashu Copier le Jeton Adresse Lightning non définie - Jeton copié dans le presse-papiers EN DIRECT DÉCONNECTÉ TERMINÉ @@ -540,7 +433,6 @@ Préférences de l\'application Paramètres Toujours - Wifi uniquement WiFi illimité Jamais Complet @@ -564,7 +456,6 @@ Choisir le style du message Style de la galerie de profil Choisissez le style de la galerie - Charger l\'image Spammeurs Silencieux. Cliquer pour réactiver le son Son activé. Cliquer pour mettre en silencieux @@ -572,12 +463,8 @@ L\'adresse Nostr a été vérfiée La vérification de l\'adresse Nostr a échouée Vérification de l\'adresse Nostr - Tout sélectionner/désélectionner Défaut Rétablir les valeurs par défaut - Sélectionner un relay pour continuer - Transférer les Zaps à: - Les clients compatibles transmettront des zaps sur l\'adresse LN ou le profil Utilisateur ci-dessous au lieu du vôtre. Révéler la localisation comme Ajoute un Geohash de votre emplacement au message. Le public saura que vous êtes à moins de 5km de l\'emplacement actuel Post exclusif à la localisation @@ -585,9 +472,6 @@ Chargement de la localisation Pas d\'autorisations de localisation Ajoute un avertissement de contenu sensible avant de montrer votre contenu. C\'est idéal pour tout contenu NSFW ou contenu que certaines personnes peuvent trouver offensant ou dérangeant - Nouvelle Fonctionnalité - Pour activer ce mode, Amethyst doit envoyer un message NIP-17 (GiftWrapped, Sealed Direct et Group Messages). Le protocole NIP-17 est nouveau et la plupart des clients ne l\'ont pas encore mis en oeuvre. Assurez-vous que le destinataire utilise un client compatible. - Activer Public Nouveau Groupe Public ou Privé Privé @@ -604,7 +488,6 @@ Charger automatiquement les images et les GIFs Lire automatiquement les vidéos et les GIFs Afficher la prévisualisation d\'URL - Quand charger les images Copier dans le presse-papiers Copier dans le presse-papiers Copier npub dans le presse-papiers @@ -615,45 +498,23 @@ Média ajouté Média ajouté à votre galerie de profil Créé le - Règles Se connecter avec Amber Mettez à jour votre statut - Erreur d\'analyse du message d\'erreur Les votes sont pondérés par le montant du zap. Vous pouvez définir un montant minimum pour éviter les spammeurs et un montant maximum pour éviter qu\'un grand nombre de zappeurs ne prenne le contrôle du sondage. Utilisez le même montant dans les deux champs pour vous assurer que chaque vote a la même valeur. Laissez le champ vide pour accepter n\'importe quel montant. Impossible d\'envoyer un zap Contacter l\'utilisateur Message %1$s Ok - Impossible d\'atteindre %1$s: %2$s - Impossible d\'assembler l\'URL NIP-11 pour %1$s: %2$s - Impossible d\'accéder à %1$s: %2$s - Impossible d\'analyser la réponse depuis %1$s: %2$s - Le Relais a refusé la requête %1$s: %2$s - Impossible d\'atteindre %1$s: %2$s - Impossible d\'analyser le résultat de %1$s: %2$s - %1$s a échoué avec le code %2$s - Actif pour : - Accueil - MPs - Salons - Général - Rechercher Diviser et Transférer des Zaps Les clients supportés vont diviser et transférer les zaps aux utilisateurs ajoutés ici au lieu du vôtre Rechercher et Ajouter un Utilisateur Nom d\'utilisateur ou nom affiché Configuration lightning manquante L\'utilisateur %1$s n\'a pas configuré d\'adresse Lightning pour recevoir des sats - Pourcentage - 25 - Diviser les zaps avec - Transférer les zaps à - Portefeuilles Lightning introuvables Payé Portefeuille %1$s Erreur lors de l\'ouverture de l\'application de signature L\'application signataire est introuvable. Vérifiez que l\'application n\'a pas été désinstallée - Demande de signature rejetée Assurez-vous que l\'application signataire a autorisé cette transaction Aucun portefeuille trouvé pour payer une facture lightning (Erreur : %1$s). Veuillez installer un portefeuille Lightning pour utiliser les zaps Aucun portefeuille trouvé pour payer une facture lightning. Veuillez installer un portefeuille Lightning pour utiliser les zaps @@ -664,36 +525,19 @@ Sélectionnez une option Impossible de payer la facture Impossible de retirer - Impossible de configurer Wallet Connect - Erreur lors de l\'analyse de l\'événement de connexion NIP-47. Vérifiez si tout est correct avec le prestataire de votre Portefeuille : %1$s. Erreur : %2$s - Erreur lors de l\'analyse de l\'événement de connexion NIP-47. Vérifiez si tout est correct avec le prestataire de votre Portefeuille : %1$s. Impossible d\'utiliser ce Cashu Le Mint a fourni le message d\'erreur suivant : %1$s - Les jetons de cashu sont déjà dépensés. Cashu reçu %1$s sats ont été envoyés à votre portefeuille. (Frais : %2$s sats) Aucun portefeuille Cashu compatible trouvé dans le système Impossible de récupérer la facture depuis les serveurs du destinataire Le fournisseur de connexion de votre portefeuille a retourné l\'erreur suivante : %1$s - Impossible de se connecter à Tor - Téléchargement du document relais indisponible Impossible d\'assembler LNUrl à partir de l\'adresse Lightning \"%1$s\". Vérifiez la configuration de l\'utilisateur - Le service lightning du récepteur à %1$s n\'est pas disponible. Il a été calculé à partir de l\'adresse lightning \"%2$s\". Erreur: %3$s. Vérifiez si le serveur est en ligne et si l\'adresse lightning est correcte - Impossible de résoudre %1$s. Vérifiez si vous êtes connecté, si le serveur est en ligne et si l\'adresse lightning %2$s est correcte - Impossible de résoudre %1$s. Vérifiez si vous êtes connecté, si le serveur est actif et si l\'adresse Lightning %2$s est correcte.\n\nL\'erreur était : %3$s - Impossible de récupérer la facture depuis %1$s Impossible de récupérer la facture à partir de %1$s: %2$s - Erreur lors de l\'analyse du JSON à partir de l\'Adresse Lightning. Vérifiez la configuration lightning de l\'utilisateur Erreur lors de l\'analyse du JSON de %1$s. Vérifiez la configuration lightning de l\'utilisateur - URL de callback introuvable dans la configuration serveur de l\'adresse lightning de l\'utilisateur URL de callback introuvable dans la réponse de %1$s - Erreur lors de l\'analyse du JSON à partir de la récupération de la facture de l\'Adresse Lightning. Vérifiez la configuration Lightning de l\'utilisateur - Erreur lors de l\'analyse du JSON de la facture de %1$s. Vérifiez la configuration lightning de l\'utilisateur Montant de la facture (%1$s sats) incorrect de %2$s. Il aurait dû être %3$s Impossible de créer une facture lightning avant d\'envoyer le zap. Le portefeuille lightning du destinataire a envoyé l\'erreur suivante : %1$s - Impossible de créer une facture lightning. Message de %1$s: %2$s - Impossible de créer une facture lightning avant d\'envoyer le zap. Élément pr introuvable dans le JSON résultant. - Impossible de créer une facture lightning avec %1$s. Élément pr introuvable dans le JSON résultant. Utilisateur en lecture seule Aucune réaction configurée Sélectionnez une application UnifiedPush @@ -711,13 +555,11 @@ Envoyer un message au vendeur Bonjour %1$s, est-ce toujours disponible ? Bonjour, est-ce toujours disponible ? - Vendre un Objet Titre iPhone 13 État Catégorie Prix (en Sats) - 1000 Emplacement Ville, État, Pays Neuf @@ -746,20 +588,13 @@ Autres Échec du téléversement du fichier Impossible d\'ouvrir le fichier compressé - Erreur lors de la compression du média : %1$s Erreur de téléversement : %1$s Le serveur n\'a pas fourni d\'URL après le téléversement Impossible de télécharger le média depuis le serveur Impossible de vérifier le fichier téléchargé après le téléversement : %1$s - Impossible de préparer le fichier local à téléverser: %1$s Impossible de téléverser vers %1$s: %2$s - Échec du téléversement: %1$s Échec de la suppression : %1$s Le média est trop volumineux pour NIP-95 - Impossible de charger la miniature - Impossible de préparer les informations d\'en-tête : %1$s - Compression annulée - La compression n\'a pas réussi à renvoyer un fichier Qualité des médias Sélectionnez une qualité basse pour compresser vos médias en un fichier plus petit, avec moins de qualité ou sélectionnez qualité haute pour compresser en un fichier plus grand, avec une meilleure qualité. Basse @@ -768,15 +603,11 @@ Non compressé Modifier le brouillon Se connecter avec un QR Code - Route Accueil - Rechercher Découvrir Messages Notifications - Général Vidéos courtes - Filtres de Sécurité Nouveau Message Nouveaux Shorts : images ou vidéos Nouvelle Note Communautaire @@ -791,29 +622,22 @@ Relais %1$s Développer la liste des relais Options de la note - Sélecteur de liste de relais Sondage Désactiver le Sondage Facture Bitcoin Annuler la Facture Bitcoin - Annuler la Vente d\'un Objet Collecte de Zaps Annuler la Collecte de Zaps Emplacement Retirer l\'Emplacement - Partage des Zaps - Annuler le partage des Zaps Ajouter un avertissement de contenu Retirer l\'avertissement de contenu Afficher npub en tant que QR code Adresse invalide Amethyst a reçu une URI à ouvrir mais cette URI était invalide : %1$s Relais de boîte de réception MP - Relais: %1$s - Utilisation des relais réguliers Configurer vos relais de messagerie privée Ce paramètre informe tout le monde les relais à utiliser pour vous envoyer des messages. Sans eux, vous risquez de manquer certains messages. - Les bonnes options sont:\n - inbox.nostr.wine (payant)\n - auth.nostr1.com (gratuit)\n - you.nostr1.com (relais personnels - payant) De bonnes options sont:\n - auth.nostr1.com (gratuit)\n - inbox.nostr.wine (payant)\n - relay.0xchat.com (gratuit) Insérez entre 1–3 relais pour utiliser de boîte de réception privée. Les relais de boîte de réception MP doivent accepter les messages de tout le monde, mais ne vous permet que de les télécharger. Configurer maintenant @@ -822,7 +646,6 @@ La création d\'une liste de relais spécialement conçue pour la recherche et l\'étiquetage utilisateur améliorera ces résultats. Insérez de 1 à 3 relais à utiliser lors de la recherche de contenu ou de l\'étiquetage utilisateur. Assurez-vous que les relais que vous avez choisis implémentent le NIP-50 De bonnes options sont:\n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com - Téléversement de MP Paramètres du relais Relais publics d\'accueil Ce type de relais stocke tout votre contenu. Amethyst enverra vos messages ici et d\'autres utiliseront ces relais pour trouver votre contenu. Insérez entre 1 et 3 relais : il peut s\'agir de relais personnels, de relais payants ou de relais publics. @@ -832,10 +655,6 @@ Insérez de 1 à 3 relais pour servir de boîte de réception privée. Les autres utilisateurs utiliseront ces relais pour vous envoyer des MPs. Les relais de la boîte de réception MP doivent accepter tout message de tout le monde, mais ne vous permet que de les télécharger. De bonnes options sont:\n - inbox.nostr.wine (payant)\n - auth.nostr1.com (gratuit)\n - you.nostr1.com (relais personnels - payant) Relais privés Insérez entre 1 et 3 relais pour stocker des événements que personne d\'autre ne peut voir, comme vos Brouillons et/ou paramètres d\'application. Idéalement, ces relais sont soit locaux soit nécessitent une authentification avant de télécharger le contenu de chaque utilisateur. - Relais généraux - Amethyst utilise ces relais pour télécharger des messages pour vous. - Relais recommandés - Ajoutez les relais suivants à votre liste de relais généraux afin de recevoir les messages des utilisateurs listés. Relais de recherche Liste des relais à utiliser pour la recherche et l\'étiquetage des utilisateurs. L\'étiquetage et la recherche ne fonctionneront pas si aucune option n\'est disponible. Relais locaux @@ -847,11 +666,8 @@ Cette version vous a été apportée par : Version %1$s Merci ! - Limite maximale Écritures limitées Forké depuis - FORK - Dépôt Git : %1$s Web : Clone : OTS: %1$s @@ -859,19 +675,12 @@ Il y a une preuve que ce message a été signé avant %1$s. La preuve a été estampillée dans la blockchain Bitcoin à cette date et à cette heure. Modifier le Message Proposition pour améliorer votre publication - Récapitulatif des modifications - Corrections rapides … Accepter la Suggestion Télécharger - Paroles activées - Paroles désactivées - Message scellé désactivé. Cliquer pour activer le message scellé - Message scellé activé. Cliquer pour désactiver le message scellé Envoyer Écouter le nom d\'utilisateur Punaise Scanner le QR code - Accéder au fournisseur de portefeuille tiers Alby Il n\'est pas possible de répondre à un brouillon Il n\'est pas possible de citer un brouillon Il n\'est pas possible de réagir à un brouillon @@ -912,19 +721,21 @@ Stockage insuffisant - Le serveur n\'a pas assez d\'espace pour traiter la demande avec succès Boucle détectée - Le serveur détecte une boucle infinie lors du traitement de la requête Authentification réseau requise - Le client doit être authentifié pour accéder au réseau - Serveurs NIP-96 - Ajoutez autant de serveurs que vous le souhaitez. Vous pourrez choisir celui à utiliser plus tard lors du téléversement de votre image Serveurs Blossom Ajoutez autant de serveurs que vous le souhaitez. Vous pourrez choisir celui à utiliser plus tard lors du téléversement de votre image Ajouter un serveur NIP-96 Ajouter un serveur Blossom Tout supprimer Êtes-vous sûr de vouloir supprimer tous les brouillons ? - Pile : Fichier torrent Télécharger Échec de l\'ouverture du fichier Aucune application torrent installée pour ouvrir et télécharger le fichier. Sélectionnez une liste pour filtrer le fil Se déconnecter au verrouillage de l\'appareil + Le service lightning du récepteur à %1$s n\'est pas disponible. Il a été calculé à partir de l\'adresse lightning \"%2$s\". Erreur: %3$s. Vérifiez si le serveur est en ligne et si l\'adresse lightning est correcte + Impossible de résoudre %1$s. Vérifiez si vous êtes connecté, si le serveur est actif et si l\'adresse Lightning %2$s est correcte.\n\nL\'erreur était : %3$s + Erreur lors de l\'analyse du JSON de la facture de %1$s. Vérifiez la configuration lightning de l\'utilisateur + Impossible de créer une facture lightning. Message de %1$s: %2$s + Impossible de créer une facture lightning avec %1$s. Élément pr introuvable dans le JSON résultant. diff --git a/amethyst/src/main/res/values-gu-rIN/strings.xml b/amethyst/src/main/res/values-gu-rIN/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-gu-rIN/strings.xml +++ b/amethyst/src/main/res/values-gu-rIN/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-hi-rIN/strings.xml b/amethyst/src/main/res/values-hi-rIN/strings.xml index 91f096889c..d3f11037a2 100644 --- a/amethyst/src/main/res/values-hi-rIN/strings.xml +++ b/amethyst/src/main/res/values-hi-rIN/strings.xml @@ -32,8 +32,6 @@ अन्य उत्पीडन हिंसा - अज्ञात - पनःप्रसारक चिह्न अज्ञात लेखक लेख की अनुकृति करें लेखक विभेदक की अनुकृति करें @@ -48,12 +46,9 @@ कचरालेख / घोटाला की सूचना दें पररूपण की सूचना दें - अभद्र विषयवस्तु की सूचना दें अवैध बरताव की सूचना दें दुष्क्रमक की सूचना दें - विकृति की सूचना दें दुष्क्रमक - विकृति आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। उत्तर देने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। प्रकाशित पत्रों को उद्धृत करने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। प्रकाशित पत्रों को चाहने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें @@ -67,17 +62,14 @@ आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। अनुचरण रोकने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। शब्द अथवा वाक्य छिपाने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। शब्द अथवा वाक्य आच्छादन हटाने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें - आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। स्थापना विकल्पों का परिवर्तन करने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। आरोहण करने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। घटनाओं पर हस्ताक्षर करने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें अनधिकृत अपरहस्यीकरण हस्ताक्षरकर्ता ने इस कार्य करने के लिए अपरहस्यीकरण का अधिकार नहीं दिया। आपके हस्ताक्षर क्रमक में निप॰-४४ अपरहस्यीकरण सक्रिय करें तथा पुनः प्रयास करें हस्ताक्षरकर्ता अप्राप्त क्या हस्ताक्षर क्रमक अस्थापित किया गया। जाँच करें कि यदि हस्ताक्षरकर्ता स्थापित है तथा यह लेखा वहाँ है। यदि हस्ताक्षर क्रमक में परिवर्तन है तो निर्गमनांकन तथा प्रवेशांकन पुनः करें। - हस्ताक्षरकर्ता द्वारा दुर्व्यवहार बाहरी हस्ताक्षरकर्ता द्वारा दिया गया उत्तर विचित्र है अनुरोध के लिए। अमेथिस्ट अथवा हस्ताक्षरकर्ता में कुछ दोष हो सकता है। ज्साप - दृष्ट संख्या उद्धरण उद्धृत सम्पादित @@ -90,9 +82,7 @@ जोडें "उत्तर इनको " " तथा " - "प्रणाली अभ्यन्तर " परिचय पृष्ठ चौडाचित्र - भुगतान सफल अपक्रम संदेश परखने में अपक्रम " का अनुचरण" " अनुचर" @@ -165,7 +155,6 @@ इस प्राप्तकर्ता द्वारा स्वीकृत किसी टकसाल में शेष पर्याप्त नहीं। पहले अपने काशयू॰ धनकोष का पुनःभरण करें। व्ययक्षमता इस प्राप्तकर्ता के लिए : %1$s साट्स जाल शुल्क - आपका धनकोष क्रमक व्यापार : %1$s लैटनिंग दान ग्राहक के लिए सूचना @@ -179,16 +168,13 @@ दृश्यमान उपसर्ग 😎 पत्र के साथ जोडें - "%1$s का पूर्वीक्षण परखने में अपक्रम : %2$s" "%1$s के लिए पूर्वीक्षण पत्ता चित्र" लेख - नयी प्रणाली प्रणाली नाम मेरा बढिया झुण्ड चित्र जालपता चित्र जालपता (आवश्यक नहीं) विवरण - विवरण अप्राप्त "हमारा परिचय…" आपके मन में क्या है? सन्देश लिखें … @@ -198,42 +184,25 @@ बनाएँ पुनःनामकरण निरस्त करें - चित्र आरोहण असफल - पुनःप्रसारक पता - प्रकाशित पत्र - अष्टक अपक्रम अपक्रम सफल संयोजनों का प्रतिशत पुनःप्रसारक के साथ - संयोजन अपक्रमों की संख्या इस सत्र में - मुख्य सूचनावली - निजी संदेश सूचनावली - सार्वजनिक चर्चा सूचनावली - वैश्विक सूचनावली - खोज सूचनावली ढूँढें तथा प्रयेक्ता जोडें - प्रयोक्ता जोडें पुनःप्रसारक जोडें - नाम - नाम (@सूचक के लिए) मेरा @सूचक नाम प्रदर्शन नाम मेरा प्रदर्शन नाम उष्ट्रपक्षी मक्बढिया स्वागतम उष्ट्रपक्षी! उपयोगकर्ता नाम - मेरा उपयोगकर्ता नाम मेरा परिचय अवतारचित्र जालपता ध्वजचित्र जालपता जालस्थान पता सर्वनाम - लै॰जाल पता - लै॰जाल पता (पुराना) स्रोत पुनःप्रसारक सम्भवतः पुराने हो चुके पुराना पुनःप्रसारक चेतावनी संचारयन्त्र में अभिलेखन करें - चित्रालय में अभिलेखन करें चित्र का अभिलेखन किया गया चित्रालय क्रमक में चलचित्र अवरोहण आरम्भ हुआ … अभिलेख अवरोहण आरम्भ हुआ … @@ -250,15 +219,12 @@ एक चित्र लें चलचित्र का अभिलेखन करें ऐक संदेश का अभिलेखन करें - ऐक संदेश का अभिलेखन करें टाँकें तथा दबाए रखें संदेश का अभिलेखन करने के लिए पुनरभिलेखन ध्वन्यभिलेखन ध्वन्यभिलेखन %1$s - आरोहण चल रहा है… आरोहण अपक्रम ध्वनि सन्देश आरोहण असफल - अनपेक्षित आरोहण स्थिति निप॰९५ का आलम्बन अभी नहीं है ध्वनि सन्देशों के लिए ध्वनि आरोहण असफल : %1$s कुछ भी नहीं @@ -270,8 +236,6 @@ उपयोगकर्ता का कोई लैटनिंग पता स्थापित नहीं जिसपर साट्स प्राप्त कर सके "उत्तर यहाँ दें.. " इस चर्चा में - नोस्ट्र में बाँटने के लिए टीका विभेदक की अनुकृति करता है टाँकाफलक में - प्रणाली विभेदक (टीका) की अनुकृति करें टाँकाफलक में प्रणाली उपतथ्य का सम्पादन करता है जुडें ज्ञात @@ -285,7 +249,6 @@ प्रतिवचन आपका चित्रालय - "अनुचरित" "सूचनाएँ" "%1$s सूचनाएँ" अधिक विकल्प @@ -293,11 +256,8 @@ जालस्थान लैटनिंग पता एनसेक॰ विभेदक (आपका गुप्त पारणशब्द) की अनुकृति करता है टाँकाफलक में सुरक्षित रखने के लिए - गुप्त कुंचिका की अनुकृति करें टाँकाफलक में निजी कुंचिका क्यूआर॰ क्रमचित्र दिखाएँ। रहस्यीकृत निजी कुंचिका क्यूआर॰ क्रमचित्र दिखाएँ। - ख्याप्य कुंचिका की अनुकृति करता है टाँकाफलक में बाँटने के लिए - ख्याप्य कुंचिका (एनपुब॰) की अनुकृति करें टाँकाफलक में सीधा संदेश भेजें उपयोगकर्ता के उपतथ्य का सम्पादन करता है अनुचरण करें @@ -326,8 +286,6 @@ आपको कैसे सम्बोधित करें क्या नोस्ट्र लेखा नहीं है? क्या नोस्ट्र लेखा पहले से है? - नया लेखा बनाएँ - नयी कुंचिका बनाएँ सूचनावली प्राप्त की जा रही है लेखा जानकारी प्राप्त की जा रही है रहस्यीकृत @@ -343,13 +301,7 @@ खुला मतदान सूचनावली रिक्त है। नवीकरण - बनाया गया - इसके विवरण सहित - तथा चित्र - चर्चा नाम यह बना दिया गया नया चर्चा परिचय : - इस विवरण तक - तथा इस चित्र तक निर्गमन अनुचरण ना करें प्रणाली बनायी गयी @@ -386,7 +338,6 @@ नोस्ट्र पता कभी नहीं अभी - सेकण्ड घं॰ मि॰ दि॰ @@ -394,7 +345,6 @@ अपशब्द / द्वेषपूर्ण भाषण द्वेषपूर्ण भाषण की सूचना दें नग्नता / अश्लील चित्र की सूचना दें - अन्य सब ज्ञात को पढ लिया चिह्नित करें सब नये को पढ लिया चिह्नित करें सब को पढ लिया चिह्नित करें @@ -415,8 +365,6 @@ प्रमाणीकरण असफल जैविकमात्राएँ द्वारा इस संचारयन्त्र के अध्यक्ष का प्रमाणीकरण असफल जैविकमात्राएँ द्वारा इस संचारयन्त्र के अध्यक्ष का प्रमाणीकरण असफल। अपक्रम : %1$s - अपक्रम - "%1$s के द्वारा बनाया गया" "पदक पुरस्कार चित्र %1$s के लिए" \"पदक पुरस्कार चित्र आपको नया पदक पुरस्कार प्राप्त हुआ @@ -424,7 +372,6 @@ टीका लेख की अनुकृति की गई टाँकाफलक में लेखक के @npub की अनुकृति की गई टाँकाफलक में टीका विभेदक (@note1) की अनुकृति की गई टाँकाफलक में - लेख चुनें "<निजी संदेश का अरहस्यीकरण असफल>\n\nआप का उल्लेख किया गया एक निजी / रहस्यीकृत संवाद में %1$s तथा %2$s के बीच।" नयी लेखा जोडें लेखाएँ @@ -436,8 +383,6 @@ लेखा चुनें नयी लेखा जोडें सक्रिय लेखा - निजी कुंचिका उपलब्ध - केवल पढ सकते हैं, निजी कुंचिका नहीं पीछे चलें चयन करें जालसंचारक योजक बाँटें @@ -458,14 +403,12 @@ सूत्र मौन करें सूत्र मौन हटाएँ सूचना - मिटाएँ फिर से ना दिखाएँ कचरालेख अथवा घोटाला अपशब्द अथवा द्वेषपूर्ण बरताव दुर्भावनापूर्ण पररूपण नग्नता अथवा आपत्तिजनक विषयवस्तु अवैध बरताव - दुष्क्रमक उपयोगकर्ता को बाधित करने से उनका विषयवस्तु आपके लिए छिपाया जाएगा क्रमक में। आपके टीकाएँ सार्वजनिक रूप से दृश्य रहेंगे, उन जनों के लिए भी जिनहे आपने बाधित किया। बाधित उपयोगकर्ता सूचित हैं सुरक्षा छलनियाँ पटल पर। दुर्व्यवहार की सूचना दें @@ -493,7 +436,6 @@ निर्धारित कार्यसमय का चयन के लिए कार्यसमय… प्रकशन %1$s पश्चात - होना था %1$s पूर्व समय पत्र प्रकाशन समय निर्धारण समय निर्धारण निरस्त @@ -568,7 +510,6 @@ रचयिता अनुरोध स्वीकृतियाँ - कोई भी समुदाय इस छलनी के अनुकूल नहीं। सत्यापन सम्भव नियम (विकल्पात्मक) एक यन्त्र पठनशक्य नियम अभिलेख (निप॰९ए) का प्रकाशन करता है समुदाय के पार्श्व में। ग्राहक जो इसका आलम्बन करते हैं उन पत्रों को भेजने से पहले बाधित करते हैं जो इसके अनुकूल नहीं। अनुमत घटना प्रकार @@ -597,26 +538,15 @@ विश्वासजाल द्वार जोडें वैश्विक अधिकतम घटना आकार (विकल्पात्मक) अष्टक \u2014 रिक्त छोड दें कोई वैश्विक सीमा नहीं तो। - प्राप्त - मेरा - पुरस्कृत - खोजें नया पदक - पदक सम्पादन पदक पुरस्कार स्वीकार अस्वीकार परिचय से हटाएँ - पदक परिचयचिह्न (डी॰सूचक) - साहस, योगदानकर्ता-२०२५… नाम मनुष्य द्वारा पढा जा सके पदक नाम विवरण यह पदक पुरस्कार क्यों दिया गया। - चित्र जालपता (१०२४घ्न१०२४) - https://example.com/badge.png - सूक्षमचित्र जालपता (विकल्पात्मक) - https://example.com/badge-thumb.png चित्र आरोहण वर्गाकार चित्र का चयन करें पदक मुख के लिए। पदक आवहन चालू… @@ -625,7 +555,6 @@ हटाएँ शीर्षकरहित पदक पुरस्कृत %1$d को - आपको एक पदक प्राप्त हुआ परिचय पदक पदक %1$d चयन करें कि आपके प्राप्त पदकों में से कौन से आपके परिचय पर दिखाई देंगे। @@ -677,7 +606,6 @@ आहार उपवास क्रमक - क्रमक स्रोत : %1$s संस्करण %1$s अवरोहण @@ -686,12 +614,10 @@ विषय सूची योजक नवीनतम संस्करण - टिप्पणियाँ सर्वप्रथम टिप्पणी करें। द्वारा पुराने संस्करण दिखाएँ पुराने संस्करण छिपाएँ - दिनदर्शिकाएँ छोटे सार्वजनिक चर्चा अनुचरण पोटलियाँ @@ -701,18 +627,14 @@ एक निलय मंच वक्ताओं के लिए प्रतीक्षा… - श्रोतागण हाथ उठाएँ हाथ नीचे करें ध्वनि संयोजन - वियोजन मौन मौन हटाएँ - संयोजन बन रहा है… शाला सुलझाव परिवहन उद्घाटन ध्वनि समझौता - ध्वनि संयोजित पुनःसंयोजन… अभिलेख सुनें सन्देश प्रेषण असफल @@ -720,9 +642,7 @@ क्या इस शाला को आवृत करें। सभी उपस्थित वियोजित हो जाएँगे। शाला आवृत दिखेगा सूचनावली में। शाला आवृत करें - भविष्य आरम्भ समय का चयन। ध्वनि असफल : %1$s - इस शाला के लिए ध्वनि उपलब्ध नहीं बात करें मंच छोडें ध्वनिग्राहक मौन @@ -730,7 +650,6 @@ सीधा प्रसारण प्रारम्भ… प्रसारण असफल : %1$s मौनकरण असफल : %1$s - ध्वनिग्राहक अभिगमन आवश्यक है इस शाला में बात करने के लिए। कोई अनुमति नहीं निलय ध्वनि चालू रखता है जब शाला खुला है। @@ -741,7 +660,6 @@ निलय जुडें निमन्त्रक खोलें - निकटकाल चर्चा शाला में अभी कोई नहीं। %1$d श्रोता निमन्त्रक @@ -769,8 +687,6 @@ श्रोतागण हाथ श्रोतागण कोई नहीं अब तक। - भेजें - कुछ बात करें… कोई सन्देश नहीं अब तक। आप ही पहले चर्चा आरम्भ करें। प्रतिक्रिया शाला सम्पादन @@ -804,7 +720,6 @@ क्रिया असफल क्रिया का निर्माण नहीं हो सका। शाला बाँटें - छोटा करें सुनते रहने के लिए छोटा करें ध्वनि कट गयी शाला आवहन… @@ -837,7 +752,6 @@ चयन करें कि किन एमओक्यू॰ जालावास सेवासंगणकों पर अमेथिस्ट आपके निलयों का प्रकाशन करता है। प्रथम विकल्प का प्रयोग होगा मूलविकल्पतः जब आप एक नया स्थान आरम्भ करेंगे। आपके सेवासंगणक प्रकार १०११२ प्रतिस्थापनशील घटना के रूप में अभिलेखित जिससे कि अन्य ग्राहक आपके आद्यताओं को पढ सके। - निलय सेवासंगणक जोडें पुनःप्रसारक (जालपरिवहन) जालपता प्रमाणीकरण (जेडबल्यूटी॰ टकसाल) जालपता जोडें @@ -850,13 +764,11 @@ सेवासंगणक हटाएँ कोई निलय सेवासंगणक नहीं अब तक। एक को जोडें नीचे अथवा एक अनुशम्सित सेवासंगणक का चयन करें। चलचित्र - लेख संगीत संगीतसूचियाँ कडियाँ पुटप्रसार कडियाँ देखें - कडियाँ कोई कडी प्राप्त नहीं अब तक %1$d कडी @@ -868,9 +780,6 @@ अभिलेख शीर्षक कलाकार कलाकार नाम - ध्वनि जालपता - https://… .mp3 - बाहरी चित्र जालपता (विकल्पात्मक) संगीतसंग्रह (विकल्पात्मक) अवधि सेकण्डों में (विकल्पात्मक) पद्य अथवा अभारसूची (विकल्पात्मक) @@ -880,7 +789,6 @@ संगीतसूची में जोडें आपकी कोई संगीतसूची नहीं है अब तक। ऊपर के क्षेत्र का प्रयोग करें एक बनाने के लिए। सभी संगीतसूचियों का प्रबन्धन करें - नयी संगीतसूची संगीतसूची नाम बनाएँ (शीर्षक रहित संगीतसूची) @@ -916,9 +824,6 @@ स्मर्त्तव्य सूची मिटाएँ पत्र देखें लेख देखें - योजक देखें - विषयसूचक देखें - आपका कोई स्मर्त्तव्य सूची अभी नहीं है। एक नया बनाने के लिए नीचे घुण्डी दबाएँ। विषयसूचक समुच्चय आपके कोई रुचि समुच्चय अभी नहीं हैं। एक नया बनाने के लिए नीचे घुण्डी दबाएँ। नव्य रुचि समुच्चय @@ -937,7 +842,6 @@ निजी पत्र (%1$s) सार्वजनिक पत्र सार्वजनिक पत्र (%1$s) - निजी लेख निजी लेख (%1$s) सार्वजनिक लेख सार्वजनिक लेख (%1$s) @@ -964,16 +868,6 @@ स्मर्त्तव्य सूची उपतथ्य किसी के भी द्वारा देखे जा सकते हैं नोस्टर पर। केवल आपके निजी सदस्य रहस्यीकृत होते हैं। सार्वजनिक करें निजी बनाएँ - धनकोष संयोजन सेवा - एक नोस्ट्र रहस्य को अधिकृत करता है ज्साप भुगतान करने के लिए क्रमक से बाहर चले बिना। रहस्य को सुरक्षित रखें तथा एक निजी पुनःप्रसारक का प्रयोग करें हो सके तो। - धनकोष संयोजन ख्याप्यकुंचिका - धनकोष संयोजन पुनःप्रसारक - धनकोष संयोजन रहस्य - गुप्त कुंचिका दिखाएँ - एनसेक॰ / षोडशांकरूप निजी कुंचिका - संयोजित - असंयोजित - उन्नत : संयोजन विवरणों को स्वयम प्रविष्ट करें शीघ्र ज्साप मात्राएँ ज्साप घुण्डी दबाने पर दिखाया जाता है। प्रत्येक मात्रा का भुगतान किसी भी विधि से की जा सकती है जो प्राप्तकर्ता द्वारा अवलम्बित है। लैटनिंग अथवा काशयू अथवा खण्डश्रृंखलाबद्ध। खण्डश्रृंखलाबद्ध केवल बडी मात्राओं के लिए। एक मात्रा दबाएँ उसे हटाने के लिए। उसे रिक्त छोड दें तो प्रत्येक बार मात्रा प्रविष्ट करने के लिए पूछेगा। खण्डश्रृंखला सत्यापित विधि से भेजें इसके स्थान पर @@ -1005,14 +899,8 @@ संयोजन धनकोष पुनःप्रसारक सूचनावली देखें प्रतिज्ञा मात्रा साट्स में - मतदान प्रकाशित करें - अनिवार्य प्रपत्रस्थान : - ज्साप के ग्राहक - प्रमुख मतदान विवरण… - विकल्प विकल्प %s मतदान विकल्प विवरण - प्रपत्रस्थान जो अनिवार्य नहीं : ज्साप न्यूनतम ज्साप अधिकतम सर्वसम्मति @@ -1021,11 +909,8 @@ अनेक विकल्प मतदान समापन दिनांक तथा समय मतदान %1$s में समाप्त होगा - के पश्चात समाप्त करें - दिन निर्वाचन करने में असफल मतदान आवृत है नये निर्वाचनों के लिए - ज्साप मात्रा प्रत्येक उपयोगकर्ता को केवल एक निर्वाचन करने की अनुमति है इस प्रकार के मतदान में। "घटना %1$s के लिए खोज चल रहा है" ज्साप भेजें @@ -1061,11 +946,8 @@ ज्साप अतिरिक्त नोस्ट्र में कोई पदचिह्न नहीं, केवल लैटनिंग पर नामरहित - पत्र प्रकाशित करें एक नए क्षेपणार्थ लेखाचिह्न के साथ। आपका लेखा इस उत्तर के साथ नहीं जोडा जाएगा। - यह उत्तर भेजा जाएगा एक नए नामरहित लेखा से अभिलेख सेवासंगणक इस अभिलेख का आरोहण करने के लिए सेवासंगणक का चयन करें - लै॰जाल पता अथवा @उपयोगकर्ता प्रसारसंगणक आपके प्रसारसंगणक आद्यताएँ स्थापित करें। स्थानीय ब्लोस्सम॰ द्रुतस्मृति का प्रयोग करें @@ -1074,10 +956,8 @@ स्थानीय द्रुतस्मृति का पता नहीं चला संयोजनद्वार २४२४२ पर। केवल परिचय चित्रों को द्रुतस्मृति में रखें स्थानीय द्रुतस्मृति को केवल परिचय चित्रों तक सीमित रखें। सूचनावली चित्र तथा चलचित्र सीधे मूल सेवासंगणकों से प्राप्त किए जाएँगे। - आपका कोई निप॰-९६ सेवासंगणक स्थापित नहीं। आप अमेथिस्ट की सूची का प्रयोग कर सकते हैं अथवा नीचे एक जोड सकते हैं ↓ आपका कोई ब्लोस्सम॰ प्रसारसंगणक स्थापित नहीं। आप अमेथिस्ट की सूची का प्रयोग कर सकते हैं अथवा नीचे एक जोड सकते हैं ↓ अनुशम्सित प्रसारसंगणक - अन्तर्निहित प्रसारसंगणक अमेथिस्त की मूलविकल्प सूची। आप एक एक करके जोड सकते हैं अथवा सूची जोड सकते हैं। मूलविकल्प सूची का प्रयोग करें प्रसारसंगणक जोडें @@ -1100,38 +980,21 @@ विभेदकोत्पादन प्रक्रिया चल रही है हो गया अपक्रम - आपके पुनःप्रसारक (निप॰-९५) - अभिलेख आपके पुनःप्रसारक द्वारा रखे जाते हैं। नया निप॰: जाँच करें यदि वे अवलम्बन करते हैं गोपनीयता विकल्प - टोर / ओर्बोट स्थापन - आपकी ओर्बोट स्थापना द्वारा संयोजन करें अनुकूल करें टोर स्थापना विकल्प - क्या आपके ओर्बोट / टोर से संयोजन काट दें - आपके तथ्य तत्क्षणतः सामान्य जाल से चलने लगेंगे हाँ नहीं - अनुचरण सूची सभी अनुचरित प्रयोक्ता के सभी अनुगामी मूल अनुचरण सूची - प्रतिनिधि द्वारा अनुचरित मेरे आसपास वैश्विक आयोजित संग्रह - चतुरंग मेरा मौन सूची अनुचरण सूचियाँ ये अनुचरण सूचियाँ आपके उपयोग के लिए रूपांकित हैं। आप प्रयोक्ताओं का अनुचरण कर सकते हैं निजी अथवा सार्वजनिक रूप से - सूचक युक्त स्मर्त्तव्य सूची - सामान्य स्मर्त्तव्य सूची - सार्वजनिक - निजी - मिश्रित - लगता है आपका अब तक कोइ अनुगम्य समुच्चय नहीं है। - \nनवीकरण के लिए नीचे दबाएँ। अथवा एक नया बनाने के लिए जोड घुण्डियाँ टाँकें। - नव्य लेखक जोडें अनुचरण सूची में प्रयोक्ता को सूचियों में जोडें अथवा हटाएँ अथवा इस प्रयोक्ता के साथ नई सूची बनाएँ। @@ -1140,23 +1003,9 @@ %1$s एक निजी सदस्य है सार्वजनिक सदस्य के रूप में जोडें निजी सदस्य के रूप में जोडें - सार्वजनिक सदस्य - निजी सदस्य - सार्वजनिक परिचय - निजी परिचय - सदस्य - सदस्य सूची - कोई सदस्य नहीं रिक्त - %1$s इस सूची में नहीं है %1$s एक सदस्य नहीं आपके सूचियाँ तथा %1$s - आपके अनुगम्य सूचियाँ - कोई अनुगम्य सूचियाँ प्राप्त नहीं। अथवा आपका कोई अनुगम्य सूचियाँ हैं नहीं। नवीकरण के लिए नीचे दबाएँ अथवा विकल्पसूची द्वारा एक नया बनाएँ। - लाने में अपक्रम : %1$s - नई सूची बनाएँ - प्रयोक्ता के साथ नई सूची %1$s बनाएँ - अनुगम्य सूची %1$s बनाता है तथा उससे %2$s जोडता है। नई फ़ॉलो सूची नव्य अनुचरण पोटली अनुचरण सूची की अनुकृति करें @@ -1176,14 +1025,6 @@ आप पनःनामकरण कर रहे हैं इस से इस तक.. मूलविकल्प द्वार ९०५० है - ## टोर द्वारा संयोजन करें ओर्बोट के साथ - \n\n१. स्थापित करें [ओर्बोट](https://play.google.com/store/apps/details?id=org.torproject.android) - \n२. ओर्बोट चलाएँ - \n३. ओर्बोट में, सोक्स॰ द्वार का जाँच करें। मूलविकल्पतः ९०५० का प्रयोग करता है। - \n४. यदि आवश्यक हो तो ओर्बोट में द्वार परिवर्तित करें - \n५. सोक्स॰ द्वार की समाकृति करें इस पटल पर - \n६. सक्रिय करें सूचकयुक्त घुण्डी दबाएँ ओर्बोट को प्रतिनिधि के रूप में प्रयोग करने के लिए - ओर्बोट सोक्स॰ द्वार सक्रिय टोर उपकरण आन्तरीय संस्करण का प्रयोग करें अथवा ओर्बोट @@ -1225,8 +1066,6 @@ सभी संयोजनों में अपना अंकीय जालपता छिपाएँ अपना स्वयम का बनाएँ द्वार अंक अमान्य - ओर्बोट का प्रयोग करें - टोर / ओर्बोट संयोजन काट दें निजी संदेश आपको सूचित करता है जब एक निजी संदेश आएगा ज्साप प्राप्त @@ -1283,12 +1122,8 @@ ब्लूटूथ ध्‍वनि आह्वान दृश्य आह्वान - अन्यों को जुडने की प्रतीक्षा में\u2026 सहभागी जोड़ें प्रयोक्ता खोजें\u2026 - आह्वान आरम्भ करने में असफल - आह्वान स्वीकार करने में असफल - आह्वान सत्र बनानें में असफल अनुमति आवश्यक अमेथिस्ट को ध्वनिग्राहक अभिगमन आवश्यक है ध्वनि आह्वान आरम्भ करने के लिए। कृपया इसे क्रमक स्थापना विकल्पों में सक्षम करें। अमेथिस्ट को चित्रग्राहक तथा ध्वनिग्राहक अभिगमन आवश्यक है दृश्य आह्वान आरम्भ करने के लिए। कृपया इन्हें क्रमक स्थापना विकल्पों में सक्षम करें। @@ -1322,24 +1157,13 @@ आण्ड्रोइड पुनःप्रसारक संयोजनों को प्रतिबंधित कर सकता है पृष्ठतल में। विद्युत्कोष अनुकूलन निष्क्रिय करें अमेथिस्ट के लिए सुनिश्चत रूप से सूचनाएँ प्राप्त करने के लिए। अभी ठीक करें सूचित करें : - संवाद में जुड जाएँ - उपयोगकर्ता अथवा झुण्ड विभेदक - एनपुब॰, एनइवेण्ट॰ अथवा षोडशांकरूप - बनाएँ - जुडें आज विषयवस्तु चेतावनी सावधान : %1$s इस पत्र में संवेदनशील विषयवस्तु समावेशित है जो कुछ लोगों के लिए आपत्तिजनक अथवा व्याकुल करनेवाला लग सकता है - संवेदनशील विषयवस्तु सर्वदा छिपाएँ - संवेदनशील विषयवस्तु सर्वदा दिखाएँ - विषयवस्तु चेतावनियाँ सर्वदा दिखाएँ छिपाएँ दिखाएँ चेतावनी दें - अनुशंसित : - अपरिचित जन के भेजे गये कचरालेखों को छलनी द्वारा हटाएँ - चेतावनी दें जब पत्र सूचित किये गये हों आपके द्वारा अनुचरित व्यक्तियों से कचरालेख छलनी अज्ञात लोगों से पत्र छिपाएँ जो निरन्तर 5 अथवा अधिक बार यथावत समान थे मेरे घटनाओं में ग्राहक सूचक जोडें @@ -1371,22 +1195,17 @@ अष्टकों में मात्रा जो इस पुनःप्रसारक को भेजा गया था छलनियाँ तथा घटनाएँ समेत अष्टकों में मात्रा जो इस पुनःप्रसारक से प्राप्त हुआ था छलनियाँ तथा घटनाएँ समेत घटनाएँ रखे गए - %1$s से पुनःप्रसारक जानकारी प्राप्त करने के प्रयास में अपक्रम हुआ अध्यक्ष द्वारा उपयुक्त सेवा कुंजी - %1$s चलाया जा रहा है - %1$s (%2$s) चलाया जा रहा है संस्करण क्रमक सम्पर्क अवलम्बन किए हुए निप॰ सूची अवलम्बित पकड - प्रवेश शुल्क प्रवेशन ग्राहकता प्रकाशन - भुगतान %1$s भुगतान जालपता लक्ष्य दर्शक नीतियाँ तथा जालयोजक @@ -1394,7 +1213,6 @@ परिसीमाएँ देश भाषाएँ - विषयसूचक विषय सूची सभी देश सभी भाषाएँ @@ -1409,64 +1227,48 @@ खोलें पढें लिखें - आरटीटी॰ जाल प्रकार अवलम्बन किए हुए निप॰ सूची आवश्यकताएँ - अन्तिम जाँच %1$d सहस्रतमसेकण्ड स्वीकृत प्रकार स्थान सक्रिय ग्राहकताएँ - अपूर्ण निर्गतपेटिका घटनाएँ अनुरोध ग्राहकताएँ (%1$d) गणना ग्राहकताएँ (%1$d) निर्गतपेटिका घटनाएँ (%1$d) - इस पुनःप्रसारक के लिए कोई सक्रिय ग्राहकताएँ नहीं %1$d लेखक %1$d विभेदक %1$s से %1$s तक सीमा %1$d - संदेश लम्बाई - ग्राहकताएँ - छलनियाँ - ग्राहकता विभेदक की लम्बाई न्यूनतम उपसर्ग अधिकतम घटना विषयसूचक - विषयवस्तु लम्बाई अधिकतम विषयवस्तु लम्बाई इससे पुराना हटाता है इस तक स्वीकारता है %1$s भविष्य में %1$s पूर्व - %1$s शून्यांक %1$s द्वयंक घटना रखाई विषयवस्तु आकार संयोजकता अभिगमन नियन्त्रण न्यूनतम श्रमप्रमाण - प्रमाणीकरण प्रमाणीकरण आवश्यक - भुगतान भुगतान आवश्यक अधिकतम संदेश लम्बाई अधिकतम ग्राहकताएँ अधिकतम छलनियाँ प्रति ग्राहकता अधिकतम सीमा (घटनाएँ प्रतिफलित) - मूलविकल्प सीमा (घटनाएँ प्रतिफलित) अधिकतम ग्राहकताविभेदक लम्बाई काशयू अक्षरराशि टकसाल : %1$s चुकाएँ - ज्साप धनकोष को भेजें - काशयू धनकोष में खोलें अक्षरराशि की अनुकृति करें अन्य क्रमक में खोलें कोई लैटनिंग पता स्थापित नहीं - अक्षरराशि की अनुकृति की गयी टाँकाफलक में तत्क्षणप्रसार जालरहित समाप्त @@ -1517,7 +1319,6 @@ मार्मोट॰ स्थिति पुनःस्थापन। मार्मोट॰ स्थिति पुनःस्थापन असफल : %1$s सर्वदा - केवल वै॰फै॰ मात्रांकन रहित वैफै॰ कभी नहीं सम्पूर्ण @@ -1542,7 +1343,6 @@ पत्र प्रकाशन शैली का चयन करें परिचय चित्रालय शैली चित्रालय शैली चुनें - चित्र प्राप्त करें कचरालेख प्रेषक मौन किया गया। अमौन करने के लिए टाँकें ध्वनि सक्रिय। मौन करने के लिए टाँकें @@ -1554,18 +1354,13 @@ नोस्ट्र पता का सत्यापन सफल नोस्ट्र पता का सत्यापन असफल नोस्ट्र पता का जाँच चल रहा है - सब का चयन / अचयन करें मूलविकल्प मूलविकल्प पुनःस्थापित करें - पुनःप्रसारक चुनें आगे बढने के लिए - ज्साप आगे भेजें इनको : - अवलम्बन करनेवाले ग्राहक ज्सापों को आगे भेजेंगे लै॰जाल पता को अथवा नीचे के उपयोगकर्ता परिचय को तथा आपके तक नहीं स्थान अनावृत करें ऐसे आपका भूगोलिक स्थान विभेदक जोडता है पत्र में। जनता जान जाएगी कि आप वर्तमान स्थान से ५ कि॰मे॰ (३ मी॰) की दूरी के अन्दर हैं स्थल विशेष पत्र स्थल के अनुचर ही देखेंगे। आपके सामान्य अनुचर नहीं देखेंगे। विषयसूचक विशेष पत्र - केवल विषयसूचक के अनुचर इसे देखेंगे। आपके सामान्य अनुचर नहीं देखेंगे। जालस्थान पर टिप्पणी बाहरी संसाधन पर टिप्पणी %1$d मिन॰ पठन @@ -1586,20 +1381,14 @@ ध्वनि अभिलेख आरोहण एक एमपीत्री॰ अथवा वेव॰ अथवा फ्लाक॰ का चयन करें। इसका आरोहण किया जाएगा आपके प्रसारसंगणक पर अभिलेखन करने पर। ध्वनि अभिलेख आरोहण के लिए तत्पर - आरोहण चल रहा है… बाहरी चित्र तथा ध्वनि अभिलेख का आरोहण तथा प्रकाशन चालू। यह चलता रहेगा आप पटल से विगमन करें तो भी। - आरोहण असफल : %1$s स्थान प्राप्त किया जा रहा है स्थान प्राप्त करने की अनुमति नहीं आपके विषयवस्तु दिखाने से पूर्व संवेदनशील विषयवस्तु चेतावनी जोडता है। यह आदर्श है किसी कार्यालय अनुचित विषयवस्तु के लिए अथवा जो कुछ लोगों के लिए आपत्तिजनक अथवा व्याकुल करनेवाला लग सकता है कारण (विकल्पात्मक) - नयी सुविधा - इस कार्यशैली सक्षम करने के लिए अमेथिस्ट के द्वारा निप॰-१७ संदेश (उपहारकोषयुक्त, आच्छादित सीधा तथा झुण्ड संदेश) भेजना पडेगा। यह निप॰-१७ नया है तथा अनेक ग्राहक इसे कार्यान्वित किया नहीं अब तक। सुनिश्चित करें कि प्राप्तकर्ता एक अनुकूल ग्राहक का प्रयोग कर रहे हैं। - सक्रिय करें सार्वजनिक समूह नया निजी अथवा सार्वजनिक झुण्ड - पुनःप्रसारक निजी के लिए विषय @@ -1611,9 +1400,6 @@ सदस्यों के लिए व्याख्यान नाम का परिवर्तन नये लक्ष्य के लिए। टाँकाफलक से चिपकाएँ - अमान्य निप॰-४७ वैश्विकसाधनपरिचायक - यह %1$s एक मान्य निप॰-४७ प्रवेशांकन वैश्विकसाधनपरिचायक नहीं है। - नया नोस्टर धनकोष के साथ संयोजन करें धनकोष अप्राप्त अमेथिस्ट को कोई धनकोष क्रमक प्राप्य नहीं जो नोस्टर धनकोष संयोजन का अवलम्बन करता हो। \n\nआप यह कर सकते हैं : @@ -1630,7 +1416,6 @@ स्वचालित रूप से चलचित्र तथा जिफ॰ चलाता है स्वतः चालू करें चलचित्रों को जब पटल पर दिखाई दें जालपता के पूर्वीक्षण दिखाएँ - चित्रों का अवरोहण कब करें चिति की अनुकृति करें टाँकाफलक में अनुकृति करें टाँकाफलक में अनुकृत @@ -1646,43 +1431,21 @@ अभिलेख जोडा गया अभिलेख जोडा गया आपके परिचय चित्रालय में तब बनाया गया - नियमावली - हमारा परिचय दिशा निर्देश नियामक आम्बेर के साथ प्रवेशांकन करें आपकी स्थिति का नवीकरण करें - अपक्रम संदेश परखने में अपक्रम निर्वाचन का भार ज्साप मात्रा के अनुसार माना जाता है। आप एक न्यूनतम मात्रा स्थापित कर सकते हैं कचरालेख भेजनेवालों से बचने के लिए तथा एक अधिकतम मात्रा बडे ज्सापकर्ताओं के द्वारा मतदान का अधिग्रहण होने से बचने के लिए। दोनों स्थानों में एक ही मात्रा का प्रयोग करें प्रत्येक निर्वाचन का मूल्य समान मानने को सुनिश्चित करने के लिए। रिक्त रख दें कुछ भी मात्रा स्वीकार करने के लिए। ज्साप भेजने में असफल उपयोगकर्ता को संदेश भेजें सूचना %1$s ठीक है - %1$s तक जा नहीं पाए : %2$s - %1$s के लिए निप॰-११ जालपता बनाने में असफल : %2$s - %1$s तक जाने में असफल : %2$s - %1$s से प्रतिवचन परखने में असफल : %2$s - पुनःप्रसारक ने %1$s अनुरोध को इनकार किया : %2$s - %1$s तक जा नहीं पाए : %2$s - %1$s से परिणाम परख नहीं पाए : %2$s - %1$s असफल हुआ इस संकेतक के साथ : %2$s - के लिए सक्रिय : - मुखपृष्ठ - सीधे संदेश - चर्चाएँ - वैश्विक - खोज ज्साप विभाजन करें तथा आगे भेजें अवलम्बन करनेवाले ग्राहक ज्सापों का विभाजन करेंगे तथा यहाँ जोडे गये उपयोगकर्ताओं को आगे भेजेंगे आप तक के स्थान पर खोजें तथा उपयोगकर्ता जोडें उपयोगकर्ता नाम अथवा प्रदर्शन नाम लैटनिंग स्थापना अनुपलब्ध उपयोगकर्ता %1$s का कोई लैटनिंग पता स्थापित नही साट्स प्राप्त करने के लिए - प्रतिशत - २५ - ज्साप का विभाजन इनके साथ - ज्साप आगे भेजा जा रहा है इनको - लैटनिंग धनकोष ढूँढने में असफल भुगतान किया गया धनकोष %1$s हस्ताक्षर क्रमक खोलने में अपक्रम @@ -1691,7 +1454,6 @@ यह संकुचनविस्तारणविधि अथवा प्रारूप इस यन्त्र पर अवलम्बित नहीं (%1$s)। अपने जालसंचारक में खोलने का प्रयास करें। जालसंचारक मे खोलें हस्ताक्षर अनुरोध अस्वीकृत - हस्ताक्षर क्रमक अस्वीकार किया सुनिश्चित करें हस्ताक्षर क्रमक ने इस व्यापार को अनुमति दिया कोई धनकोष प्राप्त नहीं लैटनिंग चालान चुकाने के लिए (अपक्रम : %1$s)। कृपया एक लैटनिंग धनकोष की स्थापना करें ज्सापों का प्रयोग करने के लिए कोई धनकोष प्राप्त नहीं लैटनिंग चालान चुकाने के लिए। कृपया एक लैटनिंग धनकोष की स्थापना करें ज्सापों का प्रयोग करने के लिए @@ -1707,40 +1469,23 @@ विकल्प का चयन करें चालान का भुगतान नहीं कर पाए निकाल नहीं पाए - धनकोष संयोजन स्थापित नहीं कर पाए - निप॰-४७ संयोजन सूत्र परखने में अपक्रम। जाँच करें यदि यह सम्यक है अपने धनकोष सेवा प्रदाता के साथ : %1$s। अपक्रम : %2$s - निप॰-४७ संयोजन सूत्र परखने में अपक्रम। जाँच करें यदि यह सम्यक है अपने धनकोष सेवा प्रदाता के साथ : %1$s। काशयू नहीं चुका पाए टकसाल ने यह अपक्रम संदेश उपलब्ध किया : %1$s - काशयू अक्षरराशि का व्यय हो चुका। काशयू प्राप्त %1$s साट्स भेजे गये आपके धनकोष में। (शुल्क : %2$s साट्स) कोई अनुकूल काशयू धनकोष उपलब्ध नहीं यन्त्र में ग्राहक के सेवा संगणक से चालान नहीं लाया जा सका आपका धनकोष संयोजन प्रदाता ने यह अपक्रम लौटाया : %1$s - टोर से जुड नहीं पाए टोर॰ संयोजन नहीं हो रहा अमेथिस्ट द्वारा टोर॰ का उत्थापन सम्पन्न नहीं हुआ। क्या एक समान्य संयोजन (टोर॰ अतिरिक्त) का प्रयोग करें जिससे कि सूचनावली का आवहन हो सके। इस चयन का स्मरण रखा जाएगा अगले घण्टे तक तथा टोर॰ का पुनःप्रयास किया जाएगा तत्पश्चात। सामान्य संयोजन का प्रयोग करें प्रतीक्षा करते रहें - पुनःप्रसारक पत्र का अवरोहण अनुपलब्ध लै॰जालपता नहीं बना पाए लै॰पता \"%1$s\" से। उपयोगकर्ता की स्थापना की जाँच करें - ग्राहक की लैटनिंग सेवा %1$s पर उपलब्ध नहीं। इसका परिकलन किया गया \"%2$s\" लैटनिंग पता से। अपक्रम : %3$s। जाँच करें यदि सेवा संगणक चल रहा है तथा यदि लैटनिंग पता सम्यक है - %1$s का सुलझाव नहीं कर पाए। जाँच करें यदि आप संयोजित हैं, यदि सेवा संगणक चल रहा है तथा यदि लैटनिंग पता %2$s सम्यक है - %1$s का सुलझाव नहीं कर पाए। जाँच करें यदि आप संयोजित हैं, यदि सेवा संगणक चल रहा है तथा यदि लैटनिंग पता %2$s सम्यक है।\n\nअपवर्ग था : %3$s - %1$s से चालान नहीं लाया जा सका चालान नहीं लाया जा सका %1$s से : %2$s - लैटनिंग पता से जेसोन॰ परखनें में अपक्रम। उपयोगकर्ता की लैटनिंग स्थापना की जाँच करें %1$s से जेसोन॰ परखनें में अपक्रम। उपयोगकर्ता की लैटनिंग स्थापना की जाँच करें - प्रत्याह्वान जालपता उपलब्ध नहीं उपयोगकर्ता के लैटनिंग पता सेवासंगणक की समाकृति में प्रत्याह्वान जालपता उपलब्ध नहीं %1$s के उत्तर से - लैटनिंग पता से लाये गये चालान के जेसोन॰ परखनें में अपक्रम। उपयोगकर्ता की लैटनिंग स्थापना की जाँच करें - %1$s से लाए गए चालान के जेसोन॰ परखनें में अपक्रम। उपयोगकर्ता की लैटनिंग स्थापना की जाँच करें %2$s से चालान की मात्रा (%1$s साट्स) में दोष है। %3$s होना चाहिए था। ज्साप भेजने से पहले लैटनिंग चालान नहीं बना पाए। ग्राहक के लैटनिंग धनकोष ने यह अपक्रम की सूचना दी : %1$s - लैटनिंग चालान नहीं बना पाए। %1$s से संदेश : %2$s - ज्साप भेजने से पहले लैटनिंग चालान नहीं बना पाए। परिणाम जेसोन॰ में pr अम्श उपलब्ध नहीं। - %1$s से लैटनिंग चालान नहीं बना पाए। परिणाम जेसोन॰ में pr अम्श उपलब्ध नहीं। केवल पढनेवाला उपयोगकर्ता कोई प्रतिक्रियाएँ स्थापित नहीं सूचनाएँ @@ -1766,13 +1511,11 @@ विक्रेता को संदेश भेजें नमस्ते %1$s, क्या यह अब भी उपलब्ध है? नमस्ते, क्या यह अब भी उपलब्ध है? - वस्तु की बिक्री करें शीर्षक आईफोन १३ स्थिति वर्ग मूल्य (साट्स में) - १००० स्थान नगर, प्रदेश, देश नव्य @@ -1801,20 +1544,13 @@ अन्य चित्र चलचित्र आरोहण असफल संकुचित अभिलेख को खोल नहीं पाए - चित्र चलचित्र संकुचित करने में अपक्रम : %1$s आरोहण अपक्रम : %1$s सेवासंगणक ने आरोहण पश्चात जालपता नहीं दिया सेवासंगणक से आरोहणकृत चित्र चलचित्र का अवरोहण नहीं कर पाए आरोहण पश्चात अवरोहित अभिलेख की जाँच नहीं हो सकी : %1$s - स्थानीय अभिलेख अनुकूल नहीं बना सके आरोहण के लिए : %1$s %1$s पर आरोहण असफल : %2$s - आरोहण असफल : %1$s मिटाने में असफल : %1$s अभिलेख निप॰-९५ के लिए बहुत बडा है - अंगुलाकारचित्र दिखाने में असफल - शीर्षक जानकारी आयोजित करने में असफल : %1$s - संक्षिप्तीकरण निरस्त किया गया - संक्षिप्तीकरण से अभिलेख प्राप्त नहीं हुआ अभिलेख रहस्यीकरण गोपनीयता के लिए अभिलेखों का रहस्यीकरण करें। कुछ सेवासंगणक रहस्यीकृत अभिलेखों को सम्भाव्यतः अस्वीकार कर सकते हैं निःशुल्क लेखाओं के लिए। रहस्यीकृत आरोहण असफल @@ -1841,27 +1577,18 @@ एविफ॰ से परितथ्य नहीं मिटा सके : %1$s पाण्डुलिपि का सम्पादन करें क्यूआर॰ क्रमचित्र के साथ प्रवेशांकन करें - मार्ग घर - खोज आविष्करण संदेश सूचनाएँ - वैश्विक लघु चलचित्र - चित्र - व्यायाम दिनदर्शिकाएँ दिनदर्शिका सूचियाँ चतुरंग धनकोष - शेष भेजें प्राप्त करें लेनदेन - कोई धनकोष संयोजित नहीं - एक नोस्टर धनकोष संयोजन (एनडबल्यूसी॰) स्थापित करें आपके ज्साप स्थापना विकल्पों में धनकोष का उपयोग करने के लिए। - धनकोष की स्थापना करें साट्स बोल्ट॰-११ चालान चिपकाएँ भुगतान करें @@ -1889,8 +1616,6 @@ यह धनकोष संयोजन को हटाएगा। आप इसे कभी भी पुनः जोड सकते हैं। धनकोष नाम मेरा धनकोष - आपके धनकोष - धनकोष प्रबन्धन कोई धनकोष संयोजित नहीं एक अथवा अधिक नोस्टर धनकोष संयोजन जोडें भुगतान भेजने तथा प्राप्त करने के लिए। नोस्टर धनकोष संयोजन जोडें @@ -1909,12 +1634,9 @@ टकसाल जालपता टकसाल हटाएँ इतिहास - धनकोष सम्पादन नटज्साप कुंचिका (उन्नत) एक पृथक निजी कुंचिका केवल निप॰६१ नटज्साप प्राप्त करने के लिए। आपकी नोस्टर लेखा बद्ध कुंचिका नहीं। एक नयी कुंचिका बनाएँ - कोई भी लम्बित नटज्साप को अमान्य कर देगा जो वर्तमान कुंचिका से बद्ध हो। - वर्तमान कुंचिका रखें पीटूपीके॰ निजी कुंचिका (षोडशांक) काशयू॰ धनकोष सम्पादन परिवर्तनों का अभिलेखन @@ -1930,7 +1652,6 @@ लोकप्रिय टकसाल अनुकूल टकसाल - इस टकसाल की अनुशंसा करें प्राप्त करें भेजें लैटनिंग॰ अक्षरराशि भेजें @@ -1990,10 +1711,6 @@ अभिलेखन करें पुनःनामकरण धनकोष पुनःनामकरण - सम्पादन - अमान्य नोस्टर धनकोष संयोजन पता - ऊर्ध्वगमन - अधोगमन खण्डश्रृंखला सत्यापित लेनदेन इस लेखा के लिए कोई खण्डश्रृंखला पता उपलब्ध नहीं। कोई खण्डश्रृंखला पृष्ठभाग समाकृत नहीं। @@ -2068,17 +1785,13 @@ भुगतान भेजा गया (%2$d में से %1$d प्राप्तिप्रमाण प्रकाशित) पर अगले प्राप्तिप्रमाण का प्रकाशन असफल भुगतान भेजा गया (%2$d में से %1$d प्राप्तिप्रमाण प्रकाशित) पर अगले प्राप्तिप्रमाण का प्रकाशन असफल - सुरक्षार्थ छलनियाँ अनुचरित आयात करें नया पत्र प्रकाशन नये लघु : चित्र अथवा चलचित्र नया सामुदायिक टीका नया उत्पाद - नया स्थान विशेष पत्र नया लेख नया मतदान - नया ज्साप मतदान - नया सामान्य मतदान नया चित्र नयी दिनदर्शिका घटना दिनदर्शिका घटना सम्पादन @@ -2093,8 +1806,6 @@ दिन आगामी अतीत - कोई आगामी अथवा अतीत दिनदर्शिका घटनाएँ नहीं आपके चयनित सूचनावली से अब तक। - कोई दिनदर्शिका संग्रह नहीं अब तक। आपकी दिनदर्शिका रिक्त है आपके द्वारा अनुचरित लोगों के बाँटे हुए घटनाएँ यहाँ दिखेंगे। संकलनचिह्न दबाएँ आपके अपने बनाने के लिए। कोई संग्रह नहीं अब तक @@ -2121,8 +1832,6 @@ अगले सप्ताह पुर्व दिन अगले दिन - कोई घटनाएँ नहीं इस दिन - कोई घटनाएँ नहीं आगे चलता है %2$d में से %1$d दिन संचारयन्त्र दिनदर्शिका में जोडें @@ -2182,7 +1891,6 @@ चयनित चित्र का अरोहण असफल। पुनःप्रयास करें अथवा जालपता चिपकाएँ। सहभागी (%1$d) नाम अथवा एनपुब॰ अथवा निप॰०५ ढूँढें - मान्य एनपुब॰ प्रविष्ट करें… अथवा ६४ अक्षर षोडशांकरूप ख्याप्यकुंचिका। सहभागी हटाएँ दिनदर्शिका अनुस्मारक अनुस्मारक भेजें @@ -2203,10 +1911,7 @@ घटना विवरण नया छोटा चलचित्र नया लम्बा चलचित्र - शीर्षक साराम्श (वैकल्पिक) - बाहरी चित्र जालपता (वैकल्पिक) - आपका लेख मार्कडौन में लिखें… पूर्वावलोकन संपादित करें शीर्षक चित्र जोडें @@ -2290,18 +1995,14 @@ पुनःप्रसारक %1$s पुनःप्रसारक सूची का विस्तारण करें टीका विकल्प - पुनःप्रसारक सूची चयनकर्ता मतदान मतदान अक्षम करें द्व्यंकरूप्य चालान द्व्यंकरूप्य चालान निरस्त करें - वस्तु बिक्री निरस्त करें ज्सापोपार्जन योजना ज्सापोपार्जन योजना निरस्त करें स्थान स्थान हटाएँ - ज्साप विभाजन - ज्साप विभाजन निरस्त करें विषयवस्तु चेतावनी जोडें विषयवस्तु चेतावनी हटाएँ समापन दिनांक जोडें @@ -2316,11 +2017,8 @@ अमान्य पता अमेथिस्ट को एक वैश्विक वस्तु विभेदक प्राप्त हुआ खोलने के लिए परन्तु वह विभेदक अमान्य था : %1$s सीधा संदेश आगतपेटिका पुनःप्रसारक - पुनःप्रसारक : %1$s - साधारण पुनःप्रसारक प्रयुक्त आपके निजी आगतपेटिका पुनःप्रसारकों की स्थापना करें यह स्थापना विकल्प सब को सूचित करता है आपको सन्देश भेजने के लिए कौनसे पुनःप्रसारकों का प्रयोग करना चाहिए। इनके बिना आप कुछ सन्देश प्राप्त नहीं कर पाएँगे। - ये अच्छे विकल्प हैं :\n - inbox.nostr.wine (सशुल्क)\n - auth.nostr1.com (शुल्करहित)\n - you.nostr1.com (निजी पुनःप्रसारक - सशुल्क) ये अच्छे विकल्प हैं :\n - auth.nostr1.com (शुल्करहित)\n - inbox.nostr.wine (सशुल्क)\n - relay.0xchat.com (शुल्करहित) निजी आगतपेटिका के रूप में १ - ३ पुनःप्रसारकों को जोडें। सी॰सं॰ आगतपेटिका पुनःप्रसारकों को सब से सन्देश स्वीकारना चाहिए पर उनका अवरोहण करने की अनुमति केवल आपको देना चाहिए। अभी स्थापना करें @@ -2340,7 +2038,6 @@ सूचनाएँ प्राप्त करने के लिए पुनःप्रसारक सूची की विशिष्ट रचना आवश्यक है नोस्टर में। १ - ३ पुनःप्रसारकों को जोडें जो आपके लिए सूचनाएँ स्वीकारते हैं। सुनिश्चित करें कि इनके लिए भुगतान अथवा विश्वासजाल अनुमति अनावश्यक हैं अन्यथा आप केवल भुगतान करनेवालों से अथवा दीर्घकालिक प्रयोक्ताओं से सूचनाएँ प्राप्त करेंगे ये अच्छे विकल्प हैं :\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social - सीधा संदेश आरोहण पुनःप्रसारक स्थापना विकल्प पुनःक्रमबद्ध पुनःप्रसारक सार्वजनिक मुख्य पुनःप्रसारक @@ -2357,12 +2054,8 @@ पुनःप्रसारक जहाँ आपके एमएलएस॰ कुंचिकापोटलियाँ प्रकाशित होंगे (मिप॰००)। अन्य प्रयोक्ता इन कुंचिकापोटलियों को प्राप्त करेंगे आपको आमन्त्रित करने के लिए मार्मोट॰ समूह चर्चाओं में। १ - ३ पुनःप्रसारकों को जोडें जो आप से कुंचिकापोटली घटनाएँ स्वीकारते हों तथा सार्वजनिक पठन की अनुमती देते हों। निजी पुनःप्रसारक १ - ३ पुनःप्रसारकों को जोडें उन घटनाओं को रखने के लिए जो कोई अन्य नहीं देख सकता जैसे कि पाण्डुलिपियाँ अथवा क्रमक के स्थापना विकल्प। आदर्शतः ये पुनःप्रसारक स्थानीय होने चाहिए अथवा प्रत्येक उपयोगकर्ता के विषयवस्तु अवरोहण के पूर्व परिचय प्रमाणीकरण अनिवार्य होना चाहिए। - सामान्य पुनःप्रसारक - अमेथिस्ट इन पुनःप्रसारकों का प्रयोग करता है आपके पत्रों का अवरोहण करने के लिए। संयोजित पुनःप्रसारक वर्तमान उपयुक्त पुनःप्रसारकों की सूची - अनुशंसित पुनःप्रसारक - सूचित उपयोगकर्ताओं के पत्र प्राप्त करने के लिए निम्नलिखित पुनःप्रसारकों को अपने सामान्य पुनःप्रसारक सूची में जोडें। खोज पुनःप्रसारक पुनःप्रसारकों की सूची जिनको किसी विषयवस्तु अथवा उपयोगकर्ताओं को खोजने में प्रयोग करना चाहिए। कोई विकल्प नहीं तो उपयोगकर्ता सूचक जोडना तथा खोज निष्क्रिय होंगे। सुनिश्चित करें कि वे निप॰-५० को कार्यान्वित किये हैं। स्थानीय पुनःप्रसारक @@ -2397,11 +2090,8 @@ यह संस्करण आप तक लाया गया इनके द्वारा : संस्करण %1$s धन्यवाद! - अधिकतम सीमा सीमित लेखन इससे पथभेद किया गया - पथभेद - गिट क्रमलेखकोश : %1$s जाल : अनुकृति : खुला @@ -2426,20 +2116,13 @@ लेख सम्पादित करें पत्र का सम्पादन करें पत्र शोधन के लिए प्रस्ताव - परिवर्तनों का साराम्श - शीघ्र सुधार… सुझाव को स्वीकारें चलचित्र आरम्भ करें उद्भूत गवाक्ष में अवरोहण - संगीत पद्य दिखाएँ - संगीत पद्य ना दिखाएँ - समावृत संदेश निष्क्रिय। समावृत संदेश सक्रिय करने के लिए टाँकें - समावृत संदेश सक्रिय। समावृत संदेश निष्क्रिय करने के लिए टाँकें भेजें उपयोगकर्ता नाम को ध्वनि के रूप में चलाएँ घुण्डी क्यूआर॰ क्रमचित्र परखें - तृतीय पक्ष धनकोष प्रदाता आल्बी तक जाएँ दिनांक का चयन करें एक टीका पाण्डुलिपि को उत्तर नहीं दे सकते एक टीका पाण्डुलिपि पर टीका नहीं लिख सकते @@ -2481,23 +2164,18 @@ स्मृतिस्थान का अभाव - सेवासंगणक में पर्याप्त स्मृतिस्थान उपलब्ध नहीं अनुरोध पर सफलतापूर्वक काम करने के लिए क्रमचक्र दृष्ट - सेवासंगणक को अनन्त क्रमचक्र का पता चला अनुरोध पर काम करते हुए जाल प्रमाणीकरण आवश्यक - जाल उपलब्ध होने के लिए ग्राहक का प्रमाणीकरण अनिवार्य - निप॰-९६ सेवासंगणक - सेवासंगणक जितना चाहें जोडें। किस संगणक का उपयोग करना है उसका चयन कर सकते हैं चित्र का आरोहण करते समय ब्लोस्सम॰ प्रसारसंगणक सेवासंगणक जितना चाहें जोडें। किस संगणक का उपयोग करना है उसका चयन कर सकते हैं चित्र का आरोहण करते समय निप॰-९६ सेवासंगणक जोडें ब्लोस्सम॰ प्रसारसंगणक जोडें सब मिटाएँ क्या आप निश्चित रूप से सभी पाण्डुलिपियाँ मिटाना चाहते हैं। - चिति : उग्रप्रवाह अभिलेख अवरोहण अभिलेख खोलने में असफल कोई उग्रप्रवाह क्रमक स्थापित नहीं अभिलेख खोलने तथा अवरोहण करने के लिए। अभिलेखविभेदक युक्त जालनिर्देशक बनाने के लिए पर्याप्त जानकारी नहीं है घटना में - मेरे सूचियाँ / समुच्चय मेरे सूचियाँ - प्रयोक्ता सूची सूचनावली छानने के लिए सूची चुनें सूचनावली विषयसूचक @@ -2528,7 +2206,6 @@ निजी सन्देश सार्वजनिक संदेश चर्चा पुनःप्रसारक - वह पुनःप्रसारक जिससे इस चर्चा के सभी उपयोगकर्ता जुडते हैं चित्र बाँटें… चित्र बाँटने में असफल। कृपया कुछ समय पश्चात पुनःप्रयास करें… चलचित्र बाँटें… @@ -2575,7 +2252,6 @@ क्या आप निकटकालिक क्रमदोष सूचनापत्र एक सीधे सन्देश में अमेथिस्ट को भेजना चाहते हैं। कोई व्यक्तिगत जानकारी बाँटी नहीं जाएगी भेजें यह सन्देश %1$s में अदृश्य हो जाएगा - यह सन्देश %1$d दिनों में अदृश्य हो जाएगा हस्ताक्षरकर्ता चुनें पहले से ही सूची में निजी सदस्य @@ -2597,7 +2273,6 @@ पोटली नाम नव्य पोटली नाम पोटली विवरण - नव्य पोटली विवरण सूची प्रसारण पोटली प्रसारण सूची मिटाएँ @@ -2611,13 +2286,9 @@ संकुचित करें विस्तृत करें पुनःप्रयास असफल (%1$d) - +%1$d अधिक प्रसारण - " (%1$d चालू)" - %1$d/%2$d पुनःप्रसारक समयान्त पुनःप्रयास चालू… पुनःप्रयास करें - देखें हटाएँ %1$d/%2$d प्रसारण चालू @@ -2643,7 +2314,6 @@ पुनःआरम्भ स्वीकार अस्वीकार - नया खेल नया चतुरंग खेल खेल आवहन चालू\u2026 खेल अप्राप्त @@ -2798,23 +2468,13 @@ प्रयोक्ता परिचय जिससे आयात करना है खोज, एनपुब॰१…, alice@example.com एनपुब॰ एन॰परिचय निप॰०५ षोडशांक तथा नामरूप्य का आलम्बन करता है (.bit, d/, id/) - अनुचरण सूची देखें पारितोषिक %1$d लेखाएँ प्राप्त %1$d चयनित - नामरूप्य द्वारा सुलझा गया - अब %1$d लेखाएँ अनुचरित - आपकी सूचनावली उपलब्ध है। - छोडें - अन्य खोजें %1$d लेखाओं का अनुचरण करें - अधिक आयात - चलते रहें अभी के लिए छोडें - %1$s का सुलझन चालू… अनुचरण सूची प्राप्त की जा रही है… कोई अनुचरित नहीं - %1$d लेखाओं का अनुचरण… "किसी मित्र अथवा समूह नेता का परिचय प्रविष्ट करें। उनके एनपुब॰ अथवा निप॰०५ पता अथवा नामरूप्य नाम जैसे कि alice@example.com अथवा id/alice का उपयोग आप कर सकते हैं खण्डश्रृंखला सत्यापित विभेदकों के लिए।" सभी चुनें %1$d%% समय निरन्तर उपलब्ध @@ -2822,7 +2482,6 @@ संयोजन परीक्षण सेवासंगणकों का परीक्षण… संयोजित - असफल परीक्षा परिणाम निदानार्थ लक्षण अन्तिम परीक्षा @@ -2835,9 +2494,6 @@ विश्वास करें अस्वीकार करें पुनःप्रसारक समचरणीकरण - पुनःप्रसारक समचरणीकरण - अपने घटनाओं को पुनःप्रकाशित करें सभी ज्ञात पुनःप्रसारकों तक अपने निर्गतपेटिका आगतपेटिका तथा सीधासन्देश पुनःप्रसारकों का अद्यतन करने के लिए। वैफै॰ आवश्यक। यह सम्भाव्यतः बहुत जानकारी भेज सकता है। - पुनःप्रसारक समचरणीकरण खोलें… यह क्या करता है यह उपकरण आपके क्रमक द्वारा देखे गए सभी पुनःप्रसारकों को परखता है तथा आपके घटनाओं को सम्यक गन्तव्यों तक पुनःवितरण करता है : आपके द्वारा लिखे गए सभी घटनाओं का अवरोहण करें तथा आपके निर्गतपेटिका पुनःप्रसारकों को भेजें। @@ -2847,14 +2503,9 @@ क्या चलनशील संयोजान का प्रयोग करें। समचरणीकरण आरम्भ करें आरम्भ करें (चलनशील संयोजन पर भी) - विराम - पुनःचालू - पुनः आरम्भ से निरस्त करें पुनःप्रसारक : %1$d / %2$d घटनाएँ पुनःवितरित : %1$d नए %2$d भेजे गए तथा %3$d प्राप्त - समचरणीकरण विराम - सम्पन्न %2$d में से %1$d पुनःप्रसारक। %3$d घटनाएँ पुनःवितरित अब तक। पुनःचालू दबाएँ चलते रहने के लिए। समचरणीकरण समाप्त अग्रतःप्रेषित %2$d प्राप्त में से %1$d घटनाएँ गन्तव्य पुनःप्रसारकों तक। %1$d घटनाएँ गन्तव्य पुनःप्रसारकों द्वारा नव्यतः स्वीकृत। @@ -2869,16 +2520,13 @@ प्रेषित %1$s प्राप्त %1$s नव्य %1$s - कोई घटना नहीं द्व्यंकरूप्य समन्वेषक (ओटीएस॰) - घटनाएँ घटनाएँ आप से घटनाएँ आप को खोज साध्य घटनाएँ सीधेसन्देश परिचय निर्गतपेटिका सूचियाँ - पुनःप्रसारक स्थापना विकल्प पूर्व दृष्ट %1$s पहले पिछली बार दृष्ट %1$s पर (%2$s पूर्व) पिछली बार दृष्ट अभी @@ -2936,7 +2584,6 @@ आपके वैफै॰ पर यन्त्रों का खोज चालू… एचएलएस॰ आरोहण - बहुसुलझाव एचएलएस॰ प्रकाशित करें आपके प्रसारसंगणक में दृश्याभिलेख चुनें आपका दृश्याभिलेख अनेक सुलझावों में परिवर्तित किया जाएगा जिससे दर्शकों को स्निग्ध चालन प्राप्त होगा किसी भी संयोजन पर। परिवर्तन @@ -2951,10 +2598,6 @@ एच॰२६५ इस यन्त्र पर उपलब्ध नहीं। एच॰२६४ तक पुनःपतन। अभिव्यक्तियाँ स्रोत सुलझाव : %1$dघ्न%2$d - उत्पाद्य : %1$s - (%1$s त्यक्त - स्रोत ऊपर) - %1$d सहस्रांकप्रतिसेकण्ड - स्रोत ऊपर - त्यक्तव्य उच्छनिरूपण दृश्याभिलेख प्रकाशित करें प्रकाशन चालू \"%1$s\"… संकुचनान्तरण चालू %1$s @@ -2966,7 +2609,6 @@ दृश्याभिलेख प्रकाशित आपका उच्छनिरूपण दृश्याभिलेख नोस्टर पर चलन्त है। कुछ गडबड हुआ - टीका देखें हो गया पुनः प्रयास करें पोटली कार्य @@ -2981,30 +2623,21 @@ साक्ष्यांकन मान्य अमान्य - स्वीकृत - अस्वीकृत सत्यापन चालू - सत्यापित निरस्त %1$s से मान्य %1$s तक मान्य साक्ष्यांकन अनुरोध - घटना के लिए साक्ष्यांकन अनुरोध किया जा रहा है साक्षी अनुशंसा प्रकारों के लिए अनुशंसित : साक्षी निपुणता - प्रकारों के सत्यापन में निपुण : %1$s - इस के लिए साक्षी इस के लिए साक्ष्यांकन अनुरोध दिनांक सीमा से तक अभी समस्त काल - अन्तिम समचरणीकरण : %1$s - अन्तिम समचरणीकरण से जाल स्मर्त्तव्यचिह्न - अभी कोई जाल स्मर्त्तव्यचिह्न नहीं। जोडने के लिए + दबाएँ। जाल स्मर्त्तव्यचिह्न जोडें जाल स्मर्त्तव्यचिह्न सम्पादित करें जालपता @@ -3043,13 +2676,10 @@ https://example.com/image.jpg जालस्थान पता (वैकल्पिक) https://example.com - समय सीमा (वैकल्पिक) समय सीमा स्थापित करें नया उद्देश्य - उद्देश्य बनाएँ अदृश्य होने के लिए अनुरोध पुनःप्रसारकों को अनुरोध करें कि आपकी सभी जानकारी मिटाएँ चयनित दिनांक तक। यह कार्य निप॰६२ पर आधारित है तथा कुछ अधिकारक्षेत्रों में न्यायिक रूप से बाध्यकारी है। - एक पुनःप्रसारक का चयन करें लक्ष्य पुनःप्रसारक सभी पुनःप्रसारक यह सभी पुनःप्रसारकों को अनुरोध करेगा कि आपकी कुंचिका से सम्बन्धित सब कुछ मिटा दें चयनित दिनांक तक। इस घटना का यथासम्भाव्य विस्तृत प्रसार किया जाएगा। इसको पूर्ववत नहीं किया जा सकता। @@ -3065,7 +2695,6 @@ दिनांक का चयन करें समय का चयन करें अदृश्यीकरण इतिहास - नवीकरण ये आपके पूर्वकाल के अदृश्यीकरण अनुरोध घटनाएँ है जो संयोजित पुनःप्रसारकों में से प्राप्त हुए। इन घटनाओं में सूचित पुनःप्रसारकों में घटना दिनांक के पूर्व की आपकी कोई जानकारी नहीं रखनी चाहिए। कोई अदृश्यीकरण अनुरोध प्राप्त नहीं आपने कोई अदृश्यीकरण अनुरोध अभी तक भेजे नहीं। @@ -3108,7 +2737,6 @@ घटना प्रतिबन्धित करें प्रकार को अनुमति दें अंकीय जालपता अवरोधित करें - ख्याप्य कुंचिका (षोडशांक) घटना विभेदक (षोडशांक) प्रकार संख्या अंकीय जालपता @@ -3119,7 +2747,6 @@ पुनःप्रसारक नाम पुनःप्रसारक विवरण पनःप्रसारक चिह्न जालपता - पुनःप्रसारक प्रबन्धन प्रबन्धन सदस्य सूची %1$s के सदस्य @@ -3188,7 +2815,6 @@ भावचिह्न पोटली क्रियाएँ मेरे भावचिह्न पोटलियाँ भावचिह्न - भावचिह्न समुच्चय वीक्षण निजी निजी भावचिह्न सार्वजनिक भावचिह्न सब के लिए दृश्य हैं तथा आपके प्रतिक्रिया विकल्पसूची में उपस्थित होते हैं तथा \":\" स्वतःसम्पन्न चयनकर्ता में जब यह पोटली आपकी भावचिह्न सूची में है। @@ -3213,4 +2839,10 @@ नोव्हेर अभिलेख नोव्हेर कला नोव्हेर मंच + + ग्राहक की लैटनिंग सेवा %1$s पर उपलब्ध नहीं। इसका परिकलन किया गया \"%2$s\" लैटनिंग पता से। अपक्रम : %3$s। जाँच करें यदि सेवा संगणक चल रहा है तथा यदि लैटनिंग पता सम्यक है + %1$s का सुलझाव नहीं कर पाए। जाँच करें यदि आप संयोजित हैं, यदि सेवा संगणक चल रहा है तथा यदि लैटनिंग पता %2$s सम्यक है।\n\nअपवर्ग था : %3$s + %1$s से लाए गए चालान के जेसोन॰ परखनें में अपक्रम। उपयोगकर्ता की लैटनिंग स्थापना की जाँच करें + लैटनिंग चालान नहीं बना पाए। %1$s से संदेश : %2$s + %1$s से लैटनिंग चालान नहीं बना पाए। परिणाम जेसोन॰ में pr अम्श उपलब्ध नहीं। diff --git a/amethyst/src/main/res/values-hr-rHR/strings.xml b/amethyst/src/main/res/values-hr-rHR/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-hr-rHR/strings.xml +++ b/amethyst/src/main/res/values-hr-rHR/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-hu-rHU/strings.xml b/amethyst/src/main/res/values-hu-rHU/strings.xml index 5db637f2d3..7fa955ec12 100644 --- a/amethyst/src/main/res/values-hu-rHU/strings.xml +++ b/amethyst/src/main/res/values-hu-rHU/strings.xml @@ -36,8 +36,6 @@ Egyéb Zaklatás Erőszak - Ismeretlen - Átjátszóikon Ismeretlen szerző Szöveg másolása Szerző azonosítójának másolása @@ -52,12 +50,9 @@ Kéretlen tartalom vagy csalás bejelentése Profilutánzás bejelentése - Szókimondó tartalom bejelentése Illegális viselkedés bejelentése Malware bejelentése - Mod bejelentése Malware - Mod Ön nyilvános kulcsot használ, és a nyilvános kulccsal csak olvashatóak a bejegyzések. Jelentkezzen be a privát kulcsával, hogy válaszolni tudjon Ön nyilvános kulcsot használ, és a nyilvános kulccsal csak olvashatóak a bejegyzések. Jelentkezzen be a privát kulcsával, hogy meg tudja tolni a bejegyzéseket Ön nyilvános kulcsot használ, és a nyilvános kulcsok csak olvashatóak. Jelentkezzen be a privát kulccsal a hozzászólások kedveléséhez @@ -71,17 +66,14 @@ Ön nyilvános kulcsot használ, és a nyilvános kulccsal csak olvashatóak a bejegyzések. Jelentkezzen be a privát kulcsával, hogy ki tudja követni az embereket, akiket követ Ön nyilvános kulcsot használ, és a nyilvános kulccsal csak olvashatóak a bejegyzések. Jelentkezzen be a privát kulcsával, hogy egy szót vagy mondat el tudjon rejteni Ön nyilvános kulcsot használ, és a nyilvános kulccsal csak olvashatóak a bejegyzések. Jelentkezzen be a privát kulcsával, hogy egy szót vagy mondat meg tudjon jeleníteni - Ön nyilvános kulcsot használ, és a nyilvános kulcsok csak olvashatóak. A beállítások módosításához jelentkezzen be egy privát kulccsal Ön nyilvános kulcsot használ, és a nyilvános kulcsok csak olvashatóak. Jelentkezzen be egy privát kulccsal, hogy tudjon tartalmakat feltölteni Ön nyilvános kulcsot használ, és a nyilvános kulcsok csak olvashatóak. Jelentkezzen be egy privát kulccsal, hogy aláírhassa az eseményeket Jogosulatlan visszafejtés Az aláíró nem engedélyezte a művelet végrehajtásához szükséges visszafejtést. Aktiválja az NIP-44 visszafejtést az aláíró alkalmazásban, és próbálja meg újra Nem található az aláíró Az aláíró alkalmazás el lett távolítva? Ellenőrizze, hogy az aláíró telepítve van-e és rendelkezik-e ezzel a fiókkal. Jelentkezzen ki és jelentkezzen be újra, ha az aláíró alkalmazás megváltozott. - Az aláíró hibásan működött A külső aláíró a kéréstől eltérő, szokatlan választ küldött. Lehet, hogy hiba lépett fel az Amethystben vagy az aláíró alkalmazásban. Zap-ek - Megtekintések száma Megtolás megtolta szerkesztve @@ -94,9 +86,7 @@ Hozzáadás "válasz erre: " " és " - "csatornában " Profilplakát - Sikeres fizetés Hiba a hibaüzenet elemzésekor " Követett" " Követő" @@ -169,7 +159,6 @@ Nincs elég egyenleg egy olyan mint-ben, amit ez a címzett elfogad. Előbb fel kell tölteni a cashu-pénztárcát. A címzett számára elküldhető összeg: %1$s satoshi Hálózati díj - Saját pénztárca-alkalmazás Tranzakció: %1$s Lightning-borravaló Bejegyzés a kedvezményezettnek @@ -183,16 +172,13 @@ Látható előtag 😎 Hozzáadás a bejegyzéshez - "Hiba a következő előnézet elemzésekor %1$s : %2$s" "Kártyakép előnézete a következőhöz: %1$s" Cikk - Új csatorna Csatornanév A nagyszerű csoportom Kép webcíme Kép webcíme (nem kötelező) Leírás - Nem található leírás "Névjegy… " Mi jár a fejében? Üzenet írása… @@ -202,42 +188,25 @@ Létrehozás Átnevezés Mégse - Nem sikerült feltölteni a képet - Átjátszó címe - Bejegyzések - Bájt Hiba Hibák Az átjátszóhoz való sikeres kapcsolatok százalékos aránya - Ebben a munkamenetben lévő kapcsolati hibák száma - Kezdőlap hírcsatornája - Privát üzenethírfolyam - Nyilvános csevegési hírfolyam - Globális hírfolyam - Hírfolyam keresése Felhasználó keresése és hozzáadása - Felhasználó ozzáadása Egy átjátszó hozzáadása - Név - Név (az @említéshez) Saját @említési név Megjelenítendő név Saját megjelenítendő név Strucc McNagyszerű Üdvözöljük! Felhasználónév - Saját felhasználónév Névjegy Profilkép webcíme Profilplakát webcíme Weboldal webcíme Megszólítás - LN-cím - LN-webcím (elavult) A forrásátjátszók elavultak lehetnek Elavult átjátszóra vonatkozó figyelmeztetés Mentés a telefonra - Mentés a galériába Kép mentve a képgalériába A videó letöltése megkezdődött… A média letöltése megkezdődött… @@ -253,16 +222,14 @@ Fájl feltöltése Kép készítése Videó rögzítése + Ezen az eszközön nem található kameraalkalmazás Hangüzenet rögzítése - Hangüzenet rögzítése Hangüzenet rögzítéséhez kattintson és tartsa lenyomva a gombot Újrarögzítés Rögzítés %1$s rögzítése - Feltöltés… Feltöltési hiba Nem sikerült feltölteni a hangüzenetet - Váratlan feltöltési állapot A NIP-95 még nem támogatja a hangüzeneteket Nem sikerült feltölteni a hangüzenetet: %1$s Semmi @@ -274,8 +241,6 @@ A felhasználó nem rendelkezik a satoshik fogadásához beállított lightning-címmel "Válasz írása… " Ebben a csevegésben - A bejegyzés azonosítóját a vágólapra másolja a Nostr-ban való megosztáshoz - Csatorna-azonosító (bejegyzés) másolása a vágólapra Szerkeszti a csatorna metaadatait Csatlakozás Ismert @@ -289,7 +254,6 @@ Válaszok Saját Galéria - "Követett" "Bejelentés" "%1$s jelentés" További beállítások @@ -297,11 +261,8 @@ Weboldal Lightning-cím Az Nsec azonosítót (az Ön „jelszavát”) a vágólapra másolja biztonsági mentés céljából - Titkos kulcs másolása a vágólapra Privát kulcs megjelenítése QR-kódként Jelszóval védett privát kulcs megjelenítése QR-kódként - Nyilvános kulcs másolása a vágólapra a megosztáshoz - Nyilvános kulcs (NPub) másolása a vágólapra Közvetlen üzenet küldése Felhasználó metaadatainak szerkesztése Követés @@ -330,8 +291,6 @@ Hogyan szólíthatjuk Önt? Még nincs Nostr-fiókja? Már van Nostr-fiókja? - Új fiók létrehozása - Új kulcs előállítása Hírfolyam betöltése Fiók betöltése… titkosított @@ -347,13 +306,7 @@ Szavazás megnyitása A hírfolyam üres. Frissítés - létrehozva - a következő leírásával: - és kép - megváltoztatta a csevegés nevét erre: Új csevegési profil: - leírását erre: - és a képet erre: Elhagyás Követés megszüntetése Csatorna létrehozva @@ -390,7 +343,6 @@ Nostr-cím soha most - másodperc ó p n @@ -398,7 +350,6 @@ Trágárság / Gyűlöletbeszéd Gyűlöletbeszéd bejelentése Meztelenség / Pornó bejelentése - egyéb Az összes ismert megjelölése olvasottként Az összes új üzenet megjelölése olvasottként Összes megjelölése olvasottként @@ -419,8 +370,6 @@ Nem sikerült hitelesíteni A biometrika nem tudta hitelesíteni a telefon tulajdonosát A biometrika nem tudta hitelesíteni a telefon tulajdonosát. Hiba: %1$s - Hiba - "Létrehozta: %1$s" "Kitűző %1$s számára" Kitűző képe Ön egy új kitűzőt kapott @@ -428,7 +377,6 @@ Bejegyzés szövege a vágólapra másolva A szerző @npub-ja a vágólapra másolva A bejegyzés-azonosító (@note1) a vágólapra másolva - Szöveg kijelölése "<Nem sikerült a privát üzenetet visszafejteni>\n\nÖnt megemlítették egy privát/titkosított beszélgetésben %1$s és %2$s között." Új fiók hozzáadása Fiókok @@ -440,8 +388,6 @@ Fiók kiválasztása Új fiók hozzáadása Aktív fiók - Privát kulcsot tartalmaz - Csak olvasás, nem privát kulcs Vissza Kiválasztás Böngésző-hivatkozás megosztása @@ -466,14 +412,12 @@ Szál némítása Szál némításának megszüntetése Bejelentés - Törlés Ne jelenítse meg újra Kéretlen tartalom vagy átverés Trágárság vagy gyűlöletkeltő magatartás Rosszindulatú profilutánzás Meztelenség vagy pornográf tartalom Illegális viselkedés - Malware A felhasználó letiltásával elrejti annak bejegyzéseit az alkalmazásban. Az Ön bejegyzései továbbra is nyilvánosan megtekinthetők azok számára is, akiket Ön letiltott. A letiltott felhasználók a „Biztonsági szűrők” lapon jelennek meg. Visszaélés bejelentése @@ -501,7 +445,6 @@ Válasszon ki egy időpontot Ütemezés… Közzététel: %1$s - Már %1$s ezelőtt esedékes volt Időpont Bejegyzés ütemezése Ütemezés visszavonása @@ -576,7 +519,6 @@ Szerző Kérések Jóváhagyások - Nincs olyan közösség, amely megfelelne ennek a szűrőnek. Ellenőrizhető szabályok (nem kötelező) A közösség mellett egy géppel olvasható szabálydokumentumot (NIP-9B) is közzétesz. Az ezt támogató kliensek küldés előtt eltávolítják a szabályoknak meg nem felelő bejegyzéseket. Engedélyezett eseménytípusok @@ -605,26 +547,15 @@ WoT-szűrő hozzáadása Globális maximális eseményméret (nem kötelező) Bájtban \u2014 hagyja üresen, ha nem szeretne globális korlátozást megadni. - Fogadott - Saját - Kitüntetett - Felfedezés Új kitűző - Kitűző szerkesztése Kitüntetési kitűző Elfogadás Elutasítás Eltávolítás a profilból - Kitűzőazonosító (d-tag) - bátorság, közreműködő-2025… Név Olvasható kitűzőnév Leírás Miért osztják ki ezt a kitűzőt? - kép webcíme (1024×1024) - https://pelda.hu/kituzo.png - Bélyegkép webcíme (nem kötelező) - https://pelda.hu/kituzo-belyegkepe.png Kép feltöltése Válasszon ki egy négyzet alakú képet a kitűző számára. Kitűző betöltése… @@ -633,7 +564,6 @@ Eltávolítás Cím nélküli kitűző A kitűzőt %1$d érdemelte ki - Ön kapott egy kitűzőt Profilkitűzők Kitűzők · %1$d Válassza ki, hogy a megszerzett kitűzők közül melyek jelenjenek meg a profilban. @@ -679,12 +609,7 @@ Edzések megosztása Engedélyezze az Amethyst alkalmazás számára, hogy beolvassa a befejezett edzéseit a Health Connectből (Samsung Health, Google Fit, Fitbit, Garmin…), és bejegyzést javasoljon. Kapcsolódás - Új edzés észlelve - Megosztás - Eltüntetés %1$s km - %1$s bpm - %1$s kcal Health Connectből Futás Gyaloglás @@ -698,7 +623,6 @@ Étrend Böjt Alkalmazások - Alkalmazások Forrás: %1$s v%1$s Letöltés @@ -707,12 +631,10 @@ Témák Hivatkozások Legújabb kiadás - Megjegyzések Legyen Ön az első hozzászóló. általa Korábbi kiadások megjelenítése Korábbi kiadások elrejtése - Naptárak Rövidek Nyilvános csevegések Követési csomagok @@ -722,18 +644,14 @@ egy hangszoba Színpad Várakozás az előadókra… - Közönség Kéz felemelése Kéz leengedése Hang csatlakoztatása - Kapcsolat bontása Némítás Némítás megszüntetése - Kapcsolódás… Szoba feloldása Átvitel megnyitása Hang egyeztetése - Hang csatlakoztatva Újrakapcsolódás… Felvétel meghallgatása Nem sikerült elküldeni az üzenetet @@ -741,9 +659,7 @@ Bezárja ezt a szobát? Minden résztvevő le lesz választva. A szoba BEZÁRVA fog megjelenni a hírfolyamban. Szoba bezárása - Válasszon egy jövőbeli kezdési időpontot. Hanghiba: %1$s - A hang nem érhető el ebben a szobában Beszéd Színpad elhagyása Mikrofon némítása @@ -751,7 +667,6 @@ Élő közvetítés elkezdése… Nem sikerült a közvetítés: %1$s Nem sikerült némítani: %1$s - Az Amethystnek hozzáférésre van szüksége a mikrofonhoz a beszélgetéshez ebben a szobában. Nincsenek engedélyek Hangszobák Hang lejátszása, amíg a szoba meg van nyitva. @@ -762,7 +677,6 @@ Csatlakozás a hangszobához Kiszolgáló Megnyitás - Legutóbbi csevegés Jelenleg senki sincs a szobában. %1$d hallgató Kiszolgáló @@ -790,8 +704,6 @@ Közönség Kezek Még senki sem hallgatja. - Küldés - Mondjon valamit… Még nincsenek üzenetek. Legyen Ön az első hozzászóló. Reagálás Szoba szerkesztése @@ -825,7 +737,6 @@ Sikertelen művelet A műveletet nem sikerült előkészíteni. Szoba megosztása - Minimalizálás Minimalizálás a további hallgatáshoz A hang megszakadt Szoba betöltése… @@ -858,7 +769,6 @@ Válassza ki, hogy az Amethyst mely MoQ-kiszolgálókon tegye közzé a hangszobáit. Új tér indításakor alapértelmezetten az első bejegyzés kerül felhasználásra. Saját kiszolgálók Kind-10112 típusú cserélhető eseményként mentve, így más kliensek is olvashatják az Ön beállítását. - Hangszoba-kiszolgáló hozzáadása Átjátszó (WebTransport) webcíme Hitelesítési (JWT mint) webcím Hozzáadás @@ -871,13 +781,11 @@ Kiszolgáló eltávolítása Még nincsenek hangszoba-kiszolgálók. Adjon hozzá egyet alább, vagy válasszon egy ajánlott kiszolgálót. Videók - Cikkek Zene Lejátszási listák Részek Hangműsor Részek megtekinése - Részek Nem találhatók részek %1$d rész @@ -889,9 +797,6 @@ Szám címe Előadó Előadó neve - Hang webcíme - https://… .mp3 - Borítókép webcíme (nem kötelező) Album (nem kötelező) Időtartam másodpercben (nem kötelező) Dalszöveg vagy stáblista (nem kötelező) @@ -901,7 +806,6 @@ Hozzáadás a lejátszási listához Önnek még nincs lejátszási listája. A fenti mező segítségével hozhat létre egyet. Összes lejátszási lista kezelése - Új lejátszási lista Lejátszási lista neve Létrehozás (cím nélküli lejátszási lista) @@ -937,9 +841,6 @@ Könyvjelzőlista törlése Bejegyzések megtekintése Cikkek megtekintése - Hivakozások megtekintése - Kulcsszavak megtekintése - Még nincs egyetlen könyvjelzőlistája sem. Koppintson az „Új” gombra, hogy létrehozzon egyet. Kulcsszócsomagok Még nincs egyetlen érdeklődési csomagja sem. Koppintson az „Új” gombra, hogy létrehozzon egyet. Új érdeklődési csomag @@ -958,7 +859,6 @@ Privát bejegyzések (%1$s) Nyilvános bejegyzések Nyilvános bejegyzések (%1$s) - Privát cikkek Privát cikkek (%1$s) Nyilvános cikkek Nyilvános cikkek (%1$s) @@ -985,16 +885,6 @@ A könyvjelzőlisták metaadatai a Nostr-on bárki számára láthatók. Csak a privát tagok vannak titkosítva. Áthelyezés a nyilvános könyvjelzőkbe Áthelyezés a privát könyvjelzőkbe - Wallet Connect szolgáltatás - Lehetővé teszi az Amethyst számára, hogy az alkalmazásból kilépés nélkül fizessen. Tartsa biztonságos helyen a titkot! - Wallet Connect nyilvános kulcs - Wallet Connect átjátszó - Wallet Connect titok - Titkos kulcs megjelenítése - nsec / hex privát kulcs - Kapcsolódva - Nem kapcsolódott - Speciális: kapcsolat részleteinek kézi megadása Gyors Zap-összegek A „Zap” gomb megnyomásakor jelenik meg. Az egyes összegeket a címzett által támogatott bármely fizetési csatornán keresztül ki lehet fizetni - Lightning, Cashu vagy láncon belül (láncon belül csak nagyobb összegek esetén). Érintse meg az összeget annak eltávolításához. Ha üresen hagyja, a rendszer minden alkalommal megnyitja az összeg megadására szolgáló párbeszédpanelt. Küldés inkább láncon belül @@ -1026,14 +916,8 @@ Pénztárca összekapcsolása Átjátszó hírfolyamának megtekintése Hozzájárulás összege satoshiban - Szavazás közzététele - Kötelező mezők: - Zap-kedvezményezettek - Szavazás elsődleges leírása… - Lehetőség %s. válaszlehetőség Válaszlehetőség leírása - Nem kötelező mezők: Minimum Zap Maximum Zap Együttműködés @@ -1042,11 +926,8 @@ Több lehetőség Szavazás lezárásának dátuma és ideje A szavazás lezárul %1$s múlva - Szavazás lezárása - nap Nem lehet szavazni A szavazásra már nem lehet új szavazato(ka)t leadni - Zap-összeg Az ilyen típusú szavazásokon felhasználónként csak egy szavazat engedélyezett "%1$s esemény keresése" Zap küldése @@ -1082,11 +963,8 @@ Nem Zap Nostr-ban nyoma sincs, csak a Lightning-ban Névtelen - Közzététel új, eldobható profillal. Az Ön saját fiókja nem lesz köthető ehhez a válaszhoz. - Ez a válasz egy új, névtelen profilból lesz közzétéve Fájlkiszolgáló Válasszon ki egy kiszolgálót a fájl feltöltéséhez neki: - Ln-cím vagy @Felhasználó Médiakiszolgálók Állítsa be a kívánt médiafeltöltő-kiszolgálókat. Helyi Blossom gyorsítótár használata @@ -1095,10 +973,8 @@ Helyi gyorsítótár nem található a 24242-es porton. Csak a profilképek gyorsítótárazása A helyi gyorsítótár korlátozása csak a profilképekre. A hírfolyamban megjelenő képek és videók közvetlenül az eredeti kiszolgálókról lesznek letöltve. - Nincsenek beállítva NIP-96 kiszolgálók. Használhatja az Amethyst listáját, vagy hozzáadhat egyet az alábbiakból ↓ Nincsenek Blossom-kiszolgálók beállítva. Használhatja az Amethyst listáját, vagy hozzáadhat egyet az alábbiakból ↓ Ajánlott médiakiszolgálók - Beépített médiakiszolgálók Az Amethyst alapértelmezett listája. Hozzáadhatja őket egyenként, vagy hozzáadhatja a listát. Alapértelmezett lista használata Médiakiszolgáló hozzáadása @@ -1121,38 +997,21 @@ Kivonatolás Kész Hiba - Saját átjátszók (NIP-95) - A fájlokat a kiszolgálók tárolják. Új NIP: ellenőrizze, hogy támogatják-e Adatvédelmi beállítások - Tor és Orbot beállítása - Kapcsolódás az Orbot beállításain keresztül Módosítás Tor-beállítások - Kapcsolat bontása az Orbottal / Torral? - Az Ön adatai azonnal átkerülnek a normál hálózatra Igen Nem - Követési lista Minden ami követett Minden követett felhasználó Alapértelmezett követési lista - Követés proxyn keresztül Közelben lévők bejegyzései Globális Válogatott - Sakk Saját Némítottak bejegyzései Követési listák Ezek a követési listák az Ön saját alkalmazáshasználatából lettek kialakítva. A felhasználókat privát vagy nyilvánosan követheti - Címkézett könyvjelzők - Általános könyvjelzők - Nyílvános - Privát - Kevert - Úgy tűnik, hogy még egyetlen gyüjteményt sem követ. - \nKoppintson a frissítéshez vagy érintse meg a hozzáadás gombot a gyüjtemény létrehozásához. - Új Szerző hozzáadása a követési listához Felhasználó hozzáadása vagy eltávolítása a listákból, vagy új lista létrehozása ezzel a felhasználóval. @@ -1161,23 +1020,9 @@ %1$s egy privát tag Hozzáadás mint nyílvános tag Hozzáadás mint privát tag - Nyilvános tagok - Privát Tagok - Nyílvános profilok - Privát profilok - tag - tagok - Nincsenek tagok Üres - A(z) %1$s nincs a listában %1$s nem tag Saját listák és %1$s - Saját listák - Nem találhatók vagy Önnek még nincs követési listája. Koppintson az alábbi gombra a frissítéshez vagy használja a menüt egy új lista létrehozásához. - Probléma történt a következő lekérdezésekor: %1$s - Új lista létrehozása - Új lista %1$s tagsággal - Egy új követési gyüjtemény létrehozása, és %1$s hozzáadása mint %2$s tag. Új követési lista Új követési csomag Követési lista másolása/klónozása @@ -1197,14 +1042,6 @@ Ön átnevezi a követési gyüjteményt erről: erre: Alapértelmezett port: 9050 - ## Kapcsolódás a TORon keresztül az Orbot segítségével - \n\n1. Telepítse az [Orbotot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Indítsa el az Orbotot - \n3. Ellenőrizze az Orbotban a Socks-portokat. Az alapbeállítás: 9050 - \n4. Ha szükséges az Orbotban változtassa meg a portot - \n5. Ezen a felületen állítsa be a Socks-portot - \n6. Kattintson az „Aktiválás” gombra, hogy az Orbotot proxyként használja - Orbot Socks-portja Aktív Tor-motor Használja a beépített verziót vagy az Orbotot @@ -1246,8 +1083,6 @@ IP-cím elrejtése az összes kapcsolatnál Készítsen sajátot Érvénytelen portszám - Orbot használata - Kapcsolat bontása a Torral / Orbottal Privát üzenetek Értesítés, ha privát üzenet érkezik Zap-et kapott @@ -1304,12 +1139,8 @@ Bluetooth Hanghívás Videóhívás - Várakozás mások csatlakozására\u2026 Résztvevő hozzáadása Felhasználók keresése\u2026 - Nem sikerült hívást kezdeményezni - Nem sikerült elfogadni a hívást - Nem sikerült létrehozni a hívási munkamenetet Engedély szükséges Az Amethyst alkalmazásnak hozzáférésre van szüksége a mikrofonhoz a hanghívások kezdeményezéséhez. Engedélyezze ezt az alkalmazás beállításaiban. Az Amethyst alkalmazásnak hozzáférésre van szüksége a kamerához és a mikrofonhoz a videohívások kezdeményezéséhez. Engedélyezze ezeket az alkalmazás beállításaiban. @@ -1345,30 +1176,21 @@ Folyamatos kapcsolatot tart fenn a beérkező üzenetek átjátszóival az értesítések azonnali kézbesítése érdekében. Megjeleníti a folyamatban lévő értesítéseket. Több akkumulátort fogyaszt, de így biztosan nem marad le egyetlen üzenetről sem. Értesítések szétválasztása követések szerint Két értesítési fül megjelenítése — Követettek (akiket Ön követ) és Mindenki. Az olvasatlan jelző csak a követett személyek aktivitása esetén világít. + Üzenetek megjelenítése + Közvetlen és csoportos üzenetek megjelenítése az Értesítések lapon. Kapcsolja ki, ha az üzeneteket csak az Üzenetek lapon szeretné látni. Követés Mindenki Akkumulátor-optimalizálás aktív Az Android korlátozhatja a háttérben futó átjátszókapcsolatokat. Az Amethyst esetében tiltsa le az akkumulátor-optimalizálást a megbízható értesítések biztosítása érdekében. Javítás most Értesítés: - Csatlakozás a beszélgetéshez - Felhasználó- vagy csoport-azonosító - npub, nevent vagy hex - Létrehozás - Csatlakozás Ma Tartalomra vonatkozó figyelmeztetés Figyelmeztetés: %1$s Ez a bejegyzés érzékeny tartalmat tartalmaz, amelyet egyesek sértőnek vagy zavarónak találhatnak - Az érzékeny tartalmat mindig rejtse el - Az érzékeny tartalmat mindig jelenítse meg - A tartalomra vonatkozó figyelmeztetéseket mindig jelenítse meg Elrejtés Megjelenítés Figyelmeztetés - Ajánlott alkalmazások: - Az idegenektől érkező kéretlen tartalmak szűrése - Figyelmeztessen amikor a bejegyzések jelentve vannak azok által akiket követek Kéretlen tartalomszűrő Elrejti az ismeretlen felhasználók hozzászólásait, amelyek pontosan ugyanazok voltak 5 vagy több alkalommal Klienscímke hozzáadása a saját eseményekhez @@ -1400,22 +1222,17 @@ Az átjátszónak küldött bájt-mennyiség, beleértve a szűrőket és eseményeket is Az átjátszótól kapott bájt-mennyiség, beleértve a szűrőket és eseményeket is Tárolt események - Hiba lépett fel, amikor megpróbálta lekérni az átjátszó-információt innen: %1$s Tulajdonos Használat a következővel: Szolgáltatási kulcs - %1$s futtatása - %1$s (%2$s) futtatása Verzió Szoftver Kapcsolat Támogatott NIP-ek Támogatott tartalomkezelők - Csatlakozási díj Felvétel Előfizetés Közzététel - %1$s kifizetések Fizetési webcím Célközönség Irányelvek és hivatkozások @@ -1423,7 +1240,6 @@ Korlátozások Országok Nyelvek - Címkék Témák Összes ország Összes nyelv @@ -1438,64 +1254,48 @@ Megnyitás Olvasás Írás - RTT (válaszidő) Hálózat Típus Támogatott NIP-ek Követelmények - Utoljára ellenőrizve %1$d ms Elfogadott típusok Helyszín Aktív előfizetések - Függőben lévő kimenő események Szükséges előfizetések (%1$d) Előfizetések száma (%1$d) Kimenő események (%1$d) - Nincsenek aktív előfizetések ehhez az átjátszóhoz %1$d szerző %1$d azonosító ekkortól: %1$s eddig: %1$s %1$d korlátozás - Üzenethossz - Előfizetések - Szűrők - Előfizetés azonosítójának hossza Minimális előtaghossz Eseménycímkék száma legfeljebb - Tartalomhossz Tartalom hossza legfeljebb Ettől régebbiek elvetése: Elfogadások legfeljebb %1$s a jövőben %1$s ezelőtt - %1$s nulla %1$s bit Eseménymegőrzés Tartalom mérete Kapcsolat Hozzáférés-vezérlés Kéretlen tartalmak szűrésének erőssége - Hitelesítés Hitelesítés szükséges - Fizetés Fizetés szükséges Üzenet hossza legfeljebb Előfizetések legfeljebb Szűrők száma feliratkozásonként Korlátozás (visszatérő események) - Alapértelmezett korlátozás (visszatérő események) Feliratkozás-azonosító hossza legfeljebb Cashu token Mint: %1$s Beváltás - Küldés ide: Zap Wallet - Megnyitás a Cashu pénztárcában Token másolása Megnyitás másik alkalmazásban Nincs beállítva Lightning-cím - Token a vágólapra másolva ÉLŐ OFFLINE VÉGET ÉRT @@ -1546,7 +1346,6 @@ Marmot-állapot visszaállítva. Nem sikerült visszaállítani a Marmot-állapotot: %1$s Mindig - Csak Wi-Fi-n Korlátlan Wi-Fi Soha Teljes @@ -1571,7 +1370,6 @@ Bejegyzés stílusának kiválasztása Profilgaléria stílusa Válassza ki a galéria stílusát - Kép betöltése Spamelők Némítva. Koppintson a némitás megszüntetéséhez Hang bekapcsolva. Koppintson a némításhoz @@ -1583,18 +1381,13 @@ Nostr-cím hitelesítve lett Nostr-cím hitelesítése sikeretelen Nostr-cím ellenőrzése - Összes kijelölése / elvetése Alapértelmezett Visszaállítás alapértelmezettre - A folytatáshoz válasszon ki egy átjátszót - Zap-ek továbbítása neki: - A funkciót támogató kliensek a Zap-eket az alábbi LN-címre vagy felhasználói profilra továbbítják az Öné helyett A helyszín megjelenítése mint Hozzáadja a helyszínének geokivonatát a bejegyzéséhez. A nyilvánosság tudni fogja, hogy a jelenlegi helytől 5 km-en (3 mi) belül tertózkodik Helyszín-alapú bejegyzés Csak a helyszín követői láthatják. Az általános követők nem fogják látni. Kulcsszóexkluzív bejegyzés - Csak a kulcsszó követői fogják látni, de az Ön általános követői viszont nem. Megjegyzés egy weboldalhoz Megjegyzés egy külső forráshoz Olvasási idő: %1$d perc @@ -1615,9 +1408,7 @@ Egy hangfájl feltöltése Válasszon ki egy MP3-, WAV- vagy FLAC-fájlt. A „Mentés” gombra koppintva a fájl feltöltődik a médiakiszolgálóra. A hangfájl készen áll a feltöltésre - Feltöltés… Borító és hangfájl feltöltése, majd közzététel. Ez akkor is folytatódik, ha elhagyja a képernyőt. - Nem sikerült feltölteni: %1$s Lejátszási lista szerkesztése Lejátszási lista szerkesztése Cím @@ -1638,13 +1429,9 @@ A helyszín-meghatározás nincs engedélyezve Hozzáadja az érzékeny tartalomra vonatkozó figyelmeztetést a tartalom megjelenítése előtt. Ez ideális bármilyen NSFW tartalom vagy olyan tartalom esetén, amelyet egyesek sértőnek vagy zavarónak találhatnak Indoklás (nem kötelező) - Új funkció - Ennek az üzemmódnak az aktiválásához az Amethystnek NIP-17 üzenetet kell küldenie (GiftWrapped, Sealed Direct és csoport-üzenetek). A NIP-17 új, és a legtöbb kliens még nem implementálta. Győződjön meg arról is, hogy a kedvezményezett kompatibilis klienst használ. - Aktiválás Nyilvános Csoport Új nyilvános vagy privát csoport - Átjátszó Privát Neki: Tárgy @@ -1656,9 +1443,6 @@ Kifejtés a csoport tagjai számára Név megváltoztatása az új célok érdekében. Beszúrás vágólapról - Érvénytelen NIP-47 URI - A(z) %1$s URI nem egy érvényes NIP-47 bejelentkezési URI. - Kapcsolódás az új NWC-pénztárcához Nem található pénztárca Az Amethyst nem talált olyan pénztárca-alkalmazást, amely támogatja a Nostr Wallet Connect (NWC) szolgáltatást. \n\nAmit tehet: @@ -1675,7 +1459,6 @@ Videók és GIF-ek automatikus betöltése Videók automatikus lejátszása, amint megjelennek a kijelzőn Webcím-előnézetek megjelenítése - Mikor töltse be a képeket Köteg másolása Másolás a vágólapra Vágólapra másolva @@ -1691,43 +1474,21 @@ Média hozzáadva Média hozzáadva az Ön profil-galériájába Létrehozva ekkor: - Szabályok - Névjegy Útmutatók Moderátorok Bejelentkezés Amberrel Állapot frissítése - Hiba a hibaüzenet elemzésekor A szavazatok egy Zap összeggel vannak súlyozva. Beállíthat egy minimális összeget, hogy elkerülje a spamelőket, és egy maximális összeget, hogy elkerülje, hogy a nagy Zap-elők átvegyék a szavazást. Használja ugyanazt az összeget mindkét mezőben, hogy minden szavazatot ugyanannyira értékeljen. Hagyja üresen, hogy bármilyen összeget elfogadjon. Nem sikerült Zap-et küldeni Üzenet a felhasználónak Üzenet: %1$s OK - Nem sikerült elérni a következőt: %1$s: %2$s - Nem sikerült összeállítani a NIP-11 webcímet a következőhöz: %1$s: %2$s - Nem sikerült elérni a következőt: %1$s: %2$s - Nem sikerült a válasz elemzése a következőtől: %1$s: %2$s - Az átjátszó elutasította a következő kérést: %1$s: %2$s - Nem sikerült elérni a következőt: %1$s: %2$s - Nem sikerült az eredmény elemzése a következőtől: %1$s: %2$s - A(z) %1$s sikertelen a következő kóddal %2$s - Aktív: - Kezdőlap - Privát üzenetek - Csevegések - Globális - Keresés Zap-ek megosztása és továbbítása A funkciót támogató kliensek megosztják és továbbítják a Zap-eket az itt hozzáadott felhasználóknak az Ön felhasználói helyett Felhasználó keresése és hozzáadása Felhasználónév vagy megjelenítendő név Hiányzó lightning-beállítás A(z) %1$s nevű felhasználó nem rendelkezik a satoshik fogadására beállított lightning-címmel - Százalék - 25 - A Zap-ek megosztása vele: - Zap-ek továbbítása ide: - Nem található lightning-pénztárca Fizetve Pénztárca: %1$s Hiba az aláíró-alkalmazás megnyitásakor @@ -1736,7 +1497,6 @@ Az eszköz nem támogatja a kódolást vagy a formátumot (%1$s). Próbálja meg a böngészőben megnyitni. Megnyitás böngészőben Aláírási kérés elutasítva - Aláíró-alkalmazás elutasítva Győződjön meg arról, hogy ezt a tranzakciót az aláíró-alkalmazás hitelesítette-e Nem található pénztárca a Lighning-számla kifizetéséhez (Hiba: %1$s). A Zap-ek használatához telepítsen egy Lightning-pénztárcát Nem található pénztárca a Lighning-számla kifizetéséhez. A Zap-ek használatához telepítsen egy Lightning-pénztárcát @@ -1752,40 +1512,23 @@ Válasszon egy lehetőséget Nem sikerült kifizetni a számlát Nem sikerült a pénzkivétel a pénztárcából - Nem sikerült beállítani a Wallet Connectet - Hiba a NIP-47 kapcsolati karakterlánc elemzésekor. Ellenőrizze, hogy a pénztárca-szolgáltatónál a következő helyes-e: %1$s. Hiba: %2$s - Hiba a NIP-47 kapcsolati karakterlánc elemzésekor. Ellenőrizze, hogy a pénztárca-szolgáltatónál a következő helyes-e: %1$s. Nem sikerült a Cashut beváltani A pénzverde a következő hibaüzenetet küldte:%1$s - A Cashu tokeneket már elköltötték. Cashu megkapva %1$s satoshi érkezett a pénztárcájába. (Költség: %2$s satoshi) A rendszeren nem található kompatibilis Cashu pénztárca Nem sikerült a számlát a kedvezményezett kiszolgálóiról lekérni A Wallet Connect szolgáltatója a következő hibával tért vissza: %1$s - Nem sikerült a Tor hálózathoz kapcsolódni Nem sikerült kapcsolódni a Tor hálózathoz Az Amethystnek nem sikerült befejeznie a Tor előkészítését. Legyen normál (nem Tor) kapcsolat használva a hírfolyam betöltéséhez? A választás egy óráig érvényes, utána a rendszer ismételten megkísérli a Tor hálózathoz való kapcsolódást. Normál kapcsolat használata Tovább várok - Nem érhető el az átjátszó-dokumentum Nem sikerült az LN-webcímet a(z) „%1$s” Lightning-címről összeállítani. Ellenőrizze a felhasználó beállításait - A kedvezményezett lightning-szolgáltatása ennél: %1$s nem érhető el. A(z) „%2$s” lightning-cím lett kiszámítva. Hiba: %3$s. Ellenőrizze, hogy a kiszolgáló működik-e, és hogy a lightning-cím helyes-e - Nem sikerült megoldani a következőt: %1$s. Ellenőrizze, hogy kapcsolódik-e, vagy működik-e a kiszolgáló, és hogy a(z) %2$s lightning-cím helyes-e - Nem sikerült megoldani a következőt: %1$s. Ellenőrizze, hogy kapcsolódik-e, vagy működik-e a kiszolgáló, és hogy a(z) %2$s lightning-cím helyes-e.\n\nKivéve: %3$s - Nem sikerült lekérni a számlát a következőtől: %1$s Nem sikerült lekérni a számlát a következőtől: %1$s: %2$s - Hiba a Lightning-címből származó JSON elemzésekor. Ellenőrizze a felhasználó Lightning-beállítását Hiba történt a(z) %1$s JSON elemzésekor. Ellenőrizze a felhasználó Lightning-beállítását - A visszahívási webcím nem található a felhasználó lightning-cím-kiszolgálójának konfigurációjában Nem található a visszahívási webcím a(z) %1$s válaszából - Hiba történt a JSON elemzésekor a Lightning-cím számlahívásából. Ellenőrizze a felhasználó lightning-beállításait - Hiba történt a JSON elemzésekor a(z) %1$s számlahívásából. Ellenőrizze a felhasználó lightning-beállításait Helytelen (%1$s satoshi) számlaösszeg a következőtől: %2$s. A következőnek kellett volna lennie: %3$s Nem sikerült a Zap-összeg elküldése előtt lightning-számlát készíteni. A címzett lightning-pénztárcája a következő hibát küldte: %1$s - Nem lehetett lightning-számlát létrehozni. Üzenet a következőtől: %1$s: %2$s - Nem sikerült Lightning-számlát létrehozni a Zap elküldése előtt. A „PR” elem nem található a kapott JSON-ban. - Nem sikerült Lightning-számlát létrehozni a következőből: %1$s: A „PR” elem nem található a kapott JSON-ban. Csak olvasható felhasználó Nincs reakcióbeállítás Értesítések @@ -1811,13 +1554,11 @@ Üzenet küldése az eladónak Tisztelt %1$s! Ez még aktuális? Tisztelt hölgyem / uram! Ez még aktuális? - Egy tétel eladása Cím iPhone 13 Állapot Kategória Ár (satoshiban) - 1000 Helyszín Város, állam, ország Új @@ -1846,20 +1587,13 @@ Egyéb Nem sikerült feltölteni a médiát Nem sikerült megnyitni a tömörített fájlt - Hiba a média tömörítésekor: %1$s Feltöltési hiba: %1$s A kiszolgáló a feltöltés után nem szolgáltatott webcímet Nem sikerült letölteni a kiszolgálóról az oda feltöltött médiát Nem lehetett ellenőrizni a letöltött fájlt a feltöltés után: %1$s - Nem sikerült előkészíteni feltöltésre a helyi fájlt: %1$s Nem sikerült feltölteni a következőre: %1$s: %2$s - Nem sikerült feltölteni: %1$s Nem sikerült törölni: %1$s Média túl nagy a NIP-95 számára - Nem sikerült betölteni a bélyegképet - Nem sikerült előkészíteni a fejlécadatokat: %1$s - Tömörítés visszavonva - A tömörítés nem tudott visszaadni egy fájlt Fájlok titkosítása Az adatok védelme érdekében titkosítsa a fájlokat a feltöltés előtt. Egyes kiszolgálók az ingyenes fiókok esetében nem biztos, hogy elfogadják a titkosított fájlokat. Titkosított feltöltés sikertelen @@ -1886,27 +1620,18 @@ Nem sikerült eltávolítani az AVIF-fájl metaadatait: %1$s Piszkozat szerkesztése Bejelentkezés QR-kóddal - Útvonal Főoldal - Keresés Felfedezés Üzenetek Értesítések - Globális Rövidek - Képek - Edzések Naptárak Naptárlisták Sakk Pénztárca - Egyenleg Küldés Fogadás Tranzakciók - Nincs pénztárca összekapcsolva - A pénztárca használatához állítson be egy Nostr Wallet Connect (NWC) kapcsolatot a zap-beállításokban. - Pénztárca beállítása satoshik Egy BOLT-11 számla beillesztése Fizetés @@ -1934,8 +1659,6 @@ Ezzel eltávolítja a pénztárca-kapcsolatot. Később bármikor újra hozzáadhatja. Pénztárca neve Saját pénztárca - Saját pénztárcák - Pénztárcák kezelése Nincs pénztárca összekapcsolva Kapcsolja össze fiókját egy vagy több NWC-pénztárcával a fizetések küldéséhez és fogadásához. NWC-kapcsolat hozzáadása @@ -1955,12 +1678,9 @@ Mint eltávolítása Mint hozzáadása Előzmények - Pénztárca szerkesztése Nutzap kulcs (speciális) Egy külön privát kulcs, amelyet kizárólag NIP-61 nutzapok fogadására használ a rendszer. Nem azonos a Nostr azonosító kulccsal. Új kulcs előállítása - Érvényteleníti a jelenlegi kulcshoz zárolt összes függőben lévő nutzapot. - Jelenlegi kulcs megtartása P2PK privát kulcs (hex) Mintek szerkesztése Módosítások mentése @@ -1976,7 +1696,6 @@ Népszerű mintek Egyező mintek - Ajánlom ezt a mintet Fogadás LN küldése Token küldése @@ -2057,10 +1776,6 @@ Mentés Átnevezés Pénztárca átnevezése - Szerkesztés - Érvénytelen NWC-kapcsolati cím - Mozgatás felfelé - Mozgatás lefelé Láncon belüli tranzakciók Ehhez a fiókhoz nincs elérhető láncon belüli cím. Nincs beállítva lánc-háttérprogram. @@ -2135,17 +1850,13 @@ Fizetés elküldve (%1$d/%2$d igazolás közzétéve), de a következő igazolást nem sikerült közzétenni Fizetés elküldve (%1$d/%2$dnyugta közzétéve), de a következő nyugtát nem sikerült közzétenni - Biztonsági szűrők Követettek importálása Új bejegyzés Új rövidek: képek vagy videók Új közösségi bejegyzés Új termék - Új hely-exkluzív bejegyzés Új cikk Új szavazás - Új zap-szavazás - Új szabályos szavazás Új kép Új naptáresemény Naptáresemény szerkesztése @@ -2160,8 +1871,6 @@ Nap Közelgő Elmúlt - Még nincsenek közelgő vagy elmúlt események a kiválasztott hírfolyamban. - Még nincsenek naptár-gyüjtemények. A naptár üres Itt jelennek meg a követett személyek által megosztott események. Koppintson a „+” gombra a saját események létrehozásához. Még nincsenek gyüjtemények @@ -2188,8 +1897,6 @@ Következő hét Előző nap Következő nap - Nincsenek események ezen a napon - Nincsenek események Folytatás %1$d. nap / %2$d Hozzáadás az eszköz naptárához @@ -2249,7 +1956,6 @@ A kiválasztott képet nem sikerült feltölteni. Próbálja újra vagy adja meg a kép webcímét. Résztvevők (%1$d) Keresés név, npub vagy nip-05 szerint - Adjon meg egy érvényes npub… vagy 64 karakteres hexadecimális nyilvános kulcsot. Résztvevő eltávolítása Naptár-emlékeztetők Emlékeztetők küldés @@ -2270,10 +1976,7 @@ Esemény részletei Új rövid videó Új hosszú videó - Cím Összefoglalás (nem kötelező) - Borítókép webcíme (nem kötelező) - Cikk írása markdownban… Előnézet Szerkesztés Fejléckép hozzáadása @@ -2357,18 +2060,14 @@ %1$s átjátszó Átjátszólista kibontása Bejegyzésbeállítások - Átjátszólista-választó Szavazás Szavazás kikapcsolása Bitcoin-számla Bitcoin-számla visszavonása - Egy tétel eladásának visszavonása Zap-gyűjtés Zap-gyűjtés visszavonása Helyszín Helyszín eltávolítása - Zap-megosztások - Zap-megosztások visszavonása Tartalmi figyelmeztetés hozzáadása Tartalmi figyelmeztetés eltávolítása Lejárati dátum hozzáadása @@ -2383,11 +2082,8 @@ Érvénytelen cím Az Amethyst kapott egy URI-t a megnyitáshoz, de az érvénytelen volt: %1$s Bejövő átjátszók a privát üzenetekhez - Átjátszók: %1$s - Általános átjátszók használata Bejövő átjátszók beállítása a privát üzenetekhez Ez a beállítás mindenkit tájékoztat arról, hogy Ön melyik átjátszót használja, amikor üzeneteket küldenek Önnek. Ezek nélkül néhány üzenetről lemaradhat. - Jó választási lehetőségek:\n - inbox.nostr.wine (fizetős)\n - auth.nostr1.com (ingyenes)\n - you.nostr1.com (személyes átjátszók - fizetős) Jó választási lehetőségek:\n - auth.nostr1.com (ingyenes)\n - inbox.nostr.wine (fizetős)\n - relay.0xchat.com (ingyenes) Adjon hozzá 1–3 átjátszót, hogy privát postafiókként szolgáljanak. A bejövő privát üzenetek átjátszóinak el kell fogadniuk bármely üzenetet bárkitől, de azok letöltését csak Ön engedélyezheti. Beállítás most @@ -2407,7 +2103,6 @@ Az értesítések fogadásához kifejezetten kialakított átjátszólista létrehozása elengedhetetlen a Nostr élményhez. Adjon meg 1-3 átjátszót, amelyeken keresztül fogadni tudja az értesítéseket. Győződjön meg arról, hogy azok nem igényelnek fizetést vagy bizalmi hálózatot a feladótól, különben csak a fizetősektől vagy a hosszú távú felhasználóktól fog értesítéseket kapni Jó választási lehetőségek:\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social - Feltöltés közvetlen üzenetbe Átjátszóbeállítások Átjátszók átrendezése Nyilvános kimenő és saját átjátszók @@ -2424,12 +2119,8 @@ Azok az átjátszók, ahol az Ön MLS-kulcscsomagjai közzétételre kerülnek (MIP-00). Más felhasználók ezeket a kulcscsomagokat lekérve tudják Önt meghívni a Marmot csoportos beszélgetésekbe. Adjon meg 1-3 olyan átjátszót, amely fogadja az Ön kulcscsomag-eseményeit, és lehetővé teszi azok nyilvános olvasását. Privát saját átjátszók Adjon hozzá 1–3 átjátszót, hogy olyan eseményeket tároljanak, amelyeket senki más nem láthat, például a piszkozatait és/vagy az alkalmazásbeállításait. Ideális esetben ezek az átjátszók vagy helyi szintűek, vagy hitelesítést igényelnek az egyes felhasználói tartalmak letöltése előtt. - Általános átjátszók - Az Amethyst ezeket az átjátszókat a bejegyzések letöltésére használja. Kapcsolódott átjátszók Jelenlegi használatban lévő átjátszók listája - Ajánlott átjátszók - Adja hozzá a következő átjátszókat az általános átjátszók listájához, hogy megkapja a felsorolt felhasználók hozzászólásait. Keresési átjátszók A tartalom vagy felhasználók keresésekor használandó átjátszók listája. A címkézés és a keresés nem fog működni, ha nem áll rendelkezésre semmilyen beállítás. Győződjön meg arról, hogy alkalmazzák a NIP-50-et. Helyi átjátszók @@ -2464,11 +2155,8 @@ Ezt a verziót a következők hozták létre Önnek: %1$s verzió Köszönöm! - Maximális korlát Korlátozott írások Elágaztatva innen: - ELÁGAZTATÁS - Git tároló: %1$s Weboldal: Klónozás: Nyitva @@ -2493,20 +2181,13 @@ Cikk szerkesztése Bejegyzés szerkesztése Javaslat egy bejegyzés javítására - Változások összefoglalása - Gyors javítások… Javaslat elfogadása Videó lejátszása felugró ablakban Letöltés - Feliratozás bekapcsolva - Feliratozás kikapcsolva - Lezárt üzenetek kikapcsolva. Koppintson a lezárt üzenetek bekapcsolásához - Lezárt üzenetek bekapcsolva. Koppintson a lezárt üzenetek kikapcsolásához Küldés Felhasználónév lejátszása hangként Kapcsolatrögzítő (Pushpin) QR-kód beolvasása - Harmadik féltől származó pénztárca-szolgáltató felkeresése: Alby Dátum kiválasztása A piszkozatokra nem lehet válaszolni A piszkozatokat nem lehet idézni @@ -2548,23 +2229,18 @@ 507 – kevés tárhely (WebDAV): A kiszolgáló nem képes a kérést tárolni, mert kevés a tárhely. 508 – végtelen ismétlés (WebDAV): A kiszolgáló végtelen ciklusban ismétlődő kéréseket érzékelt a feldolgozáskor. 511 – hálózati azonosítás: A hálózat használata előtt azonosítani kell magunkat, pl. egy Wi-Fi-hálózat használata előtt el kell fogadni a használati feltételeket. - NIP-96-kiszolgálók - Annyi kiszolgálót adhat hozzá, amennyit csak akar. Később a kép feltöltésekor kiválaszthatja, melyiket szeretné használni Blossom-kiszolgálók Annyi kiszolgálót adhat hozzá, amennyit csak akar. Később a kép feltöltésekor kiválaszthatja, melyiket szeretné használni Egy NIP-96-kiszolgáló hozzáadása Egy Blossom-kiszolgáló hozzáadása Összes törlése Biztosan törölni szeretné az összes piszkozatot? - Köteg: Torrentfájl Letöltés Nem sikerült megnyitni a fájlt A fájl megnyitásához és letöltéséhez nincsenek torrent-alkalmazások telepítve. Az esemény nem tartalmaz elegendő információt a mágneshivatkozás létrehozásához - Saját lista/gyüjtemény Saját listák - Felhasználók Szempont kiválasztása a hírfolyam szűréséhez Hírfolyamok Kulcsszavak @@ -2595,7 +2271,6 @@ Privát üzenet Nyílvános üzenet Csevegési átjátszó - Az átjátszó, amelyhez a csevegés összes felhasználója csatlakozik Kép megosztása… Nem lehetett megosztani a képet, próbálja meg újra később… Videó megosztása… @@ -2642,7 +2317,6 @@ Szeretné elküldeni a legutóbbi összeomlási jelentést az Amethystnek egy közvetlen üzenetben? A személyes adatait nem osztja meg Küldés Ez az üzenet %1$s után eltűnik - Ez az üzenet %1$d nap múlva eltűnik Aláíró kiválasztása Már rajta van a listán Privát tagok @@ -2664,7 +2338,6 @@ Csomagnév Új csomagnév Csomagleírás - Új csomagleírás Közvetítési lista Közvetítési csomag Lista törlése @@ -2678,13 +2351,9 @@ Összecsukás Kibontás Sikertelen újrapróbálkozás (%1$d) - több mint %1$d közvetítés - " (%1$d folyamatban)" - %1$d/%2$d továbbító Időtúllépés Újrapróbálkozás… Újrapróbálkozás - Megtekintés Eltüntetés %1$d/%2$d Közvetítés @@ -2710,7 +2379,6 @@ Újraindítás Elfogadás Elutasítás - Új játék Új sakkjáték Játék betöltése\u2026 Nem található játék @@ -2865,23 +2533,13 @@ Importálandó profil keresés, npub1…, aliz@pelda.hu Támogatja az npub, nprofile, NIP-05, hex és Namecoin (.bit) formátumokat - Követési lista keresése Borravaló %1$d felhasználói fiók megtalálva %1$d kiválasztva - Feloldva a Namecoinon keresztül - Most %1$d fiókot követ - A hírfolyam elkészült. - Kihagyás - Másik keresése %1$d felhasználói fiók követése - Továbbiak importálása - Folytatás Kihagyás csak most - %1$s feloldása… Követési lista lekérdezése… Nem találhatók követések - %1$d felhasználói fiók követése… "Írja be egy barátja vagy közösségi vezető profilját. Használhatja az npub, NIP-05 címüket, vagy egy Namecoin nevet, például aliz@pelda.bit vagy id/aliz a blokklánc által ellenőrzött azonosítókhoz." Összes kijelölése Üzemidő: %1$d%% @@ -2889,7 +2547,6 @@ Kapcsolat tesztelése Kiszolgálók tesztelése… Kapcsolódva - Sikertelen Teszteredmények Diagnosztika Utoljára tesztelve @@ -2902,9 +2559,6 @@ Elfogadás Elutasítás Átjátszószinkronizálás - Átjátszószinkronizálás - Tegye közzé újra az eseményeit az összes ismert átjátszón, hogy a kimenő, beérkező és privát üzenetek átjátszói mindig naprakészek legyenek. Wi-Fi-kapcsolat szükséges – ez jelentős adatforgalmat eredményezhet. - Átjátszószinkronizálás megnyitása… Hogyan működik Ez az eszköz átvizsgálja az alkalmazás által eddig észlelt összes átjátszót, és az eseményeket a megfelelő célállomásokra továbbítja: Töltse le az összes létrehozott eseményt, és küldje el őket a kimenő üzenetek átjátszóinak. @@ -2914,14 +2568,9 @@ Mobiladat-forgalom használata? Szinkronizálás indítása Indítás mindenképpen (mobiladat-forgalom) - Szüneteltetés - Folytatás - Újrakezdés Mégse Átjátszók: %1$d / %2$d Újraelosztott események: %1$d új / %2$d elküldött és %3$d fogadott - Szinkronizálás szüneteltetve - %2$d átjátszóból %1$d teljesítve — %3$d esemény újraelosztása eddig. A folytatáshoz koppintson a folytatás gombra. Szinkronizálás kész %1$d esemény továbbítva a célátjátszóknak a fogadott %2$d eseményből. A célátjátszó által %1$d esemény újként elfogadva. @@ -2936,16 +2585,13 @@ elküldve: %1$s fogadott: %1$s új: %1$s - nincsenek események Bitcoin felfedező (OTS) - események Öntől származó események Önnek szóló események kereshető események Közvetlen üzenetek profilok kimenő átjátszók listája - átjátszóbeállítások Utoljára %1$s ezelőtt látták Utoljára elérhető: %1$s (%2$s ezelőtt) Utoljára elérhető: épp most @@ -3020,7 +2666,6 @@ Eszközök keresése a Wi-Fi hálózaton… HLS-feltöltés - Többféle felbontású HLS- videó közzététele a médiakiszolgálókon Videó kiválasztása A videó több felbontásba lesz átkódolva, így a nézők bármilyen internet-kapcsolaton zökkenőmentes lejátszást kapnak. Módosítás @@ -3035,10 +2680,6 @@ A H.265 nem érhető el ezen az eszközön – visszaállás H.264-re. Felbontás-változatok Forrás felbontása: %1$d×%2$d - Létrehozásra kerül: %1$s - (%1$s kihagyva – forrás feletti) - %1$d kbps - forrás feletti – ki lesz hagyva HD-videó közzététele „%1$s” közzététele… %1$s átkódolása @@ -3050,7 +2691,6 @@ Videó közzétéve A HD-videó élesedett a Nostr-on. Valami hiba történt - Bejegyzés megtekintése Kész Próbálja újra Csomagműveletek @@ -3065,30 +2705,21 @@ Tanúsítás Érvényes Érvénytelen - Elfogadva - Elutasítva Ellenőrzés - Ellenőrizve Visszavonva Érvényes ekkortól: %1$s Érvényes eddig: %1$s Tanúsításkérés - Tanúsításkérés egy eseményhez Tanúsító ajánlása Javasolt az alábbi típusokhoz: Tanúsítói jártasság - Jártas a következő típusok igazolásában: %1$s - Tanúsítás ehhez: Tanúsítás kérése ehhez: Időszak Ekkortól Eddig Most Összes - Utoljára szinkronizálva: %1$s - Utolsó szinkronizálás óta Webes könyvjelzők - Még nincsenek webes könyvjelzők. Koppintson a „+” gombra a hozzáadáshoz. Webes könyvjelző hozzáadása Webes könyvjelző szerkesztése Webcím @@ -3145,13 +2776,10 @@ https://pelda.hu/kep.jpg Weboldal webcíme (nem kötelező) https://pelda.hu - Határidő (nem kötelező) Határidő beállítása Új cél - Cél létrehozása Törlési kérés Kérés az átjátszóknak, hogy a kiválasztott dátumig visszamenőleg véglegesen töröljék az Ön összes adatát. Ez a művelet a NIP-62 szabványon alapul, és egyes joghatóságokban jogilag kötelező érvényű. - Egy átjátszó kiválasztása Célátjátszók Összes átjátszó Ezzel az ÖSSZES átjátszót arra kéri, hogy a kiválasztott dátumig töröljön mindent, ami az Ön kulcsához kapcsolódik. Ezt az eseményt a lehető legszélesebb körben közzétesszük. Ez a művelet nem vonható vissza. @@ -3167,7 +2795,6 @@ Dátum kiválasztása Idő kiválasztása Törlési előzmények - Frissítés Ezek az Ön korábbi, a kapcsolódott átjátszókon talált törlési kérései. Az ezekben az eseményekben megjelölt átjátszók nem tárolhatják az Ön adatait az esemény dátuma előtti időszakból. Nem találhatók törlési kérések Ön még nem küldött törlési kérést. @@ -3210,7 +2837,6 @@ Esemény letiltása Típus engedélyezése IP-cím letiltása - Nyilvános kulcs (hex) Eseményazonosító (hex) Típus száma IP-cím @@ -3221,7 +2847,6 @@ Átjátszó neve Átjátszó leírása Átjátszó ikonjának webcíme - Átjátszó kezelése Kezelés Tagok A(z) %1$s tagjai @@ -3292,7 +2917,6 @@ Emodzsicsomag-műveletek Saját emodzsicsomagok Emodzsik - Emodzsicsomagok böngészése Privát Privát emodzsi A nyilvános emodzsik mindenki számára láthatók, és megjelennek a reakciómenüben, valamint a „:” automatikus kiegészítő listájában, ha ez a csomag szerepel az emodzsilistában. @@ -3317,4 +2941,86 @@ Nowhere drop Nowhere alkotás Nowhere fórum + + Marmot csoportok + Csoport létrehozása + Marmot csoport létrehozása + Egy új MLS-csoport jön létre. A tagokat később adhatja hozzá. + Marmot csoport + %1$s csoport… + %1$s… + Ismert + Ismert (%1$d) + Új kérések + Új kérések (%1$d) + Még nincsenek csoportok + Hozzon létre egy csoportot, vagy fogadjon el egy meghívást. + Nincsenek meghívók + Amikor valaki hozzáadja Önt egy csoporthoz, az itt fog megjelenni, amíg válaszol. + Még nincsenek üzenetek + + %1$d üzenet + %1$d üzenet + + + %1$d tag + %1$d tag + + Csoport neve + Adja meg a csoport nevét + Adja meg a csoport leírását (nem kötelező) + A változtatások az MLS-en keresztül kerülnek érvényesítésre a csoportban, és továbbítódnak minden tag felé. + Csoportadatok frissítve + Nem sikerült frissíteni: %1$s + Nem sikerült létrehozni a csoportot: %1$s + A KeyPackage átjátszók nincsenek beállítva + Még nincs KeyPackage átjátszólistája (MIP-00). Ez a lista tájékoztatja a többi felhasználót arról, hol érhető el a KeyPackage-e, így meg tudják hívni csoportos beszélgetésekbe.\n\nSzeretné ehhez a jelenlegi kimenő átjátszóit használni? + Kimenő átjátszók használata + Kihagyás + Csoportadatok + Csoportadatok szerkesztése + Csoport elhagyása + ez a csoport + Biztos benne, hogy elhagyja a(z) „%1$s” nevű csoportot? A továbbiakban nem fog üzeneteket kapni ebből a csoportból. + Nem sikerült elhagyni a csoportot: %1$s + %1$s hozzáadása… + Nem sikerült hozzáadni a következőt: %1$s: %2$s + ismeretlen hiba + A hozzáadáshoz közzé kell tennie egy KeyPackage-et (kind:30443). + Hozzáadás a csoporthoz + Tag hozzáadása + Tag hozzáadása + Név, npub vagy NIP-05 + (Ön) + - adminisztrátor + Tag eltávolítva + Nem sikerült eltávolítani a tagot: %1$s + Tag eltávolítása + Biztos benne, hogy el szeretné távolítani a(z) „%1$s” nevű felhasználót ebből a csoportból? + Megadás + Adminisztrátori jogosultságok megadása + Adminisztrátori jogosultságok megadása + Adminisztrátorrá teszi a(z) „%1$s” nevű felhasználót ebben a csoportban? Az adminisztrátorok hozzáadhatnak vagy eltávolíthatnak tagokat, módosíthatják a csoport adatait, és adminisztrátori jogosultságokat adhatnak más tagoknak. + Adminisztrátori jogosultságok megadva + Nem sikerült megadni az adminisztrátori jogosultságot: %1$s + Visszavonás + Adminisztrátori jogosultságok visszavonása + Adminisztrátori jogosultságok visszavonása + Visszavonja a(z) „%1$s” nevű felhasználó adminisztrátori jogosultságait? Továbbra is a csoport tagja marad. + Adminisztrátori jogosultságok visszavonva + Nem sikerült visszavonni az administrátori jogosultságot: %1$s + Átjátszók + még nincsenek események + legutóbbi esemény: %1$s + Nem tagja ennek a csoportnak + Másolás + Visszaállítás automatikus választásra + Explorer API alap webcím + Számla kiegyenlítése a DVM-től + %1$s satoshi kifizetése a DVM-nek + A kedvezményezett lightning-szolgáltatása ennél: %1$s nem érhető el. A(z) „%2$s” lightning-cím lett kiszámítva. Hiba: %3$s. Ellenőrizze, hogy a kiszolgáló működik-e, és hogy a lightning-cím helyes-e + Nem sikerült megoldani a következőt: %1$s. Ellenőrizze, hogy kapcsolódik-e, vagy működik-e a kiszolgáló, és hogy a(z) %2$s lightning-cím helyes-e.\n\nKivéve: %3$s + Hiba történt a JSON elemzésekor a(z) %1$s számlahívásából. Ellenőrizze a felhasználó lightning-beállításait + Nem lehetett lightning-számlát létrehozni. Üzenet a következőtől: %1$s: %2$s + Nem sikerült Lightning-számlát létrehozni a következőből: %1$s: A „PR” elem nem található a kapott JSON-ban. diff --git a/amethyst/src/main/res/values-hu/strings.xml b/amethyst/src/main/res/values-hu/strings.xml index 3248c74f87..5caafbf4a5 100644 --- a/amethyst/src/main/res/values-hu/strings.xml +++ b/amethyst/src/main/res/values-hu/strings.xml @@ -21,8 +21,6 @@ Illegális viselkedés Egyéb Zaklatás - Ismeretlen - Átjátszóikon Ismeretlen szerző Szöveg másolása Szerző azonosítójának másolása @@ -36,12 +34,9 @@ Kéretlen tartalom vagy csalás bejelentése Profilutánzás bejelentése - Szókimondó tartalom bejelentése Illegális viselkedés bejelentése Malware bejelentése - Mod bejelentése Malware - Mod Ön nyilvános kulcsot használ, és a nyilvános kulccsal csak olvashatóak a bejegyzések. Jelentkezzen be a privát kulcsával, hogy válaszolni tudjon Ön nyilvános kulcsot használ, és a nyilvános kulccsal csak olvashatóak a bejegyzések. Jelentkezzen be a privát kulcsával, hogy meg tudja tolni a bejegyzéseket Ön nyilvános kulcsot használ, és a nyilvános kulcsok csak olvashatóak. Jelentkezzen be a privát kulccsal a hozzászólások kedveléséhez @@ -52,7 +47,6 @@ Ön nyilvános kulcsot használ, és a nyilvános kulccsal csak olvashatóak a bejegyzések. Jelentkezzen be a privát kulcsával, hogy egy szót vagy mondat el tudjon rejteni Ön nyilvános kulcsot használ, és a nyilvános kulccsal csak olvashatóak a bejegyzések. Jelentkezzen be a privát kulcsával, hogy egy szót vagy mondat meg tudjon jeleníteni Zap - Megtekintések száma Megtolás megtolta szerkesztve @@ -65,9 +59,7 @@ Hozzáadás "válasz erre: " " és " - "csatornában " Profilplakát - Sikeres fizetés Hiba a hibaüzenet elemzésekor " Követett" " Követő" @@ -89,9 +81,7 @@ Látható előtag 😎 Hozzáadás a bejegyzéshez - "Hiba a következő előnézet elemzésekor %1$s : %2$s" "Kártyakép előnézete a következőhöz: %1$s" - Új csatorna Csatornanév A nagyszerű csoportom Kép webcíme @@ -102,33 +92,18 @@ Mentés Létrehozás Mégse - Nem sikerült feltölteni a képet - Az átjátszó címe - Bejegyzések - Bájt Hibák - Ebben a munkamenetben lévő kapcsolati hibák száma - Fő hírfolyam - Privát üzenet-hírfolyam - Nyilvános üzenet-hírfolyam - Globális hírfolyam - Keresési hírfolyam Egy átjátszó hozzáadása - Név Megjelenítendő név Saját megjelenítendő név Strucc McNagyszerű Üdvözöljük! Felhasználónév - Saját felhasználónév Névjegy Profilkép webcíme Profilplakát webcíme Weboldal webcíme Megszólítás - LN-cím - LN-webcím (elavult) - Mentés a galériába Kép elmentve a képgalériába A videó letöltése megkezdődött… A média letöltése megkezdődött… @@ -136,11 +111,8 @@ Videó elmentve a videógalériába Nem sikerült elmenteni a videót Kép feltöltése - Feltöltés… A felhasználó nem rendelkezik a satoshik fogadásához beállított lightning-címmel "Válasz írása… " - A bejegyzés azonosítóját a vágólapra másolja a Nostr-ban való megosztáshoz - Csatorna-azonosító (bejegyzés) másolása a vágólapra Szerkeszti a csatorna metaadatait Csatlakozás Ismert @@ -152,18 +124,14 @@ Válaszok Az Öné Galéria - "Követett" "Bejelentés" További beállítások " Átjátszó" Weboldal Lightning-cím Az Nsec azonosítót (az Ön „jelszavát”) a vágólapra másolja biztonsági mentés céljából - Titkos kulcs másolása a vágólapra Privát kulcs megjelenítése QR-kódként Jelszóval védett privát kulcs megjelenítése QR-kódként - Nyilvános kulcs másolása a vágólapra a megosztáshoz - Nyilvános kulcs (NPub) másolása a vágólapra Közvetlen üzenet küldése Felhasználó metaadatainak szerkesztése Követés @@ -192,8 +160,6 @@ Hogyan szólíthatjuk Önt? Még nincs Nostr-fiókja? Már van Nostr-fiókja? - Új fiók létrehozása - Új kulcs előállítása Hírfolyam betöltése… Fiók betöltése… "Hiba a válaszok betöltésekor: " @@ -201,12 +167,6 @@ Még nincsenek értesítések. A hírfolyam üres. Frissítés - létrehozva - a következő leírásával: - és kép - megváltoztatta a csevegés nevét erre: - leírását erre: - és a képet erre: Elhagyás Követés megszüntetése Csatorna létrehozva @@ -239,7 +199,6 @@ Trágárság / Gyűlöletbeszéd Gyűlöletbeszéd bejelentése Meztelenség / Pornó bejelentése - egyéb Az összes ismert megjelölése olvasottként Az összes új üzenet megjelölése olvasottként Összes megjelölése olvasottként @@ -260,23 +219,18 @@ Nem sikerült hitelesíteni A biometrika nem tudta hitelesíteni a telefon tulajdonosát A biometrika nem tudta hitelesíteni a telefon tulajdonosát. Hiba: %1$s - Hiba - "Létrehozta: %1$s" "Kitűző %1$s számára" Ön egy új kitűzőt kapott Kitűzőben részesült Bejegyzés szövege a vágólapra másolva A szerző @npub-ja a vágólapra másolva A bejegyzés-azonosító (@note1) a vágólapra másolva - Szöveg kijelölése "<Nem sikerült a privát üzenetet visszafejteni>\n\nÖnt megemlítették egy privát/titkosított beszélgetésben %1$s és %2$s között." Új fiók hozzáadása Fiókok Fiók kiválasztása Új fiók hozzáadása Aktív fiók - Privát kulcsot tartalmaz - Csak olvasás, nem privát kulcs Vissza Kiválasztás Böngésző-hivatkozás megosztása @@ -294,14 +248,12 @@ Törlés Letiltás Bejelentés - Törlés Ne jelenítse meg újra Kéretlen tartalom vagy átverés Trágárság vagy gyűlöletkeltő magatartás Rosszindulatú profilutánzás Meztelenség vagy pornográf tartalom Illegális viselkedés - Malware A felhasználó letiltásával elrejti annak bejegyzéseit az alkalmazásban. Az Ön bejegyzései továbbra is nyilvánosan megtekinthetők azok számára is, akiket Ön letiltott. A letiltott felhasználók a „Biztonsági szűrők” lapon jelennek meg. Visszaélés bejelentése @@ -321,30 +273,15 @@ Hozzáadás a nyilvános könyvjelzőkhöz Törlés a privát könyvjelzőkből Törlés a nyilvános könyvjelzőkből - Wallet Connect szolgáltatás - Hitelesíti, hogy a Nostr Secret az alkalmazásból való kilépés nélkül fizessen a Zap-et. Tartsa biztonságban a titkot, és lehetőség szerint használjon privát átjátszót - Wallet Connect nyilvános kulcs - Wallet Connect átjátszó - Wallet Connect titok - Titkos kulcs megjelenítése - nsec / hex privát kulcs Hozzájárulás összege satoshiban - Szavazás közzététele - Kötelező mezők: - Zap-kedvezményezettek - Szavazás elsődleges leírása… %s. válaszlehetőség Válaszlehetőség leírása - Nem kötelező mezők: Minimum Zap Maximum Zap Együttműködés (0–100)% - Szavazás lezárása - nap Nem lehet szavazni A szavazásra már nem lehet új szavazato(ka)t leadni - Zap-összeg Az ilyen típusú szavazásokon felhasználónként csak egy szavazat engedélyezett "%1$s esemény keresése" Nyilvános üzenet hozzáadása @@ -378,12 +315,9 @@ Nostr-ban nyoma sincs, csak a Lightning-ban Fájlkiszolgáló Válasszon ki egy kiszolgálót a fájl feltöltéséhez neki: - Ln-cím vagy @Felhasználó Médiakiszolgálók Állítsa be a kívánt médiafeltöltő-kiszolgálókat. - Nincsenek beállítva NIP-96 kiszolgálók. Használhatja az Amethyst listáját, vagy hozzáadhat egyet az alábbiakból ↓ Nincsenek Blossom-kiszolgálók beállítva. Használhatja az Amethyst listáját, vagy hozzáadhat egyet az alábbiakból ↓ - Beépített médiakiszolgálók Az Amethyst alapértelmezett listája. Hozzáadhatja őket egyenként, vagy hozzáadhatja a listát. Alapértelmezett lista használata Médiakiszolgáló hozzáadása @@ -396,31 +330,16 @@ Hash-selés… Kész Hiba - Saját átjátszók (NIP-95) - A fájlokat a kiszolgálók tárolják. Új NIP: ellenőrizze, hogy támogatják-e Adatvédelmi beállítások - Tor és Orbot beállítása - Kapcsolódás az Orbot beállításain keresztül Beállítás Tor beállítások - Kapcsolat bontása az Orbottal / Torral? - Az Ön adatai azonnal átkerülnek a normál hálózatra Igen Nem - Követési lista Követettek bejegyzései Közelben lévők bejegyzései Globális Némítottak bejegyzései Alapértelmezett port: 9050 - ## Kapcsolódás a TORon keresztül az Orbot segítségével - \n\n1. Telepítse az [Orbotot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Indítsa el az Orbotot - \n3. Ellenőrizze az Orbotban a Socks-portokat. Az alapbeállítás: 9050 - \n4. Ha szükséges az Orbotban változtassa meg a portot - \n5. Ezen a felületen állítsa be a Socks-portot - \n6. Kattintson az „Aktiválás” gombra, hogy az Orbotot proxyként használja - Orbot Socks-portja Aktív Tor-motor Használja a beépített verziót vagy az Orbotot @@ -462,8 +381,6 @@ IP-cím elrejtése az összes kapcsolatnál Készítsen sajátot Érvénytelen portszám - Orbot használata - Kapcsolat bontása a Torral / Orbottal Privát üzenetek Értesítés, ha privát üzenet érkezik Zap-et kapott @@ -472,20 +389,9 @@ Tőle: %1$s neki: %1$s Értesítés: - Csatlakozás a beszélgetéshez - Felhasználó- vagy csoport-azonosító - npub, nevent vagy hex - Létrehozás - Csatlakozás Ma Tartalomra vonatkozó figyelmeztetés Ez a bejegyzés érzékeny tartalmat tartalmaz, amelyet egyesek sértőnek vagy zavarónak találhatnak - Az érzékeny tartalmat mindig rejtse el - Az érzékeny tartalmat mindig jelenítse meg - A tartalomra vonatkozó figyelmeztetéseket mindig jelenítse meg - Ajánlott alkalmazások: - Az idegenektől érkező kéretlen tartalmak szűrése - Figyelmeztessen amikor a bejegyzések jelentve vannak azok által akiket követek Új reakció-szimbólum A felhasználó számára nincsenek előre kiválasztott reakciótípusok. Hosszan nyomja meg a szív gombot a módosításhoz Zap-gyűjtés @@ -496,37 +402,24 @@ Írás az átjátszóra Az átjátszónak küldött bájt-mennyiség, beleértve a szűrőket és eseményeket is Az átjátszótól kapott bájt-mennyiség, beleértve a szűrőket és eseményeket is - Hiba lépett fel, amikor megpróbálta lekérni az átjátszó-információt innen: %1$s Tulajdonos Verzió Szoftver Kapcsolat Támogatott NIP-ek - Csatlakozási díj Fizetési webcím Korlátozások Országok Nyelvek - Címkék Közzétételi szabályzat Hibák és megjegyzések ettől az átjátszótól - Üzenethossz - Előfizetések - Szűrők - Előfizetés azonosítójának hossza Minimális előtag Maximális eseménycímkék - Tartalomhossz Minimális PoW - Hitelesítés - Fizetés Cashu token Beváltás - Küldés ide: Zap Wallet - Megnyitás a Cashu pénztárcában Token másolása Nincs beállítva Lightning-cím - Token a vágólapra másolva ÉLŐ OFFLINE VÉGET ÉRT @@ -546,7 +439,6 @@ Alkalmazás-beállítások Beállítások Mindig - Csak Wi-Fi-n Korlátlan Wi-Fi Soha Teljes @@ -570,7 +462,6 @@ Bejegyzés stílusának kiválasztása Profilgaléria stílusa Válassza ki a galéria stílusát - Kép betöltése Spamelők Némítva. Koppintson a némitás megszüntetéséhez Hang bekapcsolva. Koppintson a némításhoz @@ -578,12 +469,8 @@ Nostr-cím hitelesítve lett Nostr-cím hitelesítése sikeretelen Nostr-cím ellenőrzése - Összes kijelölése / elvetése Alapértelmezett Visszaállítás alapértelmezettre - A folytatáshoz válasszon ki egy átjátszót - Zap-ek továbbítása neki: - A funkciót támogató kliensek a Zap-eket az alábbi LN-címre vagy felhasználói profilra továbbítják az Öné helyett A helyszín megjelenítése mint Hozzáadja a helyének geohash-sét a bejegyzéséhez. A nyilvánosság tudni fogja, hogy a jelenlegi helytől 5 km-en (3 mi) belül tertózkodik Helyszín-alapú bejegyzés @@ -591,9 +478,6 @@ Helyszín betöltése… A helyszín-meghatározás nincs engedélyezve Hozzáadja az érzékeny tartalomra vonatkozó figyelmeztetést a tartalom megjelenítése előtt. Ez ideális bármilyen NSFW tartalom vagy olyan tartalom esetén, amelyet egyesek sértőnek vagy zavarónak találhatnak - Új funkció - Ennek az üzemmódnak az aktiválásához az Amethystnek NIP-17 üzenetet kell küldenie (GiftWrapped, Sealed Direct és csoport-üzenetek). A NIP-17 új, és a legtöbb kliens még nem implementálta. Győződjön meg arról is, hogy a kedvezményezett kompatibilis klienst használ. - Aktiválás Nyílvános Új nyilvános vagy privát csoport Privát @@ -610,7 +494,6 @@ Képek és GIF-ek automatikus betöltése Videók és GIF-ek automatikus lejátszása Webcím-előnézetek megjelenítése - Mikor töltse be a képeket Köteg másolása Másolás a vágólapra Npub másolása a vágólapra @@ -621,45 +504,23 @@ Média hozzáadva Média hozzáadva az Ön profil-galériájába Létrehozva ekkor: - Szabályok Bejelentkezés Amberrel Állapot frissítése - Hiba a hibaüzenet elemzésekor A szavazatok egy Zap összeggel vannak súlyozva. Beállíthat egy minimális összeget, hogy elkerülje a spamelőket, és egy maximális összeget, hogy elkerülje, hogy a nagy Zap-elők átvegyék a szavazást. Használja ugyanazt az összeget mindkét mezőben, hogy minden szavazatot ugyanannyira értékeljen. Hagyja üresen, hogy bármilyen összeget elfogadjon. Nem sikerült Zap-et küldeni Üzenet a felhasználónak Üzenet: %1$s OK - Nem sikerült elérni a következőt: %1$s: %2$s - Nem sikerült összeállítani a NIP-11 webcímet a következőhöz: %1$s: %2$s - Nem sikerült elérni a következőt: %1$s: %2$s - Nem sikerült a válasz elemzése a következőtől: %1$s: %2$s - Az átjátszó elutasította a következő kérést: %1$s: %2$s - Nem sikerült elérni a következőt: %1$s: %2$s - Nem sikerült az eredmény elemzése a következőtől: %1$s: %2$s - A(z) %1$s sikertelen a következő kóddal %2$s - Aktív: - Főoldal - Privát üzenetek - Csevegések - Globális - Keresés Zap-ek megosztása és továbbítása A funkciót támogató kliensek megosztják és továbbítják a Zap-eket az itt hozzáadott felhasználóknak az Ön felhasználói helyett Felhasználó keresése és hozzáadása Felhasználónév vagy megjelenítendő név Hiányzó lightning-beállítás A(z) %1$s nevű felhasználó nem rendelkezik a satoshik fogadására beállított lightning-címmel - Százalék - 25 - A Zap-ek megosztása vele: - Zap-ek továbbítása ide: - Nem található lightning-pénztárca Fizetve Pénztárca: %1$s Hiba az aláíró-alkalmazás megnyitásakor Az aláíró alkalmazás nem található. Ellenőrizze, hogy az alkalmazás nincs-e eltávolítva - Aláíró-alkalmazás elutasítva Győződjön meg arról, hogy ezt a tranzakciót az aláíró-alkalmazás hitelesítette-e Nem található pénztárca a Lighning-számla kifizetéséhez (Hiba: %1$s). A Zap-ek használatához telepítsen egy Lightning-pénztárcát Nem található pénztárca a Lighning-számla kifizetéséhez. A Zap-ek használatához telepítsen egy Lightning-pénztárcát @@ -670,36 +531,19 @@ Válasszon egy lehetőséget Sikertelen számla-kifizetés Sikertelen pénzkivétel a pénztárcából - Nem sikerült beállítani a Wallet Connectet - Hiba a NIP-47 kapcsolati karakterlánc elemzésekor. Ellenőrizze, hogy a pénztárca-szolgáltatónál a következő helyes-e: %1$s. Hiba: %2$s - Hiba a NIP-47 kapcsolati karakterlánc elemzésekor. Ellenőrizze, hogy a pénztárca-szolgáltatónál a következő helyes-e: %1$s. Nem sikerült a Cashut beváltani A pénzverde a következő hibaüzenetet küldte:%1$s - A Cashu tokeneket már elköltötték. Cashu megkapva %1$s satoshi érkezett a pénztárcájába. (Költség: %2$s satoshi) A rendszeren nem található kompatibilis Cashu pénztárca Nem sikerült a számlát a kedvezményezett kiszolgálóiról lekérni A Wallet Connect szolgáltatója a következő hibával tért vissza: %1$s - Nem sikerült a Tor hálózathoz kapcsolódni - Nem érhető el az átjátszó-dokumentum Nem sikerült az LN-webcímet a(z) „%1$s” Lightning-címről összeállítani. Ellenőrizze a felhasználó beállításait - A kedvezményezett lightning-szolgáltatása ennél: %1$s nem érhető el. A(z) „%2$s” lightning-cím lett kiszámítva. Hiba: %3$s. Ellenőrizze, hogy a kiszolgáló működik-e, és hogy a lightning-cím helyes-e - Nem sikerült megoldani a következőt: %1$s. Ellenőrizze, hogy kapcsolódik-e, vagy működik-e a kiszolgáló, és hogy a(z) %2$s lightning-cím helyes-e - Nem sikerült megoldani a következőt: %1$s. Ellenőrizze, hogy kapcsolódik-e, vagy működik-e a kiszolgáló, és hogy a(z) %2$s lightning-cím helyes-e.\n\nKivéve: %3$s - Nem sikerült lekérni a számlát a következőtől: %1$s Nem sikerült lekérni a számlát a következőtől: %1$s: %2$s - Hiba a Lightning-címből származó JSON elemzésekor. Ellenőrizze a felhasználó Lightning-beállítását Hiba történt a(z) %1$s JSON elemzésekor. Ellenőrizze a felhasználó Lightning-beállítását - A visszahívási webcím nem található a felhasználó lightning-cím-kiszolgálójának konfigurációjában Nem található a visszahívási webcím a(z) %1$s válaszából - Hiba történt a JSON elemzésekor a Lightning-cím számlahívásából. Ellenőrizze a felhasználó lightning-beállításait - Hiba történt a JSON elemzésekor a(z) %1$s számlahívásából. Ellenőrizze a felhasználó lightning-beállításait Helytelen (%1$s satoshi) számlaösszeg a következőtől: %2$s. A következőnek kellett volna lennie: %3$s Nem sikerült a Zap-összeg elküldése előtt lightning-számlát készíteni. A címzett lightning-pénztárcája a következő hibát küldte: %1$s - Nem lehetett lightning-számlát létrehozni. Üzenet a következőtől: %1$s: %2$s - Nem sikerült Lightning-számlát létrehozni a Zap elküldése előtt. A „PR” elem nem található a kapott JSON-ban. - Nem sikerült Lightning-számlát létrehozni a következőből: %1$s: A „PR” elem nem található a kapott JSON-ban. Csak olvasható felhasználó Nincs reakcióbeállítás UnifiedPush-alkalmazás kiválasztása @@ -717,13 +561,11 @@ Üzenet küldése az eladónak Tisztelt %1$s! Ez még aktuális? Tisztelt hölgyem / uram! Ez még aktuális? - Egy tétel eladása Cím iPhone 13 Állapot Kategória Ár (satoshiban) - 1000 Helyszín Város, állam, ország Új @@ -752,20 +594,13 @@ Egyéb Nem sikerült feltölteni a médiát Nem sikerült megnyitni a tömörített fájlt - Hiba a média tömörítésekor: %1$s Feltöltési hiba: %1$s A kiszolgáló a feltöltés után nem szolgáltatott webcímet Nem sikerült letölteni a kiszolgálóról az oda feltöltött médiát Nem lehetett ellenőrizni a letöltött fájlt a feltöltés után: %1$s - Nem sikerült előkészíteni feltöltésre a helyi fájlt: %1$s Nem sikerült feltölteni a következőre: %1$s: %2$s - Nem sikerült feltölteni: %1$s Nem sikerült törölni: %1$s Média túl nagy a NIP-95 számára - Nem sikerült betölteni a bélyegképet - Nem sikerült előkészíteni a fejlécadatokat: %1$s - Tömörítés visszavonva - A tömörítés nem tudott visszaadni egy fájlt Média minősége Válassza az alacsony minőséget a média kisebb, de kevésbé jó minőségű fájlba tömörítéséhez, a magas minőséget a nagyobb, de jobb minőségű fájlba tömörítéshez, vagy a tömörítetlen fájlt a tömörítés nélküli feltöltéshez. Alacsony @@ -774,15 +609,11 @@ Tömörítetlen Piszkozat szerkesztése Bejelentkezés QR-kóddal - Útvonal Főoldal - Keresés Felfedezés Üzenetek Értesítések - Globális Rövidek - Biztonsági szűrők Új bejegyzés Új rövidek: képek vagy videók Új közösségi bejegyzés @@ -797,29 +628,22 @@ %1$s átjátszó Átjátszólista kibontása Bejegyzés-beállítások - Átjátszólista-választó Szavazás Szavazás kikapcsolása Bitcoin-számla Bitcoin-számla visszavonása - Egy tétel eladásának visszavonása Zap-gyűjtés Zap-gyűjtés visszavonása Helyszín Helyszín eltávolítása - Zap-megosztások - Zap-megosztások visszavonása Tartalmi figyelmeztetés hozzáadása Tartalmi figyelmeztetés eltávolítása Az npub-kulcs megjelenítése QR-kódként Érvénytelen cím Az Amethyst kapott egy URI-t a megnyitáshoz, de az érvénytelen volt: %1$s Bejövő átjátszók a privát üzenetekhez - Átjátszók: %1$s - Általános átjátszók használata Bejövő átjátszók beállítása a privát üzenetekhez Ez a beállítás mindenkit tájékoztat arról, hogy Ön melyik átjátszót használja, amikor üzeneteket küldenek Önnek. Ezek nélkül néhány üzenetről lemaradhat. - Jó választási lehetőségek:\n - inbox.nostr.wine (fizetős)\n - auth.nostr1.com (ingyenes)\n - you.nostr1.com (személyes átjátszók - fizetős) Jó választási lehetőségek:\n - auth.nostr1.com (ingyenes)\n - inbox.nostr.wine (fizetős)\n - relay.0xchat.com (ingyenes) Adjon hozzá 1–3 átjátszót, hogy privát postafiókként szolgáljanak. A bejövő privát üzenetek átjátszóinak el kell fogadniuk bármely üzenetet bárkitől, de azok letöltését csak Ön engedélyezheti. Beállítás most @@ -828,7 +652,6 @@ A kifejezetten a kereséshez és a felhasználói címkézéshez tervezett átjátszólista létrehozása javítani fogja ezeket az eredményeket. Adjon hozzá 1–3 átjátszót a tartalom kereséshez vagy a felhasználók címkézéséhez. Győződjön meg arról, hogy a kiválasztott átjátszók alkalmazzák a NIP-50-et Jó választási lehetőségek:\n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com - Feltöltés közvetlen üzenetbe Átjátszó-beállítások Nyilvános kimenő és saját átjátszók Ez az átjátszótípus tárolja az összes tartalmat. Az Amethyst ide küldi az Ön bejegyzéseit, és mások ezeket az átjátszókat fogják használni, hogy megtalálják az Ön tartalmát. Adjon hozzá 1–3 átjátszót. Ezek lehetnek személyes-, fizetett- vagy nyilvános átjátszók. @@ -838,10 +661,6 @@ Adjon hozzá 1–3 átjátszót, hogy privát postafiókként szolgáljon. Mások ezeket az átjátszókat használják, hogy Önnek privát üzeneteket küldjenek. A bejövő privát üzenetek átjátszóinak bárkitől el kell fogadniuk minden üzenetet, de azok letöltését csak Ön engedélyezheti. Jó választási lehetőségek:\n - inbox.nostr.wine (fizetős)\n - auth.nostr1.com (ingyenes)\n - you.nostr1.com (személyes átjátszók - fizetős) Privát saját átjátszók Adjon hozzá 1–3 átjátszót, hogy olyan eseményeket tároljanak, amelyeket senki más nem láthat, például a piszkozatait és/vagy az alkalmazásbeállításait. Ideális esetben ezek az átjátszók vagy helyi szintűek, vagy hitelesítést igényelnek az egyes felhasználói tartalmak letöltése előtt. - Általános átjátszók - Az Amethyst ezeket az átjátszókat a bejegyzések letöltésére használja. - Ajánlott átjátszók - Adja hozzá a következő átjátszókat az általános átjátszók listájához, hogy megkapja a felsorolt felhasználók hozzászólásait. Keresési átjátszók A tartalom vagy felhasználók keresésekor használandó átjátszók listája. A címkézés és a keresés nem fog működni, ha nem áll rendelkezésre semmilyen beállítás. Győződjön meg arról, hogy alkalmazzák a NIP-50-et. Helyi átjátszók @@ -853,11 +672,8 @@ Ezt a verziót a következők hozták létre Önnek: %1$s verzió Köszönöm! - Maximális korlát Korlátozott írások Elágaztatva innen: - ELÁGAZTATÁS - Git tároló: %1$s Weboldal: Klónozás: OTS: %1$s @@ -865,20 +681,13 @@ Bizonyíték van arra, hogy ezt a bejegyzést valamikor %1$s előtt írták alá. A bizonyítékot ezen a napon és időpontban bélyegezték a Bitcoin blokkláncába. Bejegyzés szerkesztése Javaslat egy bejegyzés javítására - Változások összefoglalása - Gyors javítások… Javaslat elfogadása Videó lejátszása felugró ablakban Letöltés - Feliratozás bekapcsolva - Feliratozás kikapcsolva - Lezárt üzenetek kikapcsolva. Koppintson a lezárt üzenetek bekapcsolásához - Lezárt üzenetek bekapcsolva. Koppintson a lezárt üzenetek kikapcsolásához Küldés Felhasználónév lejátszása hangként Kapcsolatrögzítő (Pushpin) QR-kód beolvasása - Harmadik féltől származó pénztárca-szolgáltató felkeresése: Alby A piszkozatokra nem lehet válaszolni A piszkozatokat nem lehet idézni A piszkozatokra nem lehet reagálni @@ -919,19 +728,21 @@ 507 – kevés tárhely (WebDAV): A kiszolgáló nem képes a kérést tárolni, mert kevés a tárhely. 508 – végtelen ismétlés (WebDAV): A kiszolgáló végtelen ciklusban ismétlődő kéréseket érzékelt a feldolgozáskor. 511 – hálózati azonosítás: A hálózat használata előtt azonosítani kell magunkat, pl. egy Wi-Fi-hálózat használata előtt el kell fogadni a használati feltételeket. - NIP-96-kiszolgálók - Annyi kiszolgálót adhat hozzá, amennyit csak akar. Később a kép feltöltésekor kiválaszthatja, melyiket szeretné használni Blossom-kiszolgálók Annyi kiszolgálót adhat hozzá, amennyit csak akar. Később a kép feltöltésekor kiválaszthatja, melyiket szeretné használni Egy NIP-96-kiszolgáló hozzáadása Egy Blossom-kiszolgáló hozzáadása Összes törlése Biztosan törölni szeretné az összes piszkozatot? - Köteg: Torrentfájl Letöltés Nem sikerült megnyitni a fájlt A fájl megnyitásához és letöltéséhez nincsenek torrent-alkalmazások telepítve. Lista kiválasztása a hírfolyam szűréséhez Kijelentkeztetés az eszköz zárolása esetén + A kedvezményezett lightning-szolgáltatása ennél: %1$s nem érhető el. A(z) „%2$s” lightning-cím lett kiszámítva. Hiba: %3$s. Ellenőrizze, hogy a kiszolgáló működik-e, és hogy a lightning-cím helyes-e + Nem sikerült megoldani a következőt: %1$s. Ellenőrizze, hogy kapcsolódik-e, vagy működik-e a kiszolgáló, és hogy a(z) %2$s lightning-cím helyes-e.\n\nKivéve: %3$s + Hiba történt a JSON elemzésekor a(z) %1$s számlahívásából. Ellenőrizze a felhasználó lightning-beállításait + Nem lehetett lightning-számlát létrehozni. Üzenet a következőtől: %1$s: %2$s + Nem sikerült Lightning-számlát létrehozni a következőből: %1$s: A „PR” elem nem található a kapott JSON-ban. diff --git a/amethyst/src/main/res/values-in-rID/strings.xml b/amethyst/src/main/res/values-in-rID/strings.xml index cef6471135..d6346cb69d 100644 --- a/amethyst/src/main/res/values-in-rID/strings.xml +++ b/amethyst/src/main/res/values-in-rID/strings.xml @@ -14,8 +14,6 @@ Konten Eksplisit Identitas palsu Perilaku Ilegal - Tidak dikenal - Ikon Relai Penulis Tidak Dikenal Salin Teks Salin ID Penulis @@ -26,7 +24,6 @@ Laporkan Spam / Penipuan Laporkan Pemalsuan Identitas - Laporkan Konten Eksplisit Laporkan Perilaku Ilegal Anda memakai kunci publik dan kunci publik hanya dapat membaca saja. Silahkan login dengan kunci privat agar dapat membalas Anda memakai kunci publik dan kunci publik hanya dapat membaca saja. Silahkan login dengan kunci privat agar dapat mengirim postingan @@ -38,7 +35,6 @@ Anda memakai kunci publik dan kunci publik hanya dapat membaca saja. Silahkan login dengan kunci privat agar dapat menyembunyikan kata atau kalimat Anda memakai kunci publik dan kunci publik hanya dapat membaca saja. Silahkan login dengan kunci privat agar dapat menampilkan kata atau kalimat Zap - Lihat jumlah Sebarkan disebarkan Kutip @@ -46,9 +42,7 @@ Tambah "balas ke " " dan " - "dalam kanal " Banner Profil - Pembayaran berhasil Salah memilah pesan error " Mengikuti" " Pengikut" @@ -62,9 +56,7 @@ Terima kasih banyak! Jumlah (sat) Kirim sat - "Salah memilah preview untuk %1$s : %2$s" "Preview gambar untuk %1$s" - Kanal baru Nama kanal Groupku Luar Biasa Url gambar @@ -75,34 +67,19 @@ Simpan Buat Batal - Gagal mengunggah gambar - Alamat relai - Postingan - Byte Kesalahan - Umpan Utama - Umpan Pesan Privat - Umpan Percakapan Publik - Umpan Global - Umpan Pencarian Tambah Relay Nama Tampilan Nama tampilan saya - Username saya Tentang saya URL avatar URL banner URL situs web - Alamat LN - URL LN (kedaluwarsa) Gambar disimpan ke galeri Gagal menyimpan gambar Unggah gambar - Mengunggah… Pengguna belum mengatur alamat lightning untuk menerima sat "balas disini.. " - Salin ID Note ke papan klip untuk dibagikan dalam Nostr - Salin ID Kanal (Note) ke papan klip Ubah metadata kanal Gabung Dikenal @@ -112,16 +89,12 @@ Percakapan Note Balasan - "Ikuti" "Laporan" Opsi Lainnya " Relai" Situs web Alamat Lightning Salin ID Nsec (kata sandi Anda) ke papan klip untuk cadangan - Salin Kunci Rahasia ke papan klip - Salin kunci publik ke papan klip untuk dibagikan - Salin Kunci Publik (NPub) ke papan klip Kirim Pesan Langsung Ubah metadata pengguna Ikuti @@ -140,7 +113,6 @@ ketentuan penggunaan Persetujuan aturan penggunaan diperlukan Kunci diperlukan - Buat kunci baru Memuat umpan Memuat akun @@ -149,12 +121,6 @@ Coba lagi Umpan kosong. Muat ulang - dibuat - dengan deskripsi dari - dan gambar - ubah nama obrolan ke - deskripsi untuk - dan gambar untuk Keluar Berhenti mengikuti Kanal dibuat @@ -177,7 +143,6 @@ Kata-kata kotor / Ujaran kebencian Lapor ujaran kebencian Lapor ketelanjangan / pornografi - lainnya Tandai semua yang dikenal sebagai telah dibaca Tandai semua yang baru sebagai telah dibaca Tandai semua sebagai telah dibaca @@ -187,23 +152,18 @@ Autentikasi gagal Gagal mengautentikasi biometrik pemilik ponsel ini Gagal mengautentikasi biometrik pemilik ponsel ini. Error: %1$s - Terjadi Kesalahan - "Dibuat oleh %1$s" "Gambar penghargaan lencana untuk %1$s" Anda menerima penghargaan lencana baru Penghargaan lencana diberikan kepada Teks disalin ke papan klip \@npub pemilik telah disalin ke papan klip ID note (@note1) telah disalin ke papan klip - Pilih teks "<Gagal mendekripsi pesan rahasia>\n\n Anda dikutip dalam percakapan pribadi/terenkripsi antara %1$s dan %2$s." Tambahkan Akun Baru Akun Pilih akun Tambahkan Akun Baru Akun Aktif - Memiliki kunci rahasia - Baca saja. Tidak ada kunci rahasia Kembali Pilih Bagikan Link Browser @@ -220,7 +180,6 @@ Hapus Blokir Laporkan - Hapus Jangan tampilkan lagi Spam atau penipuan Perilaku tidak senonoh atau penuh kebencian @@ -245,29 +204,15 @@ Tambahkan ke Markah Publik Hapus dari Markah Privat Hapus dari Markah Publik - Layanan Wallet Connect - Otorisasi Rahasia Nostr untuk membayar zap tanpa meninggalkan aplikasi. Jaga rahasianya tetap aman dan gunakan relay pribadi jika memungkinkan - Kunci Publik Wallet Connect - Relay Wallet Collect - Rahasia Wallet Connect - Tampilkan kunci rahasia - Kunci rahasia nsec / hex Jumlah Ikrar dalam Sat - Kolom-kolom wajib: - Penerima Zap - Deskripsi poll utama… Opsi %s Deskripsi Opsi Poll - Kolom opsional: Minimum Zap Maximum Zap Konsensus (0–100)% - Tutup setelah - hari Tidak dapat memilih Poll ditutup - Jumlah Zap Hanya satu suara per pengguna yang diperbolehkan pada jenis poll ini "Mencari Event %1$s" Tambahkan pesan publik @@ -294,29 +239,11 @@ Anonim Publik dan Penerima tidak mengetahui siapa yang mengirim pembayaran Tidak ada jejak di Nostr, hanya di Lightning - LnAddress atau @Pengguna - Relay-relay anda (NIP-95) - File dihosting oleh relay Anda. NIP Baru: periksa apakah relay mendukung - Pengaturan Tor/Orbot - Hubung melalui Orbot Anda - Putuskan sambungan dari Orbot/Tor Anda? - Data Anda akan ditransfer di jaringan reguler Ya Tidak - Daftar Ikut Semua Pengikut - ## Hubung melalui Tor dengan Orbit - \n\n1. Install [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Mulai Orbot - \n3. Di Orbot, Periksa port Socks. Secara default memakai 9050 - \n4. Jika diperlukan, Ganti port di Orbot - \n5. Konfigurasikan port Socks di layar ini - \n6. Tekan tombol Aktivasi untuk menggunakan Orbot sebagai proxy - Port Socks Orbot Nomor port tidak valid - Pakai Orbot - Putuskan koneksi Tor/Orbot Pesan Pribadi Memberi tahu Anda ketika pesan pribadi tiba Zap Diterima @@ -325,20 +252,9 @@ untuk %1$s Memberitahu: - Gabung Percakapan - ID Pengguna atau Grup - npub, nevent, atau hex - Buat - Gabung Hari ini Peringatan Konten Post ini mengandung konten sensitif yang mungkin dianggap menyinggung atau mengganggu oleh sebagian orang - Selalu sembunyikan konten sensitif - Selalu tampilkan konten sensitif - Selalu tampilkan peringatan konten - Rekomendasi: - Filter spam dari orang asing - Peringatkan jika postingan memiliki laporan dari orang yang anda ikuti Simbol Reaksi Baru Tidak ada jenis reaksi yang dipilih sebelumnya untuk pengguna ini. Tekan lama tombol hati untuk mengubahnya Penggalan dana Zap @@ -347,31 +263,21 @@ Penggalan Dana di %1$s. Sasaran %2$s sat Baca dari Relay Tulis ke Relay - Terjadi kesalahan saat menerima informasi relay dari %1$s Pemilik Versi Perangkat Lunak Kontak NIP yang didukung - Biaya Pendaftaran URL Pembayaran Pembatasan Negara Bahasa - Tag Kebijakan posting - Panjang pesan - Langganan - Filter - Panjang ID Langganan Awalan minimal Tag Event Maksimum - Panjang konten PoW Minimum - Pembayaran Token Cashu Tidak ada Alamat Lightning yang ditetapkan - Token disalin ke papan klip LANGSUNG BERAKHIR DIJADWALKAN @@ -393,7 +299,6 @@ Beri tahu kepada pemilik untuk menambahnya (translated) row titles. Marked translatable="false" so protocol terms (blossom, nsec, negentropy, …) stay searchable in every locale and aren't sent to translators. --> Selalu - Wifi-saja Jangan pernah Sistem Terang @@ -406,7 +311,6 @@ Beri tahu kepada pemilik untuk menambahnya Pratinjau URL Pengguliran Mendalam Sembunyikan Nav Bar saat menggulir - Muat Gambar Spammer Dibisukan. Ketuk untuk membunyikan Suara aktif. Ketuk untuk bisukan @@ -414,16 +318,9 @@ Beri tahu kepada pemilik untuk menambahnya Alamat nostr telah diverifikasi Verifikasi alamat Nostr gagal Memeriksa alamat Nostr - Pilih/Batal semua - Pilih relay untuk melanjutkan - Teruskan Zap ke: - Klien yang didukung akan mengalihkan zap ke LNAddress atau Profil Pengguna dibawah ini Paparkan Lokasi sebagai Menambahkan Geohash lokasi Anda ke postingan. Publik akan mengetahui bahwa Anda berada dalam jarak 5 km (3 mil) dari lokasi saat ini Menambahkan peringatan konten sensitif sebelum menampilkan konten Anda. Ini berguna untuk konten NSFW apa pun atau konten yang mungkin dianggap menyinggung atau mengganggu oleh sebagian orang - Fitur Baru - Mengaktifkan mode ini mengharuskan Amethyst mengirim pesan NIP-17 (GiftWrapped, Sealed Direct, dan Group Messages). NIP-17 masih baru dan sebagian besar klien belum menerapkannya. Pastikan penerima menggunakan klien yang didukung. - Aktifkan Publik Privat Ke @@ -439,39 +336,23 @@ Beri tahu kepada pemilik untuk menambahnya Muat gambar dan GIF secara otomatis Putar video dan GIF secara otomatis Tampilkan Pratinjau URL - Kapan memuat gambar Salin URL ke papan klip Salin ID Note ke papan klip Dibuat di - Peraturan Login dengan Amber Perbarui status anda - Kesalahan penguraian pesan kesalahan Suara ditimbang berdasarkan jumlah zap. Anda dapat menetapkan jumlah minimum untuk menghindari spammer dan jumlah maksimum untuk menghindari zappers besar mengambil alih jajak pendapat. Gunakan jumlah yang sama di kedua kolom untuk memastikan setiap suara bernilai sama. Biarkan kosong untuk menerima jumlah berapa pun. Tidak dapat mengirim zap Kirim pesan ke Pengguna - Gagal menghubungi %1$s: %2$s - Gagal menghubungi %1$s: %2$s - Gagal menguraikan hasil dari %1$s: %2$s - %1$s gagal dengan kode %2$s - Aktif selama: - Beranda - Obrolan - Cari Pisah dan alihkan Zap Klien yang didukung akan memisah dan mengalihkan zap kepada user yang ditambahkan disini Cari dan Tambahkan Pengguna Username atau tampilan nama Lightning tidak tersedia %1$s belum mengatur alamat lightning untuk menerima sat - Persentase - Memisahkan Zap dengan - Mengalihkan Zap ke - Dompet Lightning tidak ditemukan Dibayar Dompet: %1$s Terjadi kesalahan saat membuka aplikasi penanda tangan - Permintaan tanda tangan ditolak Tidak ada Dompet yang ditemukan untuk membayar faktur Lightning (Kesalahan: %1$s). Silakan instal dompet Lightning untuk menggunakan zap Tidak ada Dompet yang ditemukan untuk membayar faktur Lightning. Silakan instal dompet Lightning untuk menggunakan zap Kata-kata tersembunyi @@ -481,31 +362,16 @@ Beri tahu kepada pemilik untuk menambahnya Pilih sebuah Opsi Tidak dapat membayar faktur Tidak dapat menarik - Tidak dapat menyiapkan Wallet Connect - Gagal menguraikan teks koneksi NIP-47. Periksa apakah ini benar dengan penyedia Wallet Anda: %1$s. Error: %2$s - Gagal menguraikan teks koneksi NIP-47. Periksa apakah ini benar dengan penyedia Wallet Anda: %1$s. Tidak dapat meredeem Cashu Mint memberikan error: %1$s - Token Cashu sudah dipakai/habis. Cashu Diterima %1$s sat telah dikirim ke dompetmu. (Biaya: %2$s sat) Tidak dapat menghubung server faktur penerima Penyedia Wallet Connect anda memberi error: %1$s - Tidak dapat terhubung ke Tor - Tidak dapat menerima dokumen relay Tidak dapat merakit LNUrl dari Alamat Lightning \"%1$s\". Periksa pengaturan pengguna - Layanan Lightning penerima di %1$s tidak tersedia. Itu dihitung dari alamat Lightning \"%2$s\". Kesalahan: %3$s. Periksa apakah server aktif dan apakah alamat petir sudah benar - Tidak dapat menghubungi %1$s. Periksa apakah Anda terhubung, apakah server aktif dan apakah alamat Lightning %2$s sudah benar - Tidak dapat menerima faktur dari %1$s - Tidak dapat mengurai JSON dari alamat Lightning. -Periksa pengaturan Lightning pengguna - URL panggilan balik tidak ditemukan dalam konfigurasi server alamat Lightning Pengguna - Tidak dapat mengurai JSON dari faktur alamat Lightning. -Periksa pengaturan Lightning pengguna Jumlah faktur salah (%1$s sat) dari %2$s. Seharusnya %3$s Tidak dapat membuat faktur Lightning sebelum mengirim zap. Dompet Lightning penerima mengirimkan kesalahan berikut: %1$s - Tidak dapat membuat faktur Lightning sebelum mengirim zap. Elemen pr tidak ditemukan di JSON yang dihasilkan. Pengguna hanya-baca Tidak mengatur reaksi Pilih aplikasi UnifiedPush @@ -530,4 +396,6 @@ Seharusnya %3$s + + Layanan Lightning penerima di %1$s tidak tersedia. Itu dihitung dari alamat Lightning \"%2$s\". Kesalahan: %3$s. Periksa apakah server aktif dan apakah alamat petir sudah benar diff --git a/amethyst/src/main/res/values-in/strings.xml b/amethyst/src/main/res/values-in/strings.xml index 00447eb60f..2f74c858ba 100644 --- a/amethyst/src/main/res/values-in/strings.xml +++ b/amethyst/src/main/res/values-in/strings.xml @@ -15,8 +15,6 @@ Spam Peniruan/penipuan Perilaku Ilegal - Tidak dikenal - Ikon Relai Penulis Tidak Dikenal Salin Teks Salin ID Penulis (Author ID) @@ -27,7 +25,6 @@ Laporkan Spam / Penipuan Laporkan Peniruan - Laporkan Konten Eksplisit Laporkan Perilaku Ilegal Masuk dengan Kunci pribadi (nsec) untuk dapat membalas tulisan Masuk dengan Kunci pribadi (nsec) untuk dapat mempromosikan tulisan @@ -37,7 +34,6 @@ Masuk dengan Kunci pribadi (nsec) untuk dapat mengikuti Masuk dengan Kunci pribadi (nsec) untuk berhenti mengikuti Zaps - Jumlah pengamat Promosi dipromosikan Kutipan @@ -45,9 +41,7 @@ Tambah "membalas kepada " " dan " - dalam kanal Spanduk Profil - Pembayaran Berhasil Gagal menguraikan pesan kesalahan " Mengikuti" " Pengikut" @@ -62,9 +56,7 @@ Terima kasih banyak! Jumlah dalam Sats Kirim Sats - Gagal menampilkan pratinjau untuk %1$s : %2$s Pratinjau Gambar Kartu untuk %1$s - Kanal Baru Nama Kanal Grupku yang Hebat Alamat Url Gambar @@ -75,35 +67,20 @@ Simpan Buat Batal - Gagal mengunggah gambar - Alamat Relai - Kiriman - Bytes Errors - Beranda - Area Pesan Pribadi - Area Percakapan Publik - Area Global - Area Pencarian Tambah Relai Nama ditampilkan Namaku yg ditampilkan Nama pengguna - Nama penggunaku Tentang saya URL Avatar "URL Spanduk/Banner " URL Situs Web - Alamat LN - LN URL (versi lama) Gambar disimpan ke galeri Gagal menyimpan gambar Unggah Gambar - Mengunggah… Pengguna tidak memiliki alamat lightning (LN) yang diatur untuk menerima sats "balas di sini.. " - Menyalin ID Catatan ke papan klip untuk dibagikan di Nostr - Salin ID Kanal (Catatan) ke Papan Klip Ubah Metadata Kanal Gabung Dikenali @@ -113,16 +90,12 @@ Percakapan Catatan Balasan - Mengikuti Laporan Lebih banyak pilihan " Relai" Situs Web Alamat Lightning Salin Nsec ID (kata sandi anda) ke papan klip sebagai cadangan - Salin Kunci Privat ke papan klip - Salin Kunci Publik ke papan klip untuk dibagikan - Salin Kunci Publik (NPub) ke papan klip Kirim Pesan Langsung Ubah Metadata Pengguna Ikuti @@ -142,18 +115,11 @@ Penerimaan persyaratan diperlukan Kunci diperlukan Masuk - Buat kunci baru Memuat data umpan "Gagal memuat balasan: " Coba lagi Data umpan kosong. Perbarui - dibuat - "dengan deskripsi " - dan gambar - mengubah nama percakapan menjadi - deskripsi untuk - dan gambar untuk Tinggalkan Berhenti mengikuti Kanal dibuat @@ -177,7 +143,6 @@ Ujaran kotor/kebencian Laporkan ujaran kebencian Laporkan Ketelanjangan / Pornografi - lainnya Tandai semua yg dikenal telah dibaca Tandai pesan baru telah dibaca Tandai semua telah dibaca @@ -185,23 +150,18 @@ Kunci rahasia (nsec) disalin ke clipboard Salin kunci rahasia saya Autentikasi gagal - Kesalahan - Dibuat oleh %1$s Gambar penghargaan lencana untuk %1$s Anda Menerima Penghargaan Lencana baru Penghargaan lencana diberikan kepada Teks catatan disalin ke papan klip \@npub Penulis disalin ke papan klip Note ID (@note1) disalin ke papan klip - Pilih Teks <Gagal mendeskripsikan pesan pribadi>\n\nAnda dikutip dalam percakapan pribadi/terenkripsi antara %1$s dan %2$s. Tambah Akun Baru Akun Pilih Akun Tambah Akun Baru Akun Aktif - Memiliki kunci pribadi - Baca saja, tidak ada kunci pribadi Kembali Pilih Bagikan Tauatan ke Peramban @@ -218,7 +178,6 @@ Hapus Blokir Laporkan - Hapus Jangan tampilkan lagi Spam atau penipuan Perilaku tidak senonoh atau penuh kebencian @@ -243,28 +202,13 @@ Tambahkan Penanda Publik Hapus dari Penanda Pribadi Hapus dari Penanda Publik - Layanan Wallet Connect - Mengijinkan Kunci Rahasia Nostr untuk membayar zaps tanpa meninggalkan aplikasi. Jaga kunci tetap aman dan gunakan relai pribadi jika memungkinkan - Kunci Publik Wallet Connect - Relai Wallet Connect - Kunci Rahasia Wallet Connect - Tampilkan kunci rahasia - nsec / hex (kunci pribadi) Jumlah Dijanjikan dalam Sats - Kirim Pemungutan Suara - Bidang yang wajib diisi: - Penerima Zap - Deskripsi Utama Pemungutan Suara… Pilihan %s Deskripsi pilihan pemungutan suara - Bidang pilihan (tidak wajib): Zap terendah Zap tertinggi Konsensus (0–100)% - Berakhir pada - hari - Jumlah Zap Hanya satu suara per pengguna yang diperbolehkan pada jenis pemungutan suara ini Mencari data event %1$s Tambah pesan publik @@ -292,23 +236,12 @@ Bukan Zap Tidak ada jejak di Nostr, hanya di Lightning Network Server Berkas - Alamat LN atau @Pengguna - Relai anda (NIP-95) - Berkas disimpan di relai anda. NIP baru: periksa apakah relai mendukung fitur - Pengaturan Tor/Orbot - Hubungkan melalui pengaturan Orbot Anda - Putuskan sambungan dari Orbot/Tor Anda? - Data Anda akan segera ditransfer di jaringan reguler (bukan TOR) Ya Tidak - Daftar yang Diikuti Semua yang diikuti Global - "\n ## Terhubung melalui Tor menggunakan Orbot\n \n\n1. Pasang [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android)\n \n2. Jalankan Orbot\n \n3. Di dalam Orbot, periksa nomor port Socks. Secara bawaan menggunakan nomor 9050\n \n4. Jika diperlukan, ubah nomor port Orbot\n \n5. Atur nomor port Socks pada layar ini\n \n6. Tekan tombol Aktifkan untuk menggunakan Orbot sebagai proxy\n " Port Orbot Socks Nomor port tidak sah - Gunakan Orbot - Putuskan Tor/Orbot Pesan Pribadi Memberi tahu Anda ketika pesan pribadi tiba Zaps diterima @@ -317,20 +250,9 @@ Dari %1$s untuk %1$s "Beritahu: " - Gabung Percakapan - ID Pengguna atau Grup - npub, nevent atau kode heksa - Buat - Gabung Hari ini Peringatan konten Postingan ini berisi konten sensitif yang mungkin dianggap menyinggung atau mengganggu oleh sebagian orang - Selalu sembunyikan konten sensitif - Selalu tampilkan konten sensitif - Selalu tampilkan peringatan konten - "Rekomendasi: " - Saring spam dari orang asing (tak diikuti) - Peringatkan ketika kiriman memiliki laporan dari pengikut Anda Simbol Reaksi Baru Tidak ada jenis reaksi yang dipilih. Tekan dan tahan untuk mengubah Galang Dana Zap @@ -339,33 +261,22 @@ Galang Dana Zap mencapai %1$s. %2$s sats untuk memenuhi target Baca dari Relai Tulis ke Relai - Terjadi kesalahan saat mencoba mendapatkan informasi relai %1$s Pemilik Versi Perangkat Lunak Kontak NIP yg didukung - Biaya Pendaftaran Alamat Pembayaran Batasan Negara Bahasa - Tags Kebijakan kiriman - Panjang pesan - Langganan - Penyaringan - Panjang ID Subscription Awalan minimal Jumlah Tags maksimum - Panjang konten PoW terendah - Autentikasi - Pembayaran Token Cashu Tukarkan Tidak ada alamat Lightning yang diatur - Token disalin ke papan klip DARING (ON) LURING (OFF) BERAKHIR @@ -383,7 +294,6 @@ Menambahkan peringatan konten sensitif sebelum menampilkan konten ini Pengaturan Selalu - Hanya Wifi Tidak Pernah Sistem Terang @@ -394,7 +304,6 @@ Pratinjau Gambar Pemutaran Video Pratinjau URL - Muat Gambar Pengirim Spam Diredam. Klik untuk bersuara Bersuara. Kilik untuk meredam @@ -402,17 +311,10 @@ Alamat Nostr diverifikasi Alamat Nostr gagal diverifikasi Memeriksa Alamat Nostr - Pilih / Hapus Semua Bawaan - Pilih Relai untuk melanjutkan - Teruskan Zaps ke: - Klien yg mendukung akan meneruskan zaps ke Alamat LN atau Profil Pengguna di bawah ini, bukan ke alamat LN Anda Paparkan Lokasi sebagai Menambahkan Geohash lokasi Anda ke postingan. Publik akan mengetahui bahwa Anda berada dalam jarak 5 km (3 mil) dari lokasi saat ini Menambahkan peringatan konten sensitif sebelum menampilkan konten Anda. Ini ideal untuk konten NSFW apa pun atau konten yang mungkin dianggap menyinggung atau mengganggu oleh sebagian orang - Fitur Baru - Mengaktifkan mode ini mengharuskan Amethyst mengirim pesan NIP-17 (GiftWrapped, Sealed Direct, dan Group Messages). NIP-17 masih baru dan sebagian besar klien belum menerapkannya. Pastikan penerima menggunakan klien yang kompatibel. - Aktifkan Publik Pribadi Ke @@ -427,26 +329,13 @@ Memuat gambar dan GIF secara otomatis Memutar video dan GIF secara otomatis Tampilkan pratinjau URL - Kapan memuat gambar Salin URL ke papan klip Salin ID Catatan ke papan klip Dibuat pada - Aturan Perbaharui statusmu - Kesalahan menguraikan pesan kesalahan Suara ditimbang berdasarkan jumlah zap. Anda dapat menetapkan jumlah minimum untuk menghindari pembuat spam dan jumlah maksimum untuk menghindari pengirim zap besar mengambil alih pemungutan suara. Gunakan jumlah yang sama di kedua kolom untuk memastikan setiap suara bernilai sama. Biarkan kosong untuk menerima jumlah berapa pun. Tidak dapat mengirim zap Kirim Pesan ke Pengguna - Gagal mengakses %1$s: %2$s - Gagal mengakses %1$s: %2$s - Gagal memproses hasil dari %1$s: %2$s - %1$s gagal dengan kode %2$s - Aktif untuk: - Beranda - Pesan Langsung - Percakapan - Global - Pencarian Tempel dari papan klip Masuk dengan Amber Bagi dan Teruskan Zaps @@ -454,14 +343,9 @@ Cari dan Tambah Pengguna Nama pengguna atau nama ditampilkan Pengguna %1$s tidak memiliki alamat lightning yang diatur untuk menerima sats - Persentase - Bagikan zaps dengan - Teruskan zaps kepada - Dompet Lightning tidak ditemukan Dibayar Dompet %1$s Kesalahan membuka aplikasi pengesahan - Permintaan pengesahan ditolak Tidak ditemukan Dompet untuk membayar faktur lightning (Kesalahan: %1$s). Silakan instal dompet Lightning untuk menggunakan zaps Tidak ditemukan Dompet untuk membayar faktur lightning. Silakan instal dompet Lightning untuk menggunakan zaps Ok @@ -482,28 +366,16 @@ Pilih sebuah pilihan Tidak dapat membayar tagihan Tidak dapat mengambil dana - Tidak dapat mengatur Wallet Connect - Terjadi kesalahan saat mengurai string koneksi NIP-47. Periksa apakah ini benar dengan penyedia Wallet Anda: %1$s. Kesalahan: %2$s - Terjadi kesalahan saat mengurai string koneksi NIP-47. Periksa apakah ini benar dengan penyedia Wallet Anda: %1$s. Tidak dapat menukarkan Cashu Mint memberikan pesan kesalahan berikut: %1$s - Token Cashu sudah habis. Cashu diterima %1$s sat telah dikirim ke dompet Anda. (Biaya: %2$s sat) Tidak dapat mengambil faktur dari server penerima Penyedia koneksi dompet Anda menampilkan kesalahan berikut: %1$s - Tidak dapat terhubung ke Tor - Unduh dokumen relai tidak tersedia Tidak dapat merakit LNUrl dari Alamat Lightning \"%1$s\". Periksa pengaturan pengguna - Layanan lightning penerima pada %1$s tidak tersedia. Itu dihitung dari alamat petir \"%2$s\". Kesalahan: %3$s. Periksa apakah server aktif dan apakah alamat lightning sudah benar - Tidak dapat menyelesaikan %1$s. Periksa apakah Anda terhubung jaringan, apakah server aktif dan apakah alamat lightning %2$s sudah benar - Tidak dapat mengambil faktur dari %1$s - "Kesalahan mengurai JSON dari Alamat Lightning. Periksa pengaturan lightning pengguna " - URL panggilan balik tidak ditemukan dalam konfigurasi server alamat lightning Pengguna - Kesalahan saat Mengurai JSON dari pengambilan faktur Alamat Lightning. Periksa pengaturan lightning pengguna Jumlah faktur salah (%1$s sats) dari %2$s. Seharusnya %3$s Tidak dapat membuat faktur lightning sebelum mengirim zap. Dompet Lightning penerima mengirimkan kesalahan berikut: %1$s - Tidak dapat membuat faktur kilat sebelum mengirim zap. Elemen \'pr\' tidak ditemukan di JSON yang dihasilkan. Pengguna hanya-baca Tidak ada pengaturan reaksi + Layanan lightning penerima pada %1$s tidak tersedia. Itu dihitung dari alamat petir \"%2$s\". Kesalahan: %3$s. Periksa apakah server aktif dan apakah alamat lightning sudah benar diff --git a/amethyst/src/main/res/values-it-rIT/strings.xml b/amethyst/src/main/res/values-it-rIT/strings.xml index 23b91575ab..8ecb2ee766 100644 --- a/amethyst/src/main/res/values-it-rIT/strings.xml +++ b/amethyst/src/main/res/values-it-rIT/strings.xml @@ -14,8 +14,6 @@ Contenuto esplicito Impersonificazione Comportamento scorretto - Sconosciuto - Icona del relè Autore sconosciuto Copia testo Copia ID dell\'autore @@ -26,7 +24,6 @@ Segnala Spam / Truffa Segnala impersonificatore - Segnala contenuto esplicito Segnala comportamento scorretto Accedi con una chiave privata per poter rispondere Accedi con una chiave privata per poter condividere i post @@ -36,7 +33,6 @@ Accedi con una chiave privata per poter seguire Accedi con una chiave privata per poter smettere di seguire Zap - Mostra conteggio Condividi condiviso Cita @@ -44,9 +40,7 @@ Aggiungi "rispondendo a" " e " - "nel canale " Immagine di copertina - Pagamento effettuato Errore analisi messaggio d\'errore " Seguiti" " Seguaci" @@ -61,9 +55,7 @@ Grazie mille! Importo in Sats Invia Sats - "Errore nella creazione dell'anteprima di %1$s : %2$s" "Anteprima immagine per %1$s" - Nuovo canale Nome canale Il mio fantastico gruppo Url foto @@ -73,31 +65,19 @@ Salva Crea Cancella - Impossibile caricare l\'immagine - Indirizzo Relay Errori - Lista Messaggi Privati - Lista Chat Pubbliche - Feed Globale - Risultati Ricerca Aggiungi un Relay Nome Visualizzato Il mio nome visualizzato - Il mio nome utente Su di me Immagine del profilo URL Copertina URL Sito web URL - Indirizzo LN - LN URL (obsoleto) Immagine salvata nella galleria Salvataggio dell\'immagine non riuscito Carica immagine - Caricamento… L\'utente non dispone di un indirizzo Lightning per ricevere sats "rispondi qui.. " - Copia l\'ID della nota negli appunti per la condivisione in Nostr - Copia l\'ID del canale (Nota) negli appunti Modifica i metadati del canale Unisciti Conosciuto @@ -107,16 +87,12 @@ Conversazioni Note Risposte - "Seguiti" "Segnalazioni" Più Opzioni " Relè" Sito web Indirizzo Lightning Copia l\'ID Nsec (la password) negli appunti per il backup - Copia la chiave segreta negli appunti - Copia la chiave pubblica negli appunti per la condivisione - Copia la chiave pubblica (Npub) negli appunti Invia un messaggio diretto Modifica i metadati dell\'utente Segui @@ -136,7 +112,6 @@ L\'accettazione dei termini è obbligatoria La chiave è obbligatoria Accesso - Genera una nuova chiave Caricamento del feed @@ -144,12 +119,6 @@ Prova di nuovo Il feed è vuoto. Aggiorna - creato - con la descrizione di - e l\'immagine - modificato il nome della chat in - descrizione per - e immagine per Esci Non seguire più Canale creato @@ -169,7 +138,6 @@ Volgaritá / Linguaggio forte Segnala linguaggio forte Segnala Nuditá / Pornografia - altri Segna tutti i conosciuti come letti Segna tutti i nuovi come letti Segna tutti come letti @@ -177,23 +145,18 @@ Chiave segreta (nsec) copiata negli appunti Copia la mia chiave segreta Autenticazione fallita - Errore - "Creato da %1$s" "Immagine premio badge per %1$s" Hai ricevuto un nuovo premio Badge Premio badge assegnato a Testo della nota copiato negli appunti \@npub dell\'autore copiata negli appunti ID della nota copiato (@note1) negli appunti - Seleziona testo "<Incapace di decriptare il messaggio privato>\n\nSei stato citato in una conversazione privata/criptata tra %1$s e %2$s." Aggiungi un nuovo profilo Profili Seleziona profilo Aggiungi un nuovo profilo Profilo attivo - Ha la chiave privata - Solo lettura, nessuna chiave privata Indietro Seleziona Condividi Collegamento Browser @@ -210,7 +173,6 @@ Elimina Blocca Segnala - Elimina Non mostrare più Spam o truffe Blasfemia o comportamento odioso @@ -235,25 +197,12 @@ Aggiungi ai segnalibri pubblici Rimuovi dai segnalibri privati Rimuovi dai segnalibri pubblici - Servizio di Connessione Portafoglio - Autorizza un Nostr Secret a pagare gli zaps senza lasciare l\'app. Mantieni il segreto al sicuro e usa un relè privato se possibile - Wallet Connect Relè - Mostra chiave segreta - nsec / chiave privata esadecimale Importo in pegno in sats - Pubblica sondaggio - Campi obbligatori: - Destinatari zap - Descrizione principale del sondaggio… Opzione %s Descrizione opzione sondaggio - Campi facoltativi: Zap minimo Zap massimo Consenso - Chiudi dopo - giorni - Quantità in zap Per questo tipo di sondaggio è consentito solo un voto per utente "Cercando l'evento %1$s" Aggiungi un messaggio pubblico @@ -279,29 +228,11 @@ Anonimo Il destinatario e il pubblico non sanno chi ha inviato il pagamento Nessuna traccia in Nostr, solo in Lightning - Indirizzo LN o @User - I tuoi relè (NIP-95) - I file sono ospitati dai tuoi relè. Nuovo NIP: controlla se lo supportano - Configurazione Tor/Orbot - Connettiti tramite la tua configurazione di Orbot - Disconnettere dal tuo Orbot/Tor? - I tuoi dati verranno immediatamente trasferiti nella rete regolare Sì - Segui Lista Tutti i seguiti Globale - ## Connettiti tramite Tor con Orbot - \n\n1. Installa [Orbot](https://play.google. om/store/apps/details?id=org.torproject.android) - \n2. Avvia Orbot - \n3. In Orbot, controlla la porta Socks. Il valore predefinito utilizza 9050 - \n4. Se necessario, cambiare la porta in Orbot - \n5. Configura la porta Socks in questa schermata - \n6. Premi il pulsante Attiva per usare Orbot come proxy - Porta Socks di Orbot Numero della porta non valido - Usa Orbot - Disconnetti Tor/Orbot Messaggi privati Notifica quando arriva un messaggio privato Zaps Ricevuti @@ -310,20 +241,9 @@ per %1$s Notificare: - Unisciti Alla Conversazione - ID utente o di gruppo - npub, nevent o esadecimale - Crea - Unisciti Oggi Avviso sui contenuti Questo post contiene contenuti sensibili che alcune persone possono trovare offensivi o disturbanti - Nascondi sempre i contenuti sensibili - Mostra sempre i contenuti sensibili - Mostra sempre gli avvisi sui contenuti - Consigliati: - Filtra spam dagli sconosciuti - Avvisa quando i post hanno segnalazioni da parte di chi segui Nuovo Simbolo Di Reazione Nessun tipo di reazione selezionato. Premi a lungo per cambiare Aggiunge una quantità di sats da raccogliere per questo post. I client che supportano questa funzione la mostreranno con una barra di avanzamento per incentivare le donazioni @@ -331,30 +251,21 @@ Zapraiser a %1$s. %2$s sats all\'obiettivo Leggi dal Relè Scrivi su Relè - Si è verificato un errore nel tentativo di ottenere le informazioni del relè da %1$s Proprietario Versione Contatto NIPs Supportati - Commissioni di Ammissione Url pagamenti Limitazioni Paesi Lingue Politica di pubblicazione - Lunghezza del messaggio - Iscrizioni - Filtri - Lunghezza ID Iscrizione Prefisso minimo Tags massimi dell\'evento - Lunghezza del contenuto PoW Minima - Pagamento Token di Cashu Riscatta Nessun indirizzo Lightning impostato - Token copiato negli appunti IN DIRETTA NON IN LINEA CONCLUSO @@ -376,7 +287,6 @@ (translated) row titles. Marked translatable="false" so protocol terms (blossom, nsec, negentropy, …) stay searchable in every locale and aren't sent to translators. --> Sempre - Solo Wi-Fi Mai Sistema Chiaro @@ -387,24 +297,16 @@ Anteprima dell\'immagine Riproduzione video Anteprima URL - Carica immagine Mutato. Clicca per riattivare l\'audio Audio acceso. Clicca per disattivarlo Cerca registrazioni locali e remote L\'indirizzo Nostr è stato verificato Verifica dell\'indirizzo Nostr non riuscita Controllo dell\'indirizzo Nostr - Seleziona/Deseleziona tutto Predefinito - Seleziona un relè per continuare - Inoltra gli Zap a: - I client che lo supportano inoltreranno gli Zap all\'indirizzo LN o al profilo dell\'utente di seguito anzichè al tuo Esporre la posizione come Aggiunge un Geohash della tua posizione al post. Il pubblico saprà che ti trovi a 5 km dalla posizione attuale Aggiunge un avviso di contenuto sensibile prima di mostrare il tuo contenuto. Questo è ideale per qualsiasi contenuto NSFW o che alcune persone potrebbero trovare offensivo o disturbante - Nuova Funzionalità - Attivare questa modalità richiede ad Amethyst di inviare un messaggio NIP-17 (GiftWrapped, Sealed Direct e messaggi di gruppo). NIP-17 è nuovo e la maggior parte dei client non l\'hanno ancora implementato. Assicurarsi che il ricevitore stia utilizzando un client compatibile. - Attivare Pubblico/a Privato A @@ -419,26 +321,13 @@ Carica automaticamente immagini e GIF Riproduce automaticamente video e GIF Mostra anteprime URL - Quando caricare le immagini Copia URL negli appunti Copia ID della Nota negli appunti Creato il - Regole Aggiorna il tuo stato - Errore analisi messaggio d\'errore I voti sono ponderati con l\'importo dello zap. È possibile impostare una quantità minima per evitare gli spammer e una quantità massima per evitare che un grande zapper predomini il sondaggio. Usa lo stesso importo in entrambi i campi per assicurarti che ogni voto valga lo stesso importo. Lascialo vuoto per accettare qualsiasi importo. Impossibile inviare lo zap Invia un messaggio all\'utente - Impossibile raggiungere %1$s: %2$s - Impossibile raggiungere %1$s: %2$s - Impossibile analizzare il risultato da %1$s: %2$s - %1$s fallito con il codice %2$s - Attivo per: - Pagina iniziale - Messaggi diretti - Chat - Globale - Cerca @@ -451,4 +340,5 @@ + diff --git a/amethyst/src/main/res/values-iw-rIL/strings.xml b/amethyst/src/main/res/values-iw-rIL/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-iw-rIL/strings.xml +++ b/amethyst/src/main/res/values-iw-rIL/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-ja-rJP/strings.xml b/amethyst/src/main/res/values-ja-rJP/strings.xml index 54d99e747f..b3e1373882 100644 --- a/amethyst/src/main/res/values-ja-rJP/strings.xml +++ b/amethyst/src/main/res/values-ja-rJP/strings.xml @@ -15,8 +15,6 @@ スパム なりすまし 不法行為 - 不明 - リレーアイコン 不明な作者 テキストをコピー ユーザIDをコピー @@ -27,7 +25,6 @@ スパム / 詐欺を通報 なりすましを通報 - 露骨なコンテンツを通報 不法行為を通報 秘密鍵でログインするとリプライできます 秘密鍵でログインすると投稿をブーストできます @@ -37,7 +34,6 @@ 秘密鍵でログインするとフォローすることができます 秘密鍵でログインするとフォロー解除することができます ザップ - 表示回数 ブースト ブーストされました 引用 @@ -58,9 +54,7 @@ ありがとうございます! 金額 (sats) satsを送る - "%1$sのプレビューのパースに失敗しました: %2$s" "%1$sのプレビューカード画像" - 新しいチャンネル チャンネル名 私の素晴らしいグループ 画像URL @@ -71,35 +65,20 @@ 保存 作成 キャンセル - 画像のアップロードに失敗しました - リレーアドレス - 投稿 - バイト エラー - ホームフィード - 非公開メッセージフィード - 公開チャットフィード - グローバルフィード - 検索フィード リレーを追加 表示名 わたしの表示名 ユーザ名 - わたしのユーザ名 自己紹介 アバターURL バナーURL ウェブサイトURL - LNアドレス - LN URL (旧式) 画像を保存しました 画像の保存に失敗しました 画像をアップロード - アップロード中… satsを受け取るためのLightningアドレスが設定されていません "ここに返信… " - 投稿IDをクリップボードにコピー - チャンネルIDをクリップボードにコピー チャンネルのメタデータを編集 参加 知り合い @@ -109,16 +88,12 @@ 会話 投稿 リプライ - "フォロー" "通報" 詳細なオプション " リレー" ウェブサイト Lightningアドレス バックアップ用に nsec ID (パスワード) をクリップボードにコピー - クリップボードに秘密鍵をコピー - 公開鍵をクリップボードにコピー - 公開鍵 (NPub) をクリップボードにコピー ダイレクトメッセージを送信 ユーザのメタデータを編集 フォロー @@ -138,7 +113,6 @@ 利用規約の同意が必要です 鍵が必要です ログイン - 新しい鍵を生成 フィードを読み込み中 @@ -146,12 +120,6 @@ 後ほどお試しください フィードが空です 更新 - が作成しました: - 説明: - 画像: - がチャンネル情報を変更しました: - 説明: - 画像: 退出 フォロー解除 チャンネルが作成されました @@ -174,7 +142,6 @@ 誹謗中傷 / ヘイトスピーチ ヘイトスピーチを通報 ヌード / ポルノを通報 - その他 すべての「知り合い」を既読にする すべての「新規リクエスト」を既読にする すべて既読にする @@ -182,23 +149,18 @@ 秘密鍵 (nsec) をクリップボードにコピーしました 秘密鍵をコピー 認証に失敗しました - エラー - "%1$s によって作成" "%1$sのバッジ授与画像" 新しいバッジが授与されました バッジ授与が承認されました: テキストがクリップボードにコピーされました \@npubをクリップボードにコピーしました 投稿ID (@note1) をクリップボードにコピーしました - テキストを選択 "<プライベートメッセージの復号に失敗しました>\n\n%1$s と %2$s のプライベート/暗号化された会話であなたが言及されました。" アカウントを追加 アカウント アカウントを選択 新規アカウントを追加 アクティブアカウント - 秘密鍵あり - 読み取り専用、秘密鍵なし 戻る 選択 ブラウザリンクを共有 @@ -215,7 +177,6 @@ 削除 ブロック 通報 - 削除 再度表示しない スパムまたは詐欺 誹謗中傷またはヘイトスピーチ @@ -240,27 +201,12 @@ 公開ブックマークに追加 非公開ブックマークから削除 公開ブックマークから削除 - Wallet Connectサービス - アプリから離脱することなくザップするためにNostrシークレットを設定できます。シークレットは安全に保管し、可能であればプライベートリレーを使用してください - Wallet Connectの公開鍵 - Wallet Connectのリレー - Wallet Connectの秘密鍵 - 秘密鍵を表示 - nsec または hex 形式の秘密鍵 誓約額 (sats) - 投票を送信 - 必須のフィールド: - ザップ受取人 - 投票の説明… 選択肢%s 投票の選択肢の説明 - 任意のフィールド: 最小ザップ額 最大ザップ額 コンセンサス - 終了まで - 日 - ザップ額 このタイプの投票では、1ユーザにつき1回のみ投票可能です "イベント %1$s を探しています" 公開メッセージを追加 @@ -288,30 +234,12 @@ 非ザップ Nostrを経由せずにLightning支払いを行います ファイルサーバ - LNアドレス または @ユーザ名 - あなたのリレー (NIP-95) - ファイルはあなたのリレーによってホストされます。新規NIP: リレーがサポートしているか確認してください - Tor/Orbotを設定 - Orbotの設定を通して接続 - Orbot/Torから切断しますか? - データはすぐに通常のネットワークで送信されます はい いいえ - フォローリスト すべてのフォロー グローバル - ## Orbotを利用してTor経由で接続する - \n\n1. [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android)をインストール - \n2. Orbotを立ち上げる - \n3. OrbotでSocksポート番号を確認する。デフォルトは9050 - \n4. 必要に応じてOrbotでポート番号を変更する - \n5. この画面でSocksポート番号を設定する - \n6. アクティベートボタンを押して、Orbotをプロキシとして使用する - OrbotのSocksポート番号 無効なポート番号 - Orbotを使用 - Tor/Orbotを切断 プライベートメッセージ プライベートメッセージが届いたら通知する ザップを受け取りました @@ -320,20 +248,9 @@ %1$sに 通知: - 会話に参加 - ユーザIDまたはグループID - npub、nevent または hex - 作成 - 参加 今日 コンテンツ警告 この投稿には、一部の人々が不快や不穏に感じる可能性のあるセンシティブな内容が含まれています - センシティブなコンテンツを常に非表示 - センシティブなコンテンツを常に表示 - コンテンツ警告を常に表示 - 推奨: - 見知らぬユーザからのスパムをフィルタリングする - あなたがフォローしている人に通報された投稿を警告する 新しいリアクションシンボル リアクションタイプが選択されていません。長押しして変更 この投稿の目標募金額を追加します。サポートするクライアントは、寄付を促すためにこれをプログレスバーとして表示することができます @@ -345,23 +262,14 @@ ソフトウェア 連絡先 サポートしているNIP - 利用料 決済URL 制限 国 言語 - タグ 投稿ポリシー - メッセージ長 - サブスクリプション - フィルタ - サブスクリプションID長 最小プレフィックス 最大タグ数 - コンテンツ長 最小PoW - 認証 - 決済 Cashuトークン 償還 ライブ @@ -385,7 +293,6 @@ (translated) row titles. Marked translatable="false" so protocol terms (blossom, nsec, negentropy, …) stay searchable in every locale and aren't sent to translators. --> 常に - Wifiのみ システム ライト ダーク @@ -395,7 +302,6 @@ 自動的に画像/GIFを読み込み 自動的に動画を再生 自動的にURLプレビューを表示 - 画像読み込み @@ -408,4 +314,5 @@ + diff --git a/amethyst/src/main/res/values-ja/strings.xml b/amethyst/src/main/res/values-ja/strings.xml index 21a5107d2c..625bd0e298 100644 --- a/amethyst/src/main/res/values-ja/strings.xml +++ b/amethyst/src/main/res/values-ja/strings.xml @@ -15,8 +15,6 @@ スパム なりすまし 不法行為 - 不明 - リレーアイコン 不明な作者 テキストをコピー ユーザIDをコピー @@ -27,7 +25,6 @@ スパム / 詐欺を通報 なりすましを通報 - 露骨なコンテンツを通報 不法行為を通報 秘密鍵でログインするとリプライできます 秘密鍵でログインすると投稿をブーストできます @@ -37,7 +34,6 @@ 秘密鍵でログインするとフォローすることができます 秘密鍵でログインするとフォロー解除することができます ザップ - 表示回数 ブースト ブーストされました 引用 @@ -58,9 +54,7 @@ ありがとうございます! 金額 (sats) satsを送る - "%1$sのプレビューのパースに失敗しました: %2$s" "%1$sのプレビューカード画像" - 新しいチャンネル チャンネル名 私の素晴らしいグループ 画像URL @@ -71,35 +65,20 @@ 保存 作成 キャンセル - 画像のアップロードに失敗しました - リレーアドレス - 投稿 - バイト エラー - ホームフィード - 非公開メッセージフィード - 公開チャットフィード - グローバルフィード - 検索フィード リレーを追加 表示名 わたしの表示名 ユーザ名 - わたしのユーザ名 自己紹介 アバターURL バナーURL ウェブサイトURL - LNアドレス - LN URL (旧式) 画像を保存しました 画像の保存に失敗しました 画像をアップロード - アップロード中… satsを受け取るためのLightningアドレスが設定されていません "ここに返信… " - 投稿IDをクリップボードにコピー - チャンネルIDをクリップボードにコピー チャンネルのメタデータを編集 参加 知り合い @@ -109,16 +88,12 @@ 会話 投稿 リプライ - "フォロー" "通報" 詳細なオプション " リレー" ウェブサイト Lightningアドレス バックアップ用に nsec ID (パスワード) をクリップボードにコピー - クリップボードに秘密鍵をコピー - 公開鍵をクリップボードにコピー - 公開鍵 (NPub) をクリップボードにコピー ダイレクトメッセージを送信 ユーザのメタデータを編集 フォロー @@ -138,18 +113,11 @@ 利用規約の同意が必要です 鍵が必要です ログイン - 新しい鍵を生成 フィードを読み込み中 "リプライ読み込みエラー: " 後ほどお試しください フィードが空です 更新 - が作成しました: - 説明: - 画像: - がチャンネル情報を変更しました: - 説明: - 画像: 退出 フォロー解除 チャンネルが作成されました @@ -172,7 +140,6 @@ 誹謗中傷 / ヘイトスピーチ ヘイトスピーチを通報 ヌード / ポルノを通報 - その他 すべての「知り合い」を既読にする すべての「新規リクエスト」を既読にする すべて既読にする @@ -180,23 +147,18 @@ 秘密鍵 (nsec) をクリップボードにコピーしました 秘密鍵をコピー 認証に失敗しました - エラー - "%1$s によって作成" "%1$sのバッジ授与画像" 新しいバッジが授与されました バッジ授与が承認されました: テキストがクリップボードにコピーされました \@npubをクリップボードにコピーしました 投稿ID (@note1) をクリップボードにコピーしました - テキストを選択 "<プライベートメッセージの復号に失敗しました>\n\n%1$s と %2$s のプライベート/暗号化された会話であなたが言及されました。" アカウントを追加 アカウント アカウントを選択 新規アカウントを追加 アクティブアカウント - 秘密鍵あり - 読み取り専用、秘密鍵なし 戻る 選択 ブラウザリンクを共有 @@ -213,7 +175,6 @@ 削除 ブロック 通報 - 削除 再度表示しない スパムまたは詐欺 誹謗中傷またはヘイトスピーチ @@ -238,27 +199,12 @@ 公開ブックマークに追加 非公開ブックマークから削除 公開ブックマークから削除 - Wallet Connectサービス - アプリから離脱することなくザップするためにNostrシークレットを設定できます。シークレットは安全に保管し、可能であればプライベートリレーを使用してください - Wallet Connectの公開鍵 - Wallet Connectのリレー - Wallet Connectの秘密鍵 - 秘密鍵を表示 - nsec または hex 形式の秘密鍵 誓約額 (sats) - 投票を送信 - 必須のフィールド: - ザップ受取人 - 投票の説明… 選択肢%s 投票の選択肢の説明 - 任意のフィールド: 最小ザップ額 最大ザップ額 コンセンサス - 終了まで - 日 - ザップ額 このタイプの投票では、1ユーザにつき1回のみ投票可能です "イベント %1$s を探しています" 公開メッセージを追加 @@ -286,30 +232,12 @@ 非ザップ Nostrを経由せずにLightning支払いを行います ファイルサーバ - LNアドレス または @ユーザ名 - あなたのリレー (NIP-95) - ファイルはあなたのリレーによってホストされます。新規NIP: リレーがサポートしているか確認してください - Tor/Orbotを設定 - Orbotの設定を通して接続 - Orbot/Torから切断しますか? - データはすぐに通常のネットワークで送信されます はい いいえ - フォローリスト すべてのフォロー グローバル - ## Orbotを利用してTor経由で接続する - \n\n1. [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android)をインストール - \n2. Orbotを立ち上げる - \n3. OrbotでSocksポート番号を確認する。デフォルトは9050 - \n4. 必要に応じてOrbotでポート番号を変更する - \n5. この画面でSocksポート番号を設定する - \n6. アクティベートボタンを押して、Orbotをプロキシとして使用する - OrbotのSocksポート番号 無効なポート番号 - Orbotを使用 - Tor/Orbotを切断 プライベートメッセージ プライベートメッセージが届いたら通知する ザップを受け取りました @@ -317,20 +245,9 @@ %1$sから %1$sに 通知: - 会話に参加 - ユーザIDまたはグループID - npub、nevent または hex - 作成 - 参加 今日 コンテンツ警告 この投稿には、一部の人々が不快や不穏に感じる可能性のあるセンシティブな内容が含まれています - センシティブなコンテンツを常に非表示 - センシティブなコンテンツを常に表示 - コンテンツ警告を常に表示 - 推奨: - 見知らぬユーザからのスパムをフィルタリングする - あなたがフォローしている人に通報された投稿を警告する 新しいリアクションシンボル リアクションタイプが選択されていません。長押しして変更 この投稿の目標募金額を追加します。サポートするクライアントは、寄付を促すためにこれをプログレスバーとして表示することができます @@ -342,23 +259,14 @@ ソフトウェア 連絡先 サポートしているNIP - 利用料 決済URL 制限 国 言語 - タグ 投稿ポリシー - メッセージ長 - サブスクリプション - フィルタ - サブスクリプションID長 最小プレフィックス 最大タグ数 - コンテンツ長 最小PoW - 認証 - 決済 Cashuトークン 償還 ライブ @@ -378,7 +286,6 @@ コンテンツを表示する前に、センシティブなコンテンツであることを示す警告を表示します 設定 常に - Wifiのみ システム ライト ダーク @@ -388,5 +295,4 @@ 自動的に画像/GIFを読み込み 自動的に動画を再生 自動的にURLプレビューを表示 - 画像読み込み diff --git a/amethyst/src/main/res/values-kk-rKZ/strings.xml b/amethyst/src/main/res/values-kk-rKZ/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-kk-rKZ/strings.xml +++ b/amethyst/src/main/res/values-kk-rKZ/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-ko-rKR/strings.xml b/amethyst/src/main/res/values-ko-rKR/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-ko-rKR/strings.xml +++ b/amethyst/src/main/res/values-ko-rKR/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-ks-rIN/strings.xml b/amethyst/src/main/res/values-ks-rIN/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-ks-rIN/strings.xml +++ b/amethyst/src/main/res/values-ks-rIN/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-lt-rLT/strings.xml b/amethyst/src/main/res/values-lt-rLT/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-lt-rLT/strings.xml +++ b/amethyst/src/main/res/values-lt-rLT/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-lv-rLV/strings.xml b/amethyst/src/main/res/values-lv-rLV/strings.xml index 12a23a746f..0b4e682f9e 100644 --- a/amethyst/src/main/res/values-lv-rLV/strings.xml +++ b/amethyst/src/main/res/values-lv-rLV/strings.xml @@ -5,7 +5,6 @@ 👀 Kanāla attēls Grupas attēls - Nezināms Nezināms autors Kopēt tekstu Kopēt autora ID @@ -14,7 +13,6 @@ Sūdzēties par uzdošanos kā cita persona Sūdzēties par ļaunprogrammatūru Ļaunprogrammatūra - Skatījumi rediģēts Citāts Pievienot @@ -27,7 +25,6 @@ Maksāt 😎 Pievienot ierakstam - Jauns kanāls Kanāla nosaukums Attēla URL Apraksts @@ -36,21 +33,14 @@ Saglabāt Izveidot Atcelt - Neizdevās augšupielādēt attēlu - Ieraksti - Baiti Kļūdas Lietotājvārds - Mans lietotājvārds Par mani - LN adrese Augšupielādēt attēlu - Augšupielādē… Bloķētie lietotāji Piezīmes Atbildes Galerija - "Seko" Sekot Atbloķēt Atbloķēt lietotāju @@ -61,14 +51,10 @@ Slēpt paroli Ir nepieciešama parole Izveidot kontu - Izveidot jaunu kontu - Ģenerēt jaunu atslēgu Ielādē kontu Atsvaidzināt - aprakstu uz - un attēlu uz Kanāls izveidots saņemtie ieraksti Noņemt @@ -82,14 +68,11 @@ Papildu drošībai variet šifrēt atslēgu ar paroli. Šī atslēga sāksies ar **ncryptsec1** virkni un to nevarēs izmantot bez šīs paroles. \n\nJa jūs aizmirsīsiet paroli, vairs nevarēsiet atgūt savu atslēgu. - Kļūda Pievienot jaunu kontu Konti Atlasīt kontu Pievienot jaunu kontu Pašreizējais konts - Ar privāto atslēgu - Tikai lasīšana, bez privātās atslēgas Autora ID Kopēt tekstu Dzēst @@ -97,15 +80,11 @@ @string/block_only Dzēst @string/block_only - Dzēst - @string/malware Iemesls Bloķēt un sūdzēties Bloķēt Grāmatzīmes - Aizvērt pēc - dienām Pievienot attēlu Pievienot video Pievienot dokumentu @@ -116,9 +95,7 @@ Tor iestatījumi Jā Nē - Sekot saraksts Ikona sarakstam - Izveidot jaunu sarakstu Jauns sekošanas saraksts Kolekcijas nosaukums Kolekcijas apraksts (neobligāti, pēc izvēles) @@ -133,8 +110,6 @@ Versija Valstis Valodas - Birkas - Autorizācija Birkas, kurām sekoju Apstiprinātie ieraksti Lietotnes iestatījumi @@ -147,10 +122,7 @@ Valoda Motīvs Nevar augšupielādēt - Noteikumi - Par mums Labi - Meklēt Lietotājvārds vai parādāmais vārds Profila attēls Nevarēja samaksāt rēķinu @@ -166,14 +138,11 @@ Augšupielādes kļūda: %1$s Nevarēja lejupielādēt augšupielādēto multivides datni no servera Neizdevās augšupielādēt %1$s: %2$s - Neizdevās augšupielādēt: %1$s - Meklēt Paziņojumi Jauns ieraksts Paldies! Rediģēt ierakstu - Izmaiņu kopsavilkums @string/torrent_download Atskaņot lietotājvārdu ar skaņu Torrenta datne @@ -190,4 +159,5 @@ + diff --git a/amethyst/src/main/res/values-ne-rNP/strings.xml b/amethyst/src/main/res/values-ne-rNP/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-ne-rNP/strings.xml +++ b/amethyst/src/main/res/values-ne-rNP/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-nl-rNL/strings.xml b/amethyst/src/main/res/values-nl-rNL/strings.xml index 495b4a3396..a6c02fbb1d 100644 --- a/amethyst/src/main/res/values-nl-rNL/strings.xml +++ b/amethyst/src/main/res/values-nl-rNL/strings.xml @@ -32,8 +32,6 @@ Overige Pesterijen Geweld - Onbekend - Relay-icoon Onbekende auteur Tekst kopiëren Auteur-ID kopiëren @@ -48,12 +46,9 @@ Meld spam / oplichting Meld impersonatie - Rapporteer expliciete inhoud Rapporteer illegaal gedrag Rapporteer malware - Rapporteer moderator Malware - Moderator Je gebruikt een alleen-lezen account. Log in met een privésleutel om te kunnen reageren. Je gebruikt een alleen-lezen account. Log in met een privésleutel om berichten te boosten. Je gebruikt een alleen-lezen account. Log in met een privésleutel om berichten te liken. @@ -67,17 +62,14 @@ Je gebruikt een alleen-lezen account. Log in met een privésleutel om te ontvolgen. Je gebruikt een alleen-lezen account. Log in met een privésleutel om woorden of zinnen te verbergen. Je gebruikt een alleen-lezen account. Log in met een privésleutel om woorden of zinnen te tonen. - Je gebruikt een alleen-lezen account. Log in met een privésleutel om instellingen te wijzigen. Je gebruikt een alleen-lezen account. Log in met een privésleutel om te uploaden. Je gebruikt een alleen-lezen account. Log in met een privésleutel om berichten te ondertekenen. Ongeautoriseerde decodering De signer heeft decodering niet toegestaan. Schakel NIP-44-decodering in in je signer-app en probeer het opnieuw. Signer niet gevonden Is de signer-app verwijderd? Controleer of de signer geïnstalleerd is en dit account ondersteunt. Log opnieuw in. - Signer gedroeg zich mis Externe signer heeft een onjuiste payload geretourneerd voor dit verzoek. Er kan een bug zitten in Amethyst of in de signer. Zaps - Weergaven Boost geboost bewerkt @@ -90,9 +82,7 @@ Toevoegen "reageert op" " en " - "in kanaal" Profielbanner - Betaling geslaagd Fout bij verwerken foutmelding "Volgend" "Volgers" @@ -158,7 +148,6 @@ Onvoldoende saldo in een mint die deze ontvanger accepteert. Vul eerst je Cashu-wallet aan. Besteedbaar voor deze ontvanger: %1$s sats Netwerkkosten - je wallet-app Transactie: %1$s Lightning-tips Bericht aan ontvanger @@ -172,16 +161,13 @@ Zichtbaar voorvoegsel 😎 Toevoegen aan bericht - "Fout bij laden preview voor %1$s: %2$s" "Preview-afbeelding voor %1$s" Artikel - Nieuw kanaal Kanaalnaam Mijn geweldige groep Afbeeldings-URL Afbeeldings-URL (optioneel) Omschrijving - Geen omschrijving gevonden "Over ons…" Waar denk je aan? Schrijf een bericht… @@ -191,42 +177,25 @@ Aanmaken Hernoemen Annuleren - Uploaden van afbeelding mislukt - Relay-adres - Berichten - Bytes Fout Fouten Percentage succesvolle verbindingen met deze relay - Aantal verbindingsfouten in deze sessie - Startpagina - Privéberichten - Publieke chats - Globale feed - Zoeken Zoek en voeg gebruiker toe - Gebruiker toevoegen Relay toevoegen - Naam - Naam (voor @tagging) Mijn @naam Weergavenaam Mijn weergavenaam Struisvogel McAwesome Welkom Struisvogel! Gebruikersnaam - Mijn gebruikersnaam Over mij Profielfoto-URL Banner-URL Website-URL Voornaamwoorden - Lightning-adres - LN URL (verouderd) Bron-relays kunnen verouderd zijn Waarschuwing verouderde relay Opslaan op telefoon - Opslaan in galerij Afbeelding opgeslagen in galerij Video download gestart… Media download gestart… @@ -243,15 +212,12 @@ Foto maken Video opnemen Spraakbericht opnemen - Spraakbericht opnemen Druk en houd vast om een spraakbericht op te nemen Opnieuw opnemen Opnemen Opnemen %1$s - Uploaden… Uploadfout Spraakbericht uploaden mislukt - Onverwachte uploadstatus NIP-95 wordt nog niet ondersteund voor spraakberichten Spraakbericht uploaden mislukt: %1$s Geen @@ -263,8 +229,6 @@ Deze gebruiker heeft geen Lightning-adres ingesteld om sats te ontvangen "hier reageren…" In deze chat - Kopieert note-ID naar klembord om te delen - Kopieer kanaal-ID (note) naar klembord Past kanaal-metadata aan Deelnemen Bekend @@ -278,7 +242,6 @@ Reacties Wederzijds Galerij - "Volgend" "Rapporten" "%1$s rapporten" Meer opties @@ -286,11 +249,8 @@ Website Lightning-adres Kopieert je privésleutel (nsec) naar het klembord voor back-up - Privésleutel kopiëren naar klembord Toon QR-code van privésleutel Toon versleutelde QR-code van privésleutel - Kopieert publieke sleutel naar klembord om te delen - Publieke sleutel (npub) kopiëren naar klembord Stuur privébericht Bewerkt gebruikers-metadata Volgen @@ -319,8 +279,6 @@ Hoe mogen we je noemen? Heb je nog geen Nostr-account? Heb je al een Nostr-account? - Nieuw account aanmaken - Nieuwe sleutel genereren Feed laden… Account laden… versleuteld @@ -335,13 +293,7 @@ Poll openen Feed is leeg. Vernieuwen - aangemaakt - met omschrijving van - en afbeelding - heeft de chatnaam gewijzigd in Nieuw chatprofiel: - omschrijving naar - en afbeelding naar Verlaten Ontvolgen Kanaal aangemaakt @@ -372,7 +324,6 @@ Nostr-adres nooit nu - seconden u m d @@ -380,7 +331,6 @@ Godslastering / haatspraak Haatspraak rapporteren Naaktheid / porno rapporteren - anderen Alle bekende markeren als gelezen Alle nieuwe markeren als gelezen Alles markeren als gelezen @@ -394,8 +344,6 @@ Biometrische authenticatie mislukt Biometrie kon de eigenaar van dit toestel niet verifiëren. Biometrie kon de eigenaar niet verifiëren. Fout: %1$s - Fout - "Gemaakt door %1$s" "Badge-awardafbeelding voor %1$s" Badge-awardafbeelding Je hebt een nieuwe badge-award ontvangen @@ -403,7 +351,6 @@ Note-tekst gekopieerd naar klembord Gebruikers-ID (@npub…) gekopieerd naar klembord Note-ID (@note1…) gekopieerd naar klembord - Tekst selecteren "<Kan privébericht niet ontsleutelen>\n\nJe werd genoemd in een privégesprek tussen %1$s en %2$s." Nieuw account toevoegen Accounts @@ -415,8 +362,6 @@ Account selecteren Nieuw account toevoegen Account activeren - Heeft privésleutel - Alleen-lezen (geen privésleutel) Terug Selecteren Browserlink delen @@ -441,14 +386,12 @@ Discussie dempen Discussie dempen opheffen Rapporteren - Verwijderen Niet meer tonen Spam of oplichting Godslastering of haatdragend gedrag Kwaadwillige imitatie Naaktheid of gevoelige inhoud Illegaal gedrag - Malware Als je een gebruiker blokkeert, wordt zijn inhoud in jouw app verborgen. Jouw berichten blijven zichtbaar voor iedereen, inclusief geblokkeerde gebruikers. Misbruik melden @@ -476,7 +419,6 @@ Geplande tijd kiezen Inplannen voor… Wordt gepubliceerd over %1$s - Had %1$s geleden gepubliceerd moeten worden Tijd Bericht inplannen Inplannen annuleren @@ -551,7 +493,6 @@ Auteur Verzoeken Goedkeuringen - Geen communities gevonden die aan dit filter voldoen. Verifieerbare regels (optioneel) Publiceert een machine-leesbaar regelsdocument (NIP-9B) naast de community. Clients die dit ondersteunen blokkeren berichten die niet voldoen voordat ze worden verzonden. Toegestane event-kinds @@ -580,26 +521,15 @@ WoT-poort toevoegen Globale max. event-grootte (optioneel) Bytes — laat leeg voor geen globale limiet. - Ontvangen - Van mij - Toegekend - Ontdekken Nieuwe badge - Badge bewerken Badge toekennen Accepteren Afwijzen Verwijderen van profiel - Badge-ID (d-tag) - bravery, contributor-2025… Naam Leesbare badge-naam Omschrijving Waarom wordt deze badge toegekend? - Afbeeldings-URL (1024×1024) - https://voorbeeld.nl/badge.png - Thumbnail-URL (optioneel) - https://voorbeeld.nl/badge-thumb.png Afbeelding uploaden Kies een vierkante afbeelding als gezicht van je badge. Badge laden… @@ -608,7 +538,6 @@ Verwijderen Naamloze badge Toegekend aan %1$d - Je hebt een badge ontvangen Profielbadges Badges · %1$d Kies welke van de ontvangen badges op je profiel verschijnen. @@ -646,9 +575,6 @@ Deel je workouts Laat Amethyst voltooide workouts lezen uit Health Connect (Samsung Health, Google Fit, Fitbit, Garmin…) en stel voor om ze als bericht te delen. Verbinden - Nieuwe workout gedetecteerd - Delen - Sluiten Van Health Connect Hardlopen Wandelen @@ -666,12 +592,10 @@ Platformen Onderwerpen Laatste release - Reacties Wees de eerste die reageert. door Toon oudere releases Verberg oudere releases - Kalenders Shorts Publieke chats Volgpakketten @@ -681,18 +605,14 @@ een Nest Podium Wachten op sprekers… - Publiek Hand opsteken Hand laten zakken Audio verbinden - Verbinding verbreken Dempen Dempen opheffen - Verbinden… Ruimte oplossen Transport openen Audio onderhandelen - Audio verbonden Opnieuw verbinden… Opname beluisteren Kon bericht niet versturen @@ -700,9 +620,7 @@ Deze ruimte sluiten? Alle deelnemers worden losgekoppeld. De ruimte wordt als GESLOTEN weergegeven in de feed. Ruimte sluiten - Kies een toekomstige starttijd. Audio mislukt: %1$s - Audio is niet beschikbaar voor deze ruimte Praten Podium verlaten Microfoon dempen @@ -710,7 +628,6 @@ Live gaan… Uitzending mislukt: %1$s Dempen mislukt: %1$s - Toegang tot microfoon is vereist om te praten in deze ruimte. Geen toestemmingen Nests Houdt audio afspelen terwijl een ruimte open is. @@ -721,7 +638,6 @@ Join nest Host Openen - Recent chat Niemand is nu in de ruimte. %1$d luisteren Host @@ -749,8 +665,6 @@ Publiek Handen Nog niemand in het publiek. - Versturen - Zeg iets… Nog geen berichten. Wees de eerste die chat. Reageren Ruimte bewerken @@ -784,7 +698,6 @@ Actie mislukt De actie kon niet worden voorbereid. Ruimte delen - Minimaliseren Minimaliseren om te blijven luisteren Audio onderbroken Ruimte laden… @@ -817,7 +730,6 @@ Kies op welke MoQ-hostservers Amethyst je nests publiceert. De eerste wordt standaard gebruikt bij het starten van een nieuwe space. Jouw servers Opgeslagen als kind-10112 vervangbaar event zodat andere clients je voorkeur kunnen lezen. - Nest-server toevoegen Relay (WebTransport) URL Auth (JWT mint) URL Toevoegen @@ -830,12 +742,10 @@ Server verwijderen Nog geen nest-servers. Voeg er een toe of kies een aanbevolen server. Video\'s - Artikelen Muziek Afspeellijsten Afleveringen Afleveringen bekijken - Afleveringen Nog geen afleveringen gevonden %1$d aflevering @@ -847,8 +757,6 @@ Titel van het nummer Artiest Naam artiest - Audio-URL - Cover-afbeelding URL (optioneel) Album (optioneel) Duur in seconden (optioneel) Songteksten of credits (optioneel) @@ -858,7 +766,6 @@ Toevoegen aan afspeellijst Je hebt nog geen afspeellijsten. Gebruik het veld hierboven om er een aan te maken. Alle afspeellijsten beheren - Nieuwe afspeellijst Naam van de afspeellijst Aanmaken (naamloze afspeellijst) @@ -893,9 +800,6 @@ Bladwijzerlijst verwijderen Berichten bekijken Artikelen bekijken - Links bekijken - Hashtags bekijken - Je hebt nog geen bladwijzerlijsten. Tik op de + knop om er een te maken. Hashtag-sets Je hebt nog geen interest-sets. Tik op de nieuwe knop om er een te maken. Nieuwe interest-set @@ -914,7 +818,6 @@ Privéberichten (%1$s) Openbare berichten Openbare berichten (%1$s) - Privéartikelen Privéartikelen (%1$s) Openbare artikelen Openbare artikelen (%1$s) @@ -941,16 +844,6 @@ Bladwijzerlijst-metadata is zichtbaar voor iedereen op Nostr. Alleen privéleden zijn versleuteld. Verplaatsen naar publiek Verplaatsen naar privé - Wallet Connect Service - Hiermee kun je zaps betalen zonder de app te verlaten. Houd dit geheim en gebruik bij voorkeur privé-relays. - Wallet Connect publieke sleutel - Wallet Connect Relay - Wallet Connect Secret - Secret tonen - nsec / hex privésleutel - Verbonden - Niet verbonden - Geavanceerd: handmatig verbindingsgegevens invoeren Snelle zap-bedragen Worden getoond bij het indrukken van de zap-knop. Tik op een bedrag om te verwijderen. Leeg laten opent steeds het invoerscherm. In plaats daarvan on-chain versturen @@ -981,14 +874,8 @@ Wallet verbinden Relay-feed bekijken Bedrag in sats - Poll plaatsen - Verplichte velden: - Zap-ontvangers - Hoofdvraag van de poll… - Optie Optie %s Poll-optiebeschrijvingen - Optionele velden: Minimum zap-bedrag Maximum zap-bedrag Consensusdrempel @@ -997,11 +884,8 @@ Meerdere keuzes Sluitingsdatum & -tijd Poll sluit over %1$s - Sluit na - dagen Kan niet stemmen Deze poll is gesloten voor nieuwe stemmen - Zap-bedrag Bij dit type poll is slechts één stem per gebruiker toegestaan. "Zoeken naar bericht %1$s" Zap versturen @@ -1037,11 +921,8 @@ Non-Zap Geen spoor binnen Nostr, alleen in Lightning Anoniem plaatsen - Plaatsen als een wegwerp-identiteit. Je account wordt niet gekoppeld aan dit bericht. - Dit antwoord wordt geplaatst vanuit een nieuwe anonieme identiteit. Bestandsserver Kies een server om dit bestand naar te uploaden - LnAddress of @Gebruiker Mediaservers Stel je voorkeur mediaservers in. Lokale Blossom-cache gebruiken @@ -1050,10 +931,8 @@ Geen lokale cache gedetecteerd op poort 24242. Alleen profielfoto\'s cachen Beperk de lokale cache tot profielfoto\'s. Feed-afbeeldingen en video\'s worden direct van de originele servers opgehaald. - Je hebt nog geen NIP-96-servers ingesteld. Je kunt de standaardlijst van Amethyst gebruiken of zelf servers toevoegen. Je hebt nog geen Blossom-servers ingesteld. Je kunt de standaardlijst van Amethyst gebruiken of zelf servers toevoegen. Aanbevolen mediaservers - Ingebouwde mediaservers Standaardlijst van Amethyst. Je kunt ze individueel of allemaal toevoegen. Standaardlijst gebruiken Mediaserver toevoegen @@ -1076,36 +955,21 @@ Hashen Klaar Fout - Jouw relays (NIP-95) - Bestanden worden geüpload en gehost door je eigen relays. Geen afhankelijkheid van derden. Zorg dat je een NIP-95-relay in je lijst hebt. Privacyopties - Orbot/Tor - Verbinden via Tor (Orbot) Aanpassen Tor-instellingen - Tor uitschakelen? - Je gegevens worden dan direct via het normale internet verstuurd. Ja Nee - Volglijst Iedereen Volg alle gebruikers Standaard volglijst - Volgt via proxy In de buurt Globaal Gecureerd - Schaken Van mij Gedempte lijst Volglijsten Dit zijn lijsten voor eigen gebruik. Je kunt gebruikers privé of publiek volgen. - Gelabelde bladwijzers - Algemene bladwijzers - Publiek - Privé - Gemengd - Je hebt nog geen volglijsten.\nTik hieronder om te vernieuwen of maak een nieuwe aan. Nieuw Auteur toevoegen aan volglijst Gebruiker toevoegen of verwijderen uit lijsten, of een nieuwe lijst maken met deze gebruiker. @@ -1114,23 +978,9 @@ %1$s is een privé-lid Toevoegen als openbaar lid Toevoegen als privé-lid - Openbare leden - Privéleden - Openbare profielen - Privéprofielen - lid - leden - Geen leden Leeg - %1$s staat niet in deze lijst %1$s is geen lid Jouw lijsten en %1$s - Jouw lijsten - Geen volglijsten gevonden. Vernieuw of maak een nieuwe aan via het menu. - Fout bij ophalen: %1$s - Nieuwe lijst maken - Nieuwe lijst met %1$s-lidmaatschap - Maakt een nieuwe volglijst en voegt %1$s toe als %2$s-lid. Nieuwe volglijst Nieuw volgpakket Lijst kopiëren/klonen @@ -1150,7 +1000,6 @@ Je hernoemt naar… Standaardpoort is 9050 - ## Verbinden via Tor met Orbot\n\n1. Installeer [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android)\n2. Start Orbot\n3. Controleer de Socks-poort (standaard 9050)\n4. Pas indien nodig de poort aan\n5. Voer de Socks-poort hier in\n6. Activeer Tor Orbot Socks-poort Interne Tor-engine gebruiken Gebruik de ingebouwde versie van Orbot @@ -1192,8 +1041,6 @@ Verberg je IP bij alle verbindingen Maak je eigen configuratie Ongeldige poort - Orbot gebruiken - Orbot/Tor uitschakelen Privéberichten Melding bij nieuw privébericht Ontvangen zaps @@ -1250,12 +1097,8 @@ Bluetooth Spraak Video - Wachten tot anderen deelnemen… Deelnemer toevoegen Gebruikers zoeken… - Kan gesprek niet starten - Kan gesprek niet accepteren - Aanmaken oproepsessie mislukt Toestemming nodig Amethyst heeft toegang tot de microfoon nodig om een spraakoproep te starten. Schakel dit in bij de app-instellingen. Amethyst heeft toegang tot camera en microfoon nodig om een video-oproep te starten. Schakel dit in bij de app-instellingen. @@ -1289,24 +1132,13 @@ Android kan relay-verbindingen op de achtergrond beperken. Schakel batterij-optimalisatie uit voor Amethyst voor betrouwbare meldingen. Nu oplossen Melden: - Deelnemen aan gesprek - Gebruiker of groeps-ID - npub, nevent of hex - Aanmaken - Deelnemen Vandaag Inhoudswaarschuwing Waarschuwing: %1$s Dit bericht kan aanstootgevende of verontrustende inhoud bevatten - Altijd gevoelige inhoud verbergen - Altijd gevoelige inhoud tonen - Altijd inhoudswaarschuwingen tonen Verbergen Tonen Waarschuwen - Aanbevolen: - Spam van onbekenden filteren - Waarschuwen bij rapportages van volgers Spamfilter Verbergt identieke berichten van onbekenden die 5 keer of vaker voorkomen Client-tag toevoegen aan mijn events @@ -1338,22 +1170,17 @@ Aantal bytes verstuurd naar deze relay (filters + events) Aantal bytes ontvangen van deze relay (filters + events) Opgeslagen berichten - Fout bij ophalen relay-informatie van %1$s Eigenaar Gebruikt door Service-sleutel - Draait op %1$s - Draait op %1$s (%2$s) Versie Software Contact Ondersteunde NIPs Ondersteunde Grasps - Toegangskosten Toegang Abonnement Publicatie - Betalingen %1$s Betaallink Doelgroep Beleid & links @@ -1361,7 +1188,6 @@ Beperkingen Landen Talen - Tags Onderwerpen Alle landen Alle talen @@ -1374,63 +1200,47 @@ Open Lezen Schrijven - RTT Netwerk Type Ondersteunde NIPs Vereisten - Laatste controle %1$d ms Geaccepteerde kinds Locatie Actieve abonnementen - Wachtende outbox-berichten REQ-abonnementen (%1$d) COUNT-abonnementen (%1$d) Outbox-berichten (%1$d) - Geen actieve abonnementen voor deze relay %1$d auteurs %1$d IDs sinds %1$s tot %1$s limiet %1$d - Berichtlengte - Abonnementen - Filters - Abonnements-ID lengte Minimumvoorvoegsel Maximum event-tags - Inhoudlengte Maximum inhoudlengte Verwerpt ouder dan Accepteert tot %1$s in de toekomst %1$s geleden - %1$s zeros %1$s bits Berichtbehoud Inhoudsgrootte Connectiviteit Toegangsbeheer Minimum PoW - Authenticatie Authenticatie vereist - Betaling Betaling vereist Maximum berichtlengte Maximum abonnementen Maximum filters per abonnement Maximumlimiet (retournerende berichten) - Standaardlimiet (retournerende berichten) Maximum Sub-ID-lengte Cashu-token Inwisselen - Naar Zap-wallet sturen - Openen in Cashu-wallet Token kopiëren Openen in andere app Geen Lightning-adres ingesteld - Token gekopieerd naar klembord LIVE OFFLINE BEËINDIGD @@ -1479,7 +1289,6 @@ Marmot-status gereset. Marmot-status resetten mislukt: %1$s Altijd - Alleen wifi Alleen onbeperkt wifi Nooit Volledig @@ -1504,7 +1313,6 @@ Kies de stijl van berichten Galerijstijl Kies de stijl van de profielgalerij - Afbeelding laden Spammers Gedempt. Tik voor geluid Geluid aan. Tik voor dempen @@ -1516,18 +1324,13 @@ Nostr-adres geverifieerd Verificatie Nostr-adres mislukt Nostr-adres controleren… - Alles selecteren/deselecteren Standaard Standaardinstellingen herstellen - Selecteer een relay om verder te gaan - Zaps doorsturen naar: - Ondersteunende clients sturen zaps naar dit adres/profiel in plaats van naar jou. Locatie weergeven als Voegt een geohash van je locatie toe. Mensen weten dan dat je binnen circa 5 km bent. Alleen locatie-exclusief bericht Alleen volgers van de locatie zien dit bericht. Alleen hashtag-exclusief bericht - Alleen volgers van de hashtag zien dit bericht. Reageer op een website Reageer op een externe bron %1$d min lezen @@ -1535,13 +1338,9 @@ Geen locatiemachtigingen Voegt een waarschuwing toe voor gevoelige of NSFW-inhoud. Reden (optioneel) - Nieuwe functie - Deze modus gebruikt NIP-17. Dit is nog nieuw en niet alle clients ondersteunen het. Zorg dat de ontvanger een compatibele client gebruikt. - Activeren Publiek Groep Nieuwe openbare of besloten groep - Relay Privé Aan Onderwerp @@ -1553,9 +1352,6 @@ Uitleg aan leden Beschrijf het doel van deze groep… Plakken vanaf klembord - Ongeldige NIP-47 URI - De URI %1$s is geen geldige NIP-47 login-URI. - Verbinden met nieuwe NWC-wallet Geen wallet gevonden Amethyst kon geen wallet-apps vinden die Nostr Wallet Connect (NWC) ondersteunen.\n\nWat je kunt doen:\n1. Controleer of je wallet NWC ondersteunt.\n2. Maak in je wallet een nieuwe NWC-verbinding aan.\n3. Kopieer de verbinding-URI of scan de QR-code hier. Taal van de app-interface @@ -1564,7 +1360,6 @@ Video\'s en GIFs automatisch afspelen Video\'s automatisch afspelen wanneer zichtbaar op het scherm URL-voorbeelden automatisch tonen - Wanneer afbeeldingen laden Stack kopiëren Kopiëren naar klembord nprofile kopiëren naar klembord @@ -1576,49 +1371,26 @@ Media toegevoegd Media toegevoegd aan je profielgalerij Aangemaakt op - Regels - Over ons Richtlijnen Moderators Inloggen met Amber Status bijwerken - Geen Lightning-wallets gevonden Stemmen wegen zwaarder naarmate het zap-bedrag hoger is. Stel een minimum in om spam te voorkomen en een maximum om dominante stemmen te voorkomen. Kan zap niet versturen Bericht de gebruiker Bericht %1$s OK - Kan %1$s niet bereiken: %2$s - Fout bij samenstellen NIP-11 URL voor %1$s: %2$s - Kan %1$s niet bereiken: %2$s - Kan resultaat van %1$s niet verwerken: %2$s - Relay weigert verzoek %1$s: %2$s - Kan %1$s niet bereiken: %2$s - Kan resultaat van %1$s niet verwerken: %2$s - %1$s mislukt met code %2$s - Actief voor: - Startpagina - Privéberichten - Chats - Globaal - Zoeken Zaps delen en doorsturen Ondersteunende clients delen zaps met de hier toegevoegde gebruikers in plaats van alleen met jou. Zoek en voeg gebruiker toe Gebruikersnaam of weergavenaam Ontbrekende Lightning-configuratie Gebruiker %1$s heeft geen Lightning-adres ingesteld om sats te ontvangen - Percentage - 25 - Zaps delen met - Zaps doorsturen naar - Geen Lightning-wallets gevonden Betaald Wallet %1$s Fout bij openen signer-app De signer-app kon niet worden gevonden. Controleer of deze nog geïnstalleerd is. Ondertekenverzoek afgewezen - Ondertekenverzoek afgewezen Zorg dat de signer-app dit verzoek heeft goedgekeurd. Geen wallet gevonden om Lightning-invoice te betalen (fout: %1$s). Installeer een Lightning-wallet om zaps te kunnen gebruiken. Geen wallet gevonden om Lightning-invoice te betalen. Installeer een Lightning-wallet om zaps te kunnen gebruiken. @@ -1634,40 +1406,23 @@ Selecteer een optie Invoice kon niet betaald worden Opname mislukt - Kon Wallet Connect niet instellen - Fout bij verwerken NIP-47 verbindingsstring. Controleer of deze correct is volgens je wallet-provider: %1$s. Fout: %2$s - Fout bij verwerken NIP-47 verbindingsstring. Controleer of deze correct is volgens je wallet-provider: %1$s. Cashu-inwisselen mislukt Mint geeft de volgende foutmelding: %1$s - Deze Cashu-tokens zijn al uitgegeven. Cashu ontvangen %1$s sats zijn naar je wallet gestuurd (kosten: %2$s sats). Geen compatibele Cashu-wallet gevonden Kon invoice niet ophalen van de server van de ontvanger Je wallet-connect provider gaf de volgende fout: %1$s - Kon geen verbinding maken met Tor Tor verbindt niet Amethyst kon Tor niet volledig opstarten. Gebruik een normale (niet-Tor) verbinding zodat de feed kan laden? We onthouden dit voor het komende uur en proberen daarna Tor opnieuw. Normale verbinding gebruiken Blijven wachten - Kon relay-document niet downloaden Kon LNURL niet samenstellen vanuit Lightning-adres \"%1$s\". Controleer de instellingen van de gebruiker. - De Lightning-service van de ontvanger op %1$s is niet beschikbaar. Dit werd berekend vanuit Lightning-adres \"%2$s\". Fout: %3$s. Controleer of de server online is en het adres correct is. - Kon %1$s niet oplossen. Controleer je verbinding, of de server online is en of Lightning-adres %2$s correct is. - Kon %1$s niet oplossen. Controleer je verbinding, of de server online is en of Lightning-adres %2$s correct is.\n\nUitzondering: %3$s - Kon invoice niet ophalen van %1$s Kon invoice niet ophalen van %1$s: %2$s - Fout bij verwerken JSON van Lightning-adres. Controleer de Lightning-instellingen van de gebruiker. Fout bij verwerken JSON van %1$s. Controleer de Lightning-instellingen van de gebruiker. - Callback-URL niet gevonden in de Lightning-adresconfiguratie van de gebruiker. Callback-URL niet gevonden in het antwoord van %1$s. - Fout bij verwerken JSON van Lightning-adres invoice. Controleer de Lightning-instellingen van de gebruiker. - Fout bij verwerken JSON van invoice van %1$s. Controleer de Lightning-instellingen van de gebruiker. Onjuist invoice-bedrag (%1$s sats) van %2$s. Het had %3$s moeten zijn. Kon geen Lightning-invoice aanmaken voor het versturen van de zap. De wallet van de ontvanger gaf de volgende fout: %1$s - Kon geen Lightning-invoice aanmaken. Bericht van %1$s: %2$s - Kon geen Lightning-invoice aanmaken. Element \"pr\" niet gevonden in JSON. - Kon geen Lightning-invoice aanmaken van %1$s: element \"pr\" niet gevonden in JSON. Alleen-lezen gebruiker Geen reacties ingesteld Selecteer een UnifiedPush-app @@ -1683,13 +1438,11 @@ Stuur de verkoper een bericht Hallo %1$s, is dit nog beschikbaar? Hallo, is dit nog beschikbaar? - Verkoop een item Titel iPhone 13 Staat Categorie Prijs (in sats) - 1000 Locatie Stad, provincie, land Nieuw @@ -1718,20 +1471,13 @@ Anders Uploaden van media mislukt Kon gecomprimeerd bestand niet openen - Fout bij comprimeren media: %1$s Uploadfout: %1$s Server gaf geen URL terug na upload Kon geüploade media niet downloaden van server Kon gedownload bestand niet controleren na upload: %1$s - Kon lokaal bestand niet voorbereiden voor upload: %1$s Uploaden naar %1$s mislukt: %2$s - Media uploaden mislukt: %1$s Media verwijderen mislukt: %1$s Media is te groot voor NIP-95 - Kon thumbnail niet laden - Kon header-informatie niet voorbereiden: %1$s - Compressie geannuleerd - Compressie leverde geen bestand op Bestanden versleutelen Versleutel bestanden voordat ze worden geüpload. Sommige servers accepteren geen versleutelde bestanden op gratis accounts. Versleutelde upload mislukt @@ -1757,24 +1503,16 @@ Upload geannuleerd Concept bewerken Inloggen met QR-code - Route Start - Zoeken Ontdekken Berichten Meldingen - Globaal Shorts - Afbeeldingen Schaken Wallet - Saldo Verzenden Ontvangen Transacties - Geen wallet verbonden - Stel Nostr Wallet Connect (NWC) in via je zap-instellingen om de wallet te gebruiken. - Wallet instellen sats Plak een BOLT-11-invoice Betalen @@ -1801,8 +1539,6 @@ Dit verwijdert de wallet-verbinding. Je kunt hem later altijd weer toevoegen. Wallet-naam Mijn wallet - Jouw wallets - Wallets beheren Geen wallets verbonden Verbind een of meerdere NWC-wallets om betalingen te verzenden en ontvangen. NWC-verbinding toevoegen @@ -1810,10 +1546,6 @@ Opslaan Hernoemen Wallet hernoemen - Bewerken - Ongeldige NWC-verbinding-URI - Omhoog verplaatsen - Omlaag verplaatsen Onchain-transacties Geen on-chain adres beschikbaar voor dit account. Geen chain-backend geconfigureerd. @@ -1882,17 +1614,13 @@ Betaling verstuurd (%1$d van %2$d ontvangstbewijs gepubliceerd), maar het volgende ontvangstbewijs kon niet worden gepubliceerd Betaling verstuurd (%1$d van %2$d ontvangstbewijzen gepubliceerd), maar het volgende ontvangstbewijs kon niet worden gepubliceerd - Beveiligingsfilters Volgers importeren Nieuw bericht Nieuwe short (afbeelding/video) Nieuwe community-notitie Nieuw product - Nieuwe geo-exclusieve post Nieuw artikel Nieuwe poll - Nieuwe Zap-poll - Nieuwe gewone poll Nieuwe afbeelding Nieuw agenda-evenement Agenda-evenement bewerken @@ -1905,8 +1633,6 @@ Dag Aankomend Verleden - Nog geen aankomende of verleden agenda-evenementen van je geselecteerde feed. - Nog geen agenda-collecties. Je agenda is leeg Evenementen gedeeld door mensen die je volgt verschijnen hier. Tik op de + knop om er zelf een aan te maken. Nog geen collecties @@ -1933,8 +1659,6 @@ Volgende week Vorige dag Volgende dag - Geen evenementen op deze dag - Geen evenementen Doorgaan Dag %1$d van %2$d Toevoegen aan telefoon-agenda @@ -1992,7 +1716,6 @@ De gekozen afbeelding kon niet worden geüpload. Probeer opnieuw of plak een URL. Deelnemers (%1$d) Zoek naam, npub of nip-05 - Voer een geldige npub… of 64-karakter hex pubkey in. Deelnemer verwijderen Agenda-herinneringen Herinneringen versturen @@ -2009,10 +1732,7 @@ Evenementdetails Nieuwe short video Nieuwe lange video - Titel Samenvatting (optioneel) - Cover-afbeelding URL (optioneel) - Schrijf je artikel in markdown… Voorbeeld Bewerken Header-afbeelding toevoegen @@ -2095,18 +1815,14 @@ Relay %1$s Relay-lijst uitvouwen Notitie-opties - Relay-selectiemenu Poll Poll uitschakelen Bitcoin-invoice Bitcoin-invoice annuleren - Verkoop annuleren Zapraiser toevoegen Zapraiser annuleren Locatie toevoegen Locatie verwijderen - Zap-splitsing toevoegen - Zap-splitsing annuleren Inhoudswaarschuwing toevoegen Inhoudswaarschuwing verwijderen Vervaldatum toevoegen @@ -2121,11 +1837,8 @@ Ongeldig adres Amethyst ontving een ongeldige URI: %1$s DM-inbox relays - Via relays: %1$s - Normale relays gebruiken Stel je privé-inbox relays in Deze instelling vertelt anderen via welke relays ze privéberichten naar je kunnen sturen. Zonder deze mis je mogelijk berichten. - Goede opties zijn:\n - inbox.nostr.wine (betaald)\n - you.nostr1.com (persoonlijke relays - betaald) Goede opties zijn:\n - auth.nostr1.com (gratis)\n - inbox.nostr.wine (betaald)\n - relay.0xchat.com (gratis) Voeg 1 tot 3 relays toe als privé-inbox. Deze relays moeten berichten van iedereen accepteren, maar dienen alleen om berichten te downloaden. Nu instellen @@ -2145,7 +1858,6 @@ Een speciale lijst voor meldingen is essentieel voor een goede Nostr-ervaring. Voeg 1 tot 3 relays toe die meldingen voor je ontvangen. Vermijd relays die betaling of autorisatie vereisen, anders mis je meldingen. Goede opties zijn:\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social - DM uploaden Relay-instellingen Relays herordenen Openbare thuis-relays @@ -2162,12 +1874,8 @@ Relays waar je MLS KeyPackages worden gepubliceerd (MIP-00). Andere gebruikers halen deze KeyPackages op om je uit te nodigen voor Marmot-groepchats. Voeg 1–3 relays toe die KeyPackage-events van jou accepteren en openbare leestoegang toestaan. Privé-relays Relays voor privé-gegevens zoals concepten en app-instellingen. Idealiter lokaal of met authenticatie. - Algemene relays - Amethyst gebruikt deze relays om berichten voor je te downloaden. Verbonden relays Huidig verbonden relays - Aanbevolen relays - Voeg deze relays toe aan je algemene lijst om berichten van aanbevolen gebruikers te ontvangen. Zoek-relays Relays die gebruikt worden voor zoeken en taggen. Moeten NIP-50 ondersteunen. Lokale relays @@ -2202,11 +1910,8 @@ Deze versie is aangeboden door: Versie %1$s Bedankt! - Max. limiet Beperkte schrijfrechten Geforked van - FORK - Git-repository: %1$s Web: Klonen: Openen @@ -2231,20 +1936,13 @@ Artikel bewerken Bericht bewerken Voorstel tot verbetering - Samenvatting van wijzigingen - Snelle correcties… Suggestie accepteren Video in popup starten Downloaden voor offline gebruik - Songteksten aan - Songteksten uit - Verzegeld bericht uit. Tik om aan te zetten. - Verzegeld bericht aan. Tik om uit te zetten. Verzenden Gebruikersnaam als audio afspelen Pushpin QR-code scannen - Navigeer naar externe wallet-provider Alby Datum selecteren Het is niet mogelijk om op een concept te reageren Het is niet mogelijk om een concept te citeren @@ -2286,23 +1984,18 @@ Onvoldoende opslagruimte Loop gedetecteerd Netwerk-authenticatie vereist - NIP-96 servers - Voeg zoveel servers toe als je wilt. Je kunt later kiezen welke gebruikt wordt bij uploaden. Blossom servers Voeg zoveel servers toe als je wilt. Je kunt later kiezen welke gebruikt wordt bij uploaden. NIP-96-server toevoegen Blossom-server toevoegen Alles verwijderen Weet je zeker dat je alle concepten wilt verwijderen? - Stack: Torrent-bestand Downloaden Kon bestand niet openen Geen torrent-apps geïnstalleerd om dit bestand te openen en te downloaden. Bericht bevat onvoldoende informatie om een magnet-link te maken. - Mijn lijsten/sets Mijn lijsten - Gebruikers Selecteer een lijst om de feed te filteren Feeds Hashtags @@ -2333,7 +2026,6 @@ Privébericht Openbaar bericht Chat-relay - De relay die alle gebruikers van deze chat gebruiken om verbinding te maken Afbeelding delen… Kan afbeelding niet delen. Probeer het later opnieuw. Video delen… @@ -2380,7 +2072,6 @@ Wil je het recente crashrapport naar Amethyst sturen via een DM? Er wordt geen persoonlijke informatie gedeeld. Verzenden Dit bericht verdwijnt over %1$s - Dit bericht verdwijnt over %1$d dagen Ondertekenaar selecteren Al in de lijst Privéleden @@ -2399,7 +2090,6 @@ Pakketnaam Nieuwe pakketnaam Pakketomschrijving - Nieuwe pakketomschrijving Lijst uitzenden Pakket uitzenden Lijst verwijderen @@ -2413,13 +2103,9 @@ Inklappen Uitklappen Opnieuw proberen mislukt (%1$d) - +%1$d meer uitzendingen - " (%1$d bezig)" - %1$d/%2$d relays Time-out Opnieuw proberen… Opnieuw proberen - Bekijken Sluiten %1$d/%2$d Uitzenden @@ -2445,7 +2131,6 @@ Opnieuw starten Accepteren Weigeren - Nieuw spel Nieuw schaakspel Spel laden… Spel niet gevonden @@ -2599,23 +2284,13 @@ Profiel om van te importeren zoeken, npub1…, alice@example.com Ondersteunt npub, nprofile, NIP-05, hex en Namecoin (.bit) - Volglijst opzoeken Tip %1$d accounts gevonden %1$d geselecteerd - Opgelost via Namecoin - Volgt nu %1$d accounts - Je feed is klaar. - Overslaan - Andere zoeken %1$d accounts volgen - Meer importeren - Doorgaan Voorlopig overslaan - Oplossen van %1$s… Volglijst ophalen… Geen volgers gevonden - %1$d accounts volgen… "Voer het profiel in van een vriend of community-leider. Je kunt npub, NIP-05-adres of een Namecoin-naam gebruiken (bijv. alice@example.bit)." Alles selecteren %1$d%% uptime @@ -2623,7 +2298,6 @@ Verbinding testen Servers testen… Verbonden - Mislukt Testresultaten Diagnostiek Laatste test @@ -2636,9 +2310,6 @@ Vertrouwen Weigeren Relay-synchronisatie - Relay-synchronisatie - Herpubliceer je berichten naar alle bekende relays om je outbox, inbox en DM-relays up-to-date te houden. Vereist Wi-Fi — dit kan veel data gebruiken. - Relay-synchronisatie openen… Wat doet dit? Deze tool scant alle relays die Amethyst kent en stuurt je berichten naar de juiste bestemmingen: Download alle berichten die je zelf hebt gemaakt en stuur ze naar je outbox-relays. @@ -2648,14 +2319,9 @@ Mobiele data gebruiken? Synchronisatie starten Toch starten (mobiele data) - Pauzeren - Hervatten - Opnieuw beginnen Annuleren Relays: %1$d / %2$d Berichten herverdeeld: %1$d nieuw van %2$d verzonden en %3$d ontvangen - Synchronisatie gepauzeerd - Voltooid: %1$d van %2$d relays — %3$d berichten herverdeeld tot nu toe. Tik op Hervatten om door te gaan. Synchronisatie voltooid %1$d berichten doorgestuurd naar bestemmingsrelays van %2$d ontvangen. %1$d berichten geaccepteerd als nieuw door bestemmingsrelays. @@ -2670,16 +2336,13 @@ verzonden %1$s ontvangen %1$s nieuw %1$s - geen berichten Bitcoin Explorer (OTS) - berichten berichten van jou berichten aan jou doorzoekbare berichten DM\'s profielen outbox-lijsten - relay-instellingen Laatst gezien %1$s geleden Laatst gezien op %1$s (%2$s geleden) Laatst gezien zojuist @@ -2750,7 +2413,6 @@ Zoeken naar apparaten op je wifi… HLS-upload - Publiceer multi-resolutie HLS naar je mediaserver Kies een video Je video wordt omgezet naar meerdere resoluties zodat kijkers soepel kunnen afspelen op elke verbinding. Wijzigen @@ -2765,10 +2427,6 @@ H.265 niet beschikbaar op dit apparaat — terugvallen op H.264. Rendities Bronresolutie: %1$d×%2$d - Produceert: %1$s - (%1$s overgeslagen — boven bron) - %1$d kbps - boven bron — wordt overgeslagen Publiceer HD-video Publiceert “%1$s”… Transcoderen %1$s @@ -2780,7 +2438,6 @@ Video gepubliceerd Je HD-video is live op Nostr. Er is iets misgegaan - Bericht bekijken Klaar Opnieuw proberen Pakket-acties @@ -2795,30 +2452,21 @@ Attestatie Geldig Ongeldig - Geaccepteerd - Afgewezen Verifiëren - Geverifieerd Ingetrokken Geldig vanaf %1$s Geldig tot %1$s Attestatieverzoek - Attestatie aanvragen voor een bericht Attestor-aanbeveling Aanbevolen voor kinds: Attestor-vaardigheid - Vaardig in verificatie van kinds: %1$s - Attesteert voor Vraagt attestatie aan voor Datumbereik Vanaf Tot Nu Alle tijd - Laatste sync: %1$s - Sinds laatste sync Web-bladwijzers - Nog geen web-bladwijzers. Tik op + om er een toe te voegen. Web-bladwijzer toevoegen Web-bladwijzer bewerken URL @@ -2857,13 +2505,10 @@ https://voorbeeld.nl/afbeelding.jpg Website-URL (optioneel) https://voorbeeld.nl - Deadline (optioneel) Deadline instellen Nieuw doel - Doel aanmaken Verzoek tot verdwijnen Vraag relays om al je gegevens permanent te verwijderen tot de geselecteerde datum. Dit is gebaseerd op NIP-62 en is in sommige jurisdicties juridisch bindend. - Selecteer een relay Doel-relays ALLE RELAYS Dit verzoek gaat naar ALLE relays om alles wat bij jouw sleutel hoort tot de geselecteerde datum te verwijderen. Dit bericht wordt zo breed mogelijk verspreid. Dit kan niet ongedaan worden gemaakt. @@ -2879,7 +2524,6 @@ Datum selecteren Tijd selecteren Geschiedenis van verdwijnverzoeken - Vernieuwen Dit zijn je eerdere verzoeken tot verdwijnen die gevonden zijn op verbonden relays. Relays die hierin genoemd worden, zouden geen gegevens van jou van voor die datum meer mogen bevatten. Geen verdwijnverzoeken gevonden Je hebt nog geen verzoeken tot verdwijnen verstuurd. @@ -2922,7 +2566,6 @@ Bericht blokkeren Kind toestaan IP-adres blokkeren - Pubkey (hex) Bericht-ID (hex) Kind-nummer IP-adres @@ -2933,7 +2576,6 @@ Relay-naam Relay-omschrijving Relay-pictogram URL - Relay beheren Beheren Leden Leden van %1$s @@ -3004,7 +2646,6 @@ Emoji-pakket-acties Mijn emoji-pakketten Emoji\'s - Emoji-sets bekijken Privé Privé-emoji Openbare emoji\'s zijn zichtbaar voor iedereen en verschijnen in je reactiemenu en \":\" autocomplete-picker wanneer dit pakket in je emoji-lijst staat. @@ -3029,4 +2670,10 @@ Nowhere-drop Nowhere-kunst Nowhere-forum + + De Lightning-service van de ontvanger op %1$s is niet beschikbaar. Dit werd berekend vanuit Lightning-adres \"%2$s\". Fout: %3$s. Controleer of de server online is en het adres correct is. + Kon %1$s niet oplossen. Controleer je verbinding, of de server online is en of Lightning-adres %2$s correct is.\n\nUitzondering: %3$s + Fout bij verwerken JSON van invoice van %1$s. Controleer de Lightning-instellingen van de gebruiker. + Kon geen Lightning-invoice aanmaken. Bericht van %1$s: %2$s + Kon geen Lightning-invoice aanmaken van %1$s: element \"pr\" niet gevonden in JSON. diff --git a/amethyst/src/main/res/values-nl/strings.xml b/amethyst/src/main/res/values-nl/strings.xml index d33b02be1e..b59e52574e 100644 --- a/amethyst/src/main/res/values-nl/strings.xml +++ b/amethyst/src/main/res/values-nl/strings.xml @@ -21,8 +21,6 @@ Illegaal gedrag Overige Pesterijen - Onbekend - Relay-icoon Onbekende auteur Kopieer tekst Kopieer auteur ID @@ -36,12 +34,9 @@ Meld spam / scam Meld impersonatie - Rapporteer expliciete inhoud Rapporteer illegaal gedrag Rapporteer malware - Rapporteer mod Malware - Mod Je gebruikt een publieke sleutel en publieke sleutels zijn alleen-lezen. Login met een geheime sleutel om te reageren Je gebruikt een publieke sleutel en publieke sleutels zijn alleen-lezen. Login met een geheime sleutel om berichten te boosten Je gebruikt een publieke sleutel en publieke sleutels zijn alleen-lezen. Login met een geheime sleutel om berichten te liken @@ -52,7 +47,6 @@ Je gebruikt een publieke sleutel en publieke sleutels zijn alleen-lezen. Login met een geheime sleutel om woorden en zinnen te verbergen Je gebruikt een publieke sleutel en publieke sleutels zijn alleen-lezen. Login met een geheime sleutel om woorden of zinnen te tonen Zaps - Aantal keer bekeken Boost geboost gewijzigd @@ -65,9 +59,7 @@ Toevoegen "reageert op " " en " - "in kanaal " Profielbanner - Betaling gelukt Fout bij het parsen van foutberichten " Volgend" " Volgers" @@ -89,9 +81,7 @@ Zichtbaar voorvoegsel 😎 Voeg toe aan bericht - "Error parsing preview voor %1$s : %2$s" "Voorbeeld kaartafbeelding voor %1$s" - Nieuw kanaal Kanaalnaam Mijn geweldige groep Afbeelding URL @@ -102,33 +92,18 @@ Opslaan Maken Annuleren - Uploaden afbeelding mislukt - Relay adres - Berichten - Bytes Fouten - Het nummer van verbindingsfouten in deze sessie - Startpagina - Privéberichten - Publieke chats - Globale feed - Zoeken Voeg relay toe - Naam Naam Mijn naam Struisvogel McAwesome Welkom Struisvogel! Gebruikersnaam - Mijn gebruikersnaam Over mij Profielfoto URL Banner URL Website URL Voornaamwoorden - LN Adress - LN URL (verouderd) - Opslaan in galerij Afbeelding opgeslagen in galerij Video download is gestart… Media download is gestart… @@ -136,11 +111,8 @@ Video\'s opgeslagen in galerij De video is niet opgeslagen Afbeelding uploaden - Uploaden… Gebruiker heeft geen Lightning Adress ingesteld om sats te ontvangen "hier reageren.. " - Kopieert note ID naar klembord om te delen - Kopieer kanaal ID (note) naar klembord Past de kanaal-metadata aan Lid worden Bekend @@ -152,18 +124,14 @@ Reacties Jouw Galerij - "Volgend" "Rapporten" Meer opties "Relays" Website Lightning Adress Kopieert het NSEC ID (uw wachtwoord) naar klembord voor back-up. - Geheime sleutel kopiëren naar het klembord Toon QR-code van privésleutel Toon versleutelde QR-code van privésleutel - Kopieert de publieke sleutel naar klembord om te delen - Kopieer publieke sleutel (NPUB) naar klembord Stuur een privébericht Bewerkt de metadata van de gebruiker Volgen @@ -192,8 +160,6 @@ Hoe moeten we je noemen? Heb je geen Nostr account? Heb je al een Nostr account? - Een nieuw account aanmaken - Genereer een nieuwe sleutel Feed laden… Account wordt geladen "Foutmelding bij het laden reacties: " @@ -201,12 +167,6 @@ Nog geen meldingen. Feed is leeg. verversen - gecreëerd - met beschrijving van - en afbeelding - heeft chatnaam veranderd naar - omschrijving naar - en afbeelding naar Verlaten Ontvolgen Kanaal gemaakt @@ -232,7 +192,6 @@ Godslastering / haatdragende taal Haatdragende taal rapporteren Naaktheid / porno rapporteren - anderen Bekende markeren als gelezen Nieuwe markeren als gelezen Alles markeren als gelezen @@ -253,23 +212,18 @@ Authenticatie mislukt Biometrie kon de eigenaar van deze telefoon niet verifiëren Biometrie kon de eigenaar van deze telefoon niet verifiëren. Fout: %1$s - Fout - "Gemaakt door %1$s" "Badge award afbeelding voor %1$s" Je hebt een nieuwe Badge award ontvangen Badge award gegeven aan Note tekst gekopieerd naar klembord \@npub auteur gekopieerd naar klembord Note ID (@note1) gekopieerd naar klembord - Selecteer tekst "<Kan privébericht niet ontsleutelen>\n\nJe werd genoemd in een privégesprek tussen %1$s en %2$s." Nieuw account toevoegen Accounts Account selecteren Nieuw account toevoegen Account activeren - Heeft geheime sleutel - Alleen lezen, geen privésleutel Terug Selecteer Deel browserlink @@ -287,14 +241,12 @@ Verwijderen Blokkeren Rapporteren - Verwijderen Niet meer laten zien Spam of oplichting Godslastering of haatdragend gedrag Kwaadwillige imitatie Naaktheid of gevoelige inhoud Illegaal gedrag - Malware Als u een gebruiker blokkeert, wordt zijn inhoud in uw app verborgen. Uw notes zijn nog steeds publiekelijk zichtbaar, ook voor mensen die u blokkeert. Geblokkeerde gebruikers worden vermeld in het scherm Beveiligingsfilters. Misbruik melden @@ -314,30 +266,15 @@ Toevoegen aan publieke bladwijzers Verwijderen uit privé bladwijzers Verwijderen uit publieke bladwijzers - Wallet Connect Service - Machtigt een Nostr Secret om zaps te betalen zonder de app te verlaten. Houd het geheim veilig en gebruik indien mogelijk een privé relays. - Wallet Connect publieke sleutel - Wallet Connect Relay - Wallet Connect Secret - Toon secret sleutel - nsec / hex geheime sleutel Bedrag in sats - Verzend poll - Verplichte velden: - Zap ontvangers - Primaire poll beschrijving… Optie %s Poll optie beschrijvingen - Optionele velden: Zap minimum Zap maximum Consensus (0–100)% - Sluit na - dagen Kan niet stemmen Poll is gesloten voor nieuwe stemmen - Zap bedrag Slechts één stem per gebruiker is toegestaan bij dit type peiling. "Zoeken naar event %1$s" Een openbaar bericht toevoegen @@ -371,12 +308,9 @@ Geen spoor binnen Nostr, alleen in Lightning File server Kies een server om dit bestand naar te uploaden - LnAddress of @User Mediaservers Stel uw gewenste media upload servers in. - Je hebt geen NIP-96 servers ingesteld. Je kunt de lijst van Amethyst gebruiken of er hieronder een toevoegen ↓ Je hebt geen Blossom servers ingesteld. Je kunt de lijst van Amethyst gebruiken of er hieronder een toevoegen ↓ - Ingebouwde mediaservers Amethyst\'s standaardlijst. U kunt ze individueel toevoegen of de lijst toevoegen. Gebruik standaard lijst Mediaserver toevoegen @@ -389,31 +323,16 @@ Hashen Klaar Fout - Uw relays (NIP-95) - Bestanden worden geüpload naar en gehost door relays. Ze zijn vrij van een vaste url (afhankelijkheid van derden). Zorg ervoor dat u een NIP-95 relay in uw lijst met relays hebt. Privacyopties - Orbot/Tor setup - Verbinden via Orbot setup Aanpassen Tor-instellingen - Verbinding Orbot/Tor verbreken? - Je gegevens worden onmiddellijk overgezet via het reguliere netwerk Ja Nee - Volgerslijst Iedereen In de buurt Globaal Mute-lijst Standaard poort is 9050 - ## Verbind via Tor met Orbot - \n\n1. Installeer [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Start Orbot - \n3. Controleer in Orbot de Socks-poort. Standaard wordt 9050 gebruikt - \n4. Wijzig indien nodig de poort in Orbot - \n5. Configureer de Socks-poort in dit scherm - \n6. Druk op de knop Activeren om Orbot als proxy te gebruiken - Orbot Socks Poort Actieve Tor Engine Gebruik de interne versie van Orbot @@ -455,8 +374,6 @@ Verberg uw IP in alle verbindingen Maak je eigen Ongeldige poort - Gebruik Orbot - Ontkoppel Orbot/Tor Privéberichten Geeft een melding wanneer er een privébericht binnenkomt Zaps ontvangen @@ -465,20 +382,9 @@ Van %1$s voor %1$s Meld: - Doe mee aan het gesprek - Gebruiker of groeps ID - npub, nevent of hex - Maken - Deelnemen Vandaag Content waarschuwing Dit bericht bevat mogelijk beledigend of verontrustend, gevoelige inhoud - Verberg altijd gevoelige inhoud - Toon altijd gevoelige inhoud - Toon altijd content waarshuwingen - Raadt aan: - Filter spam van onbekenden - Waarschuw wanneer berichten meldingen hebben van je volgers Nieuwe reactie symbool Geen reactietypes geselecteerd. Lang indrukken om te wijzigen Zapraiser @@ -489,37 +395,24 @@ Schrijf naar relay Het aantal bytes dat naar deze relay is gestuurd, inclusief filters en gebeurtenissen Het aantal ontvangen bytes van deze relays, inclusief filters en gebeurtenissen - Er is een fout opgetreden bij het ophalen van de relay-informatie van %1$s Eigenaar Versie Software Contact Ondersteunde NIPs - Toelatingskosten Betaallink Beperkingen Landen Talen - Tags Postbeleid Fouten en meldingen van deze relay - Lengte van bericht - Abonnementen - Filters - Lengte abonnement-id Minimale voorvoegsel Maximale event tags - Content lengte Minimale PoW - Authenticatie - Betaling Cashu token Inwisselen - Stuur naar Zap wallet - Openen in Cashu wallet Token kopiëren Geen Lightning-adres ingesteld - Token gekopieerd naar klembord LIVE OFFLINE GEËINDIGD @@ -539,7 +432,6 @@ App-voorkeuren Instellingen Altijd - Alleen wifi Geen datalimiet Nooit Voltooid @@ -563,7 +455,6 @@ Kies de stijl van het bericht Profielgalerij stijl Kies de galerijstijl - Afbeelding laden Spammers Geen geluid. Klik om voor geluid Geluid. Klik voor geen geluid @@ -571,12 +462,8 @@ Nostr-adres is geverifieerd Verificatie van Nostr-adres mislukt Nostr-adres checken - Alles selecteren/deselecteren Standaard Standaardinstellingen herstellen - Selecteer een relay om verder te gaan - Stuur Zaps door naar: - Ondersteunende clients sturen zaps door naar het onderstaande LN-adres of gebruikersprofiel in plaats van naar het jouwe Locatie weergeven als Voegt een Geohash van je locatie toe aan het bericht. Het publiek weet dat je binnen 5 km (3mi) van de huidige locatie bent. Locatie-exclusief bericht @@ -584,9 +471,6 @@ Locatie laden Geen locatiemachtigingen Voegt een waarschuwing voor gevoelige inhoud toe voordat je inhoud wordt weergegeven. Dit is ideaal voor NSFW-inhoud of inhoud die sommige mensen beledigend of verontrustend vinden. - Nieuwe functie - Voor het activeren van deze modus is Amethyst nodig om een NIP-17 bericht te versturen. NIP-17 is nieuw en de meeste clients hebben deze nog niet geïmplementeerd. Zorg ervoor dat de ontvanger een compatibele client gebruikt. - Activeren Publiek Nieuwe openbare of besloten groep Privé @@ -603,7 +487,6 @@ Automatisch afbeeldingen en GIF\'s laden Video\'s en GIF\'s automatisch afspelen Toon URL-voorbeelden - Wanneer afbeeldingen te laden Kopieer stapel Kopiëren naar klembord Kopieer npub naar klembord @@ -614,45 +497,23 @@ Media toegevoegd Media toegevoegd aan je profielgalerij Gemaakt op - Regels Login met Amber Status bijwerken - Fout bij het parsen van foutberichten Stemmen worden gewogen door het aantal zap. U kunt een minimumbedrag instellen om spammers te voorkomen en een maximumbedrag om te voorkomen dat een grote zappers de enquête overneemt. Gebruik hetzelfde bedrag in beide velden om ervoor te zorgen dat elke stem hetzelfde wordt gewaardeerd. Laat het leeg om elk bedrag te accepteren. Kan zap niet verzenden Bericht de gebruiker Bericht %1$s Ok - Mislukt om %1$s te bereiken: %2$s - Fout bij het verzamelen van de NIP-11 url voor %1$s: %2$s - Mislukt om %1$s te bereiken: %2$s - Mislukt om het resultaat van %1$s te parsen: %2$s - Relay wijst aanvraag %1$s af: %2$s - Mislukt om %1$s te bereiken: %2$s - Mislukt om het resultaat van %1$s te parsen: %2$s - %1$s mislukt met code %2$s - Actief voor: - Startpagina - DM\'s - Chats - Globaal - Zoeken Deel en stuur Zaps door Ondersteunende clients delen en sturen door naar de gebruikers toegevoegd hier in plaats van de jouwe Zoek en voeg gebruiker toe Gebruikersnaam of weergavenaam Ontbrekende Lightning configuratie Gebruiker %1$s heeft geen Lightning Adress ingesteld om sats te ontvangen - Percentage - 25 - Deel zaps met - Stuur zaps door naar - Lightning wallets niet gevonden Betaald Wallet %1$s Fout bij openen ondertekenapp De teken-app kan niet worden gevonden. Controleer of de app niet is verwijderd - Ondertekenverzoek afgewezen Zorg ervoor dat de teken-app deze transactie heeft geautoriseerd Geen wallets gevonden om een Lightning Invoice te betalen (Error: %1$s). Installeer een Lightning wallet om zaps te gebruiken Geen wallets gevonden om een Lightning Invoice te betalen. Installeer een Lightning wallet om zaps te gebruiken @@ -663,36 +524,19 @@ Selecteer een optie Invoice kon niet worden betaald Kan niet opnemen - Kon geen Wallet Connect instellen - Fout bij het verwerken van de NIP-47 connectie string. Controleer of dit juist is met uw Wallet provider: %1$s. Fout: %2$s - Fout bij het verwerken van de NIP-47 connectie string. Controleer of dit juist is met uw Wallet provider: %1$s. Fout. Kan Cashu niet verzilveren Mint geeft de volgende foutmelding: %1$s - Cashu tokens zijn al uitgegeven. Cashu ontvangen %1$s sats zijn naar uw wallet gestuurd. (Fees: %2$s sats) Geen compatibele Cashu wallet gevonden in het systeem Kan invoice niet ophalen van de servers van de ontvanger De volgende fout is geretourneerd door uw wallet connect provider: %1$s - Kan geen verbinding maken met Tor - Download relay document niet beschikbaar Kon LNUrl niet samenbrengen van Lightning Adress \"%1$s\". Controleer de instellingen van de gebruiker - De Lightning service van de ontvanger bij %1$s is niet beschikbaar. Het werd berekend op basis van het Lightning Adress \"%2$s\". Fout: %3$s. Controleer of de server klaar is en of het Lightning Adress juist is - Kan %1$s niet oplossen. Controleer of u verbonden bent, of de server online is en of het Lightning Adress %2$s juist is - Kon %1$s niet oplossen. Controleer of u verbonden bent, of de server online is en of het Lightning Adress %2$s juist is. \n\nUitzondering was: %3$s - Kan invoice niet ophalen van %1$s Kan invoice niet ophalen van %1$s: %2$s - Fout bij het verwerken van JSON uit Lightning Adress. Controleer de Lightning setup van de gebruiker Fout bij het verwerken van JSON uit %1$s. Controleer de Lightning set-up van de gebruiker - Callback URL niet gevonden in de Lightning Adress configuratie van de gebruiker Callback URL niet gevonden uit het antwoord van %1$s - Fout bij het verwerken van JSON uit Lightning Adress. Controleer de Lightning setup van de gebruiker - Fout bij het verwerken van JSON uit de invoice van %1$s. Controleer de Lightning set-up van de gebruiker Onjuist Invoice-bedrag (%1$s sats) van %2$s. Het had %3$s moeten zijn Kan geen Linghtning invoice aanmaken voor het verzenden van de zap. De Lightning wallet van de ontvanger verstuurde de volgende fout: %1$s - Kan geen Lightning invoice aanmaken. Bericht van %1$s: %2$s - Kan geen Linghtning invoice aanmaken voor het verzenden van de zap. Element pr niet gevonden in de resulterende JSON. - Kan geen Lightning invoice aanmaken van %1$s: PR-element niet gevonden in de JSON. Read-only gebruiker Geen reacties setup Selecteer een UnifiedPush App @@ -710,13 +554,11 @@ Stuur de verkoper een bericht Hallo %1$s, is dit nog steeds beschikbaar? Hallo daar, is dit nog steeds beschikbaar? - Verkoop een artikel Titel iPhone 13 Staat Categorie Prijs (in sats) - 1000 Locatie Stad, provincie, land Nieuw @@ -745,20 +587,13 @@ Anders Uploaden van media mislukt Kan het gecomprimeerde bestand niet openen - Fout bij het comprimeren van media: %1$s Upload fout: %1$s Server heeft geen URL opgegeven na uploaden Kan de geüploade media niet downloaden van de server Kan het gedownloade bestand niet controleren na upload: %1$s - Kon lokaal bestand niet voorbereiden voor upload: %1$s Mislukt om naar %1$s te uploaden: %2$s - Uploaden van media mislukt: %1$s Verwijderen van media mislukt: %1$s Media is te groot voor NIP-95 - Kan thumbnail niet laden - Kon header-informatie niet voorbereiden: %1$s - Compressie geannuleerd - Compressie kon een bestand niet terugsturen Mediakwaliteit Selecteer lage kwaliteit om uw media te comprimeren naar een kleiner bestand met minder kwaliteit of selecteer hoge kwaliteit om te comprimeren naar een groter bestand met een hogere kwaliteit. Laag @@ -767,15 +602,11 @@ Ongecomprimeerd Concept bewerken Inloggen met QR-Code - Route Beginscherm - Zoeken Ontdekken Berichten Notificaties - Globaal Shorts - Beveiligingsfilters Nieuw bericht Nieuwe shorts: afbeeldingen of video\'s Nieuwe community note @@ -790,29 +621,22 @@ Relay %1$s Lijst van relays uitvouwen Note opties - Relay selectiemenu Poll Poll uitschakelen Bitcoin invoice Annuleer Bitcoin invoice - Verkoop van een item annuleren Zapraiser Annuleer Zapraiser Locatie Locatie verwijderen - Zap splitsen - Annuleer splitsing Zap Content waarschuwing toevoegen Content waarschuwing verwijderen Toon npub als een QR-code Ongeldig adres Amethist ontving een URI om te openen, maar die uri was ongeldig: %1$s DM inbox relays - Relays: %1$s - Gebruik normale relays Stel uw Privé Postvak relays in Deze instelling geeft iedereen informatie over de relays die gebruikt worden bij het verzenden van berichten. Zonder hen mis je mogelijk een bericht. - Goede opties zijn:\n - inbox.nostr.wine (betaald)\n - you.nostr1.com (persoonlijke relays - betaald) Goede opties zijn:\n - auth.nostr1.com (gratis)\n - inbox.nostr.wine (betaald)\n - relay.0xchat.com (gratis) Voeg tussen de 1 en 3 relays toe om als privéinbox te dienen. DM inbox relays moeten een bericht van iedereen accepteren, maar alleen om berichten te downloaden. Nu instellen @@ -821,7 +645,6 @@ Het maken van een relay lijst speciaal ontworpen voor zoekopdracht en gebruikers-tagging zal deze resultaten verbeteren. Voeg tussen de 1 en 3 relays toe om te gebruiken bij het zoeken naar content of bij het taggen van gebruikers. Zorg ervoor dat uw gekozen relays implementatie van NIP-50 Goede opties zijn:\n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com - DM uploaden Relay-instellingen Openbare thuis relays Dit relay type slaat al je inhoud op. Amethyst stuurt je berichten hierheen en anderen gebruiken deze relays om je inhoud te vinden. Voeg tussen de 1 en 3 relays toe. Het gaat om persoonlijke relays, betaalde relays of openbare relays. @@ -831,10 +654,6 @@ Voeg tussen de 1 en 3 relays toe om als uw privéinbox te dienen. Anderen gebruiken deze relays om DM\'s naar u te sturen. DM Inbox relays moeten een bericht van iedereen accepteren, maar alleen om berichten te downloaden. Goede opties zijn:\n - inbox.nostr.wine (betaald)\n - you.nostr1.com (persoonlijke relays - betaald) Privé relays Plaats tussen de 1 tot 3 relays om gebeurtenissen op te slaan die niemand anders kan zien, zoals uw Concepten en/of app instellingen. Idealiter zijn deze relays lokaal of vereist authenticatie voordat de inhoud van elke gebruiker wordt gedownload. - Algemene relays - Amethyst gebruikt deze relays om berichten voor jou te downloaden. - Aanbevolen relays - Voeg de volgende relays toe aan je algemene relay-lijst om berichten van de vermelde gebruikers te ontvangen. Relays zoeken Lijst van relays om te gebruiken bij het zoeken naar inhoud of gebruikers. Taggen en zoeken werkt niet als er geen opties beschikbaar zijn. Zorg ervoor dat ze NIP-50 implementeren. Lokale relays @@ -846,11 +665,8 @@ Deze versie werd je aangeboden door: Versie %1$s Bedankt! - Max. limiet Beperkte schrijfrechten Geforked van - FORK - Git Repository: %1$s Web: Kopiëren: OTS: %1$s @@ -858,19 +674,12 @@ Er is bewijs dat dit bericht enige tijd voor %1$sis getekend. Het bewijs is op dat tijdstip en op dat moment getypeerd in de Bitcoin-blockchain. Bericht wijzigen Voorstel om een bericht te verbeteren - Samenvatting van wijzigingen - Snelle oplossingen… Accepteer de suggestie Downloaden - Songteksten aan - Songteksten uit - Verzegeld bericht uit. Klik om Verzegeld bericht aan te zetten - Verzegeld bericht aan. Klik om Verzegeld bericht uit te zetten Verzenden Speel gebruikersnaam af als audio Pushpin Scan de QR-code - Navigeer naar de externe wallet provider Alby Het is niet mogelijk om een concept te beantwoorden Het is niet mogelijk om een concept te citeren Het is niet mogelijk om op een concept te reageren @@ -911,19 +720,21 @@ Onvoldoende opslagruimte - De server heeft niet genoeg opslagruimte om het verzoek succesvol te verwerken Loop gedetecteerd - De server detecteert een oneindige loop tijdens het verwerken van het verzoek Netwerk authenticatie vereist - De client moet geauthenticeerd zijn om toegang te krijgen tot het netwerk - NIP-96 servers - Voeg zoveel servers toe als je wilt. Je kunt later kiezen welke zal worden gebruikt bij het uploaden van je afbeelding Blossom servers Voeg zoveel servers toe als je wilt. Je kunt later kiezen welke zal worden gebruikt bij het uploaden van je afbeelding Voeg een NIP-96 Server toe Een Blossom server toevoegen Alles verwijderen Weet u zeker dat u alle concepten wilt verwijderen? - Stack: Torrent-bestand Downloaden Kon bestand niet openen Geen torrent apps geïnstalleerd om het bestand te openen en te downloaden. Selecteer een lijst om de feed te filteren Afmelden bij apparaatvergrendeling + De Lightning service van de ontvanger bij %1$s is niet beschikbaar. Het werd berekend op basis van het Lightning Adress \"%2$s\". Fout: %3$s. Controleer of de server klaar is en of het Lightning Adress juist is + Kon %1$s niet oplossen. Controleer of u verbonden bent, of de server online is en of het Lightning Adress %2$s juist is. \n\nUitzondering was: %3$s + Fout bij het verwerken van JSON uit de invoice van %1$s. Controleer de Lightning set-up van de gebruiker + Kan geen Lightning invoice aanmaken. Bericht van %1$s: %2$s + Kan geen Lightning invoice aanmaken van %1$s: PR-element niet gevonden in de JSON. diff --git a/amethyst/src/main/res/values-pcm-rNG/strings.xml b/amethyst/src/main/res/values-pcm-rNG/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-pcm-rNG/strings.xml +++ b/amethyst/src/main/res/values-pcm-rNG/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-pl-rPL/strings.xml b/amethyst/src/main/res/values-pl-rPL/strings.xml index 64f3ca72de..209546ed7d 100644 --- a/amethyst/src/main/res/values-pl-rPL/strings.xml +++ b/amethyst/src/main/res/values-pl-rPL/strings.xml @@ -20,6 +20,12 @@ %1$d zestawów aktywów %1$d zestawy aktywów + + +%1$d\nodpowiedź + +%1$d\nodpowiedzi + +%1$d\nOdpowiedzi + +%1$d\nodpowiedzi + Wydarzenie jest wczytywane lub nie można go znaleźć na liście transmiterów 👀 Zdjęcie kanału @@ -36,8 +42,6 @@ Inne Nękanie Przemoc - Nieznani - Ikona transmitera Autor nieznany Skopiuj tekst Kopiuj identyfikator autora @@ -52,12 +56,9 @@ Zgłoś spam/oszustwo Zgłoś podszywanie się - Zgłoś niedozwoloną zawartość Zgłoś antyspołeczne działania Zgłoś złośliwe oprogramowanie - Zgłoś modyfikację Złośliwe oprogramowanie - Modyfikacja Używasz klucza publicznego, a klucze publiczne są tylko do odczytu. Zaloguj się za pomocą klucza prywatnego, aby móc odpowiedzieć Używasz klucza publicznego, a klucze publiczne są tylko do odczytu. Zaloguj się za pomocą klucza prywatnego, aby zwiększyć liczbę postów Używasz klucza publicznego, a klucze publiczne są tylko do odczytu. Zaloguj się za pomocą klucza prywatnego, aby polubić posty @@ -71,17 +72,14 @@ Używasz klucza publicznego, a klucze publiczne są tylko do odczytu. Zaloguj się za pomocą klucza prywatnego, aby móc przestać obserwować Używasz klucza publicznego, a klucze publiczne są tylko do odczytu. Zaloguj się za pomocą klucza prywatnego, aby móc ukryć słowo lub zdanie Używasz klucza publicznego, a klucze publiczne są tylko do odczytu. Zaloguj się za pomocą klucza prywatnego, aby móc pokazać wyraz lub zdanie - Używasz klucza publicznego i kluczy publicznych tylko do odczytu. Zaloguj się za pomocą klucza prywatnego, aby móc zmieniać ustawienia Używasz klucza publicznego i kluczy publicznych tylko do odczytu. Zaloguj się za pomocą klucza prywatnego, aby móc wgrać Używasz klucza publicznego i kluczy publicznych tylko do odczytu. Zaloguj się za pomocą klucza prywatnego, aby móc zapisać się na udział w wydarzeniu Nieautoryzowane odszyfrowywanie Sygnatariusz nie autoryzował deszyfrowania wymaganego do wykonania tej operacji. Aktywuj deszyfrowanie NIP-44 w aplikacji logującej i spróbuj ponownie Nie odnaleziono sygnatariusza Czy aplikacja sygnatariusza została odinstalowana? Sprawdź, czy aplikacja sygnatariusza jest zainstalowana i czy ma to konto. Wyloguj się i zaloguj ponownie, jeśli aplikacja sygnatariusza uległa zmianie. - Sygnatariusz działał nieprawidłowo Sygnatariusz zewnętrzny zwrócił dane, które są niezgodne z żądaniem. Być może wystąpił błąd w Amethyst lub w samym sygnatariuszu. Zapy - Liczba wyświetleń Powtórz wpis powtórzono edytowano @@ -94,9 +92,7 @@ Dodaj "odpowiadając do " " i " - "na kanale " Baner profilu - Płatność zakończona pomyślnie Błąd podczas analizowania komunikatu o błędzie " Obserwowane" " Obserwujące" @@ -169,7 +165,6 @@ Brak wystarczającej ilości środków na koncie, z którego pochodzi ta wpłata. Najpierw doładuj swój portfel Cashu. Kwota dla tego odbiorcy: %1$s satoszy Opłata sieciowa - aplikacji portfela Transakcja: %1$s Lightning transfer Wiadomość dla odbiorcy @@ -183,16 +178,13 @@ Widoczny prefiks 😎 Dodaj do wpisu - "Błąd analizowania podglądu dla %1$s : %2$s" "Podgląd obrazu karty dla %1$s" Artykuł - Nowy kanał Nazwa Nazwa Grupy Adres Url obrazka Adres URL zdjęcia (opcjonalnie) Opis - Nie znaleziono opisu "Informacja o grupie…" Co masz na myśli? Napisz wiadomość… @@ -202,42 +194,25 @@ Utwórz Zmień nazwę Anuluj - Nie udało się przesłać obrazu - Adres transmitera - Posty - Bajtów Błąd Błędy Odsetek udanych połączeń z transmiterem - Liczba błędów połączenia w tej sesji - Główny kanał - Kanał wiadomości prywatnych - Kanał Czatu Publicznego - Kanał Ogólny - Przeszukaj kanał Szukaj i dodaj użytkownika - Dodaj użytkownika Dodaj Transmiter - Imię - Imię (dla @tagging) Moje imię @tag Nazwa użytkownika Mój nick G Braun Witamy serdecznie! Nazwa użytkownika - Mój login O mnie URL awatara URL banera Adres URL strony Zaimki - LN Adres - Adres URL LN (nieaktualny) Transmitery źródłowe mogą być nieaktualne Ostrzeżenie o nieaktualnym transmiterze Zapisz w telefonie - Zapisz w galerii Zdjęcie zostało zapisane w galerii Rozpoczęto pobieranie wideo… Rozpoczęto pobieranie plików… @@ -253,16 +228,14 @@ Prześlij plik Zrób zdjęcie Nagraj film + Nie znaleziono aplikacji kamery na tym urządzeniu Nagraj wiadomość - Nagrywanie wiadomości Kliknij i przytrzymaj aby nagrać wiadomość Nagraj ponownie Nagrywanie Nagrywanie %1$s - Wgrywanie… Błąd przesyłania Nie udało się przesłać wiadomości głosowej - Nieoczekiwany status przesyłania NIP-95 nie jest jeszcze dostępny dla wiadomości głosowych Nie udało się przesłać głosu: %1$s Brak @@ -274,8 +247,6 @@ Użytkownik nie ma skonfigurowanego adresu LN, aby odbierać satosze "odpowiedz tutaj.. " Na tym czacie - Kopiuje ID wpisu do schowka w celu udostępnienia w Nostr - Kopiuj ID kanału (wpisu) do schowka Edytuje metadane kanału Dołącz Znajomi @@ -289,7 +260,6 @@ Odpowiedzi Twoje Galeria - "Obserwowani" "Zgłoszenia" "%1$s Zgłoszeń" Więcej opcji @@ -297,11 +267,8 @@ Strona www Lightning Adres Kopiuje Nsec ID (hasło) do schowka w celu wykonania kopii zapasowej - Skopiuj tajny klucz do schowka Pokaż kod QR klucza prywatnego Pokaż zaszyfrowany kod QR klucza prywatnego - Kopiuje klucz publiczny do schowka w celu udostępnienia - Skopiuj klucz publiczny (NPub) do schowka Wyślij bezpośrednią wiadomość Edytowanie metadanych użytkowników Obserwuj @@ -330,8 +297,6 @@ Jak się do ciebie zwracać? Nie posiadasz konta Nostr? Masz już konto Nostr? - Utwórz nowe konto - Wygeneruj nowy klucz Wczytywanie zawartości Ładowanie konta zaszyfrowane @@ -347,13 +312,7 @@ Ankieta Otwarta Brak zawartości. Odśwież - stworzył (a) - z opisem - i zdjęcie - zmieniono nazwę czatu na Nowy profil czatu: - opis dla - i zdjęcie do Wyjdź Nie obserwuj Kanał utworzony @@ -387,7 +346,6 @@ Adres Nostr nigdy teraz - sekund godz. m d @@ -395,7 +353,6 @@ Wulgaryzmy / Mowa nienawiści Zgłoś mowę nienawiści Zgłoś Nagość / Pornografię - inne Zaznacz wszystkie popularne jako przeczytane Zaznacz wszystkie nowe jako przeczytane Zaznacz wszystkie jako przeczytane @@ -416,8 +373,6 @@ Uwierzytelnianie nie udało się Biometria nie uwierzytelniła właściciela tego telefonu Biometria nie uwierzytelniła właściciela tego telefonu. Błąd: %1$s - Błąd - "Utworzony przez %1$s" "Wizerunek odznaki dla %1$s" Wizerunek odznaki Otrzymałeś nową odznakę @@ -425,7 +380,6 @@ Skopiowano tekst wpisu do schowka Skopiowano @npub autora do schowka Skopiowane ID wpisu (@note1) do schowka - Zaznacz tekst "<Unable to decrypt private message>\n\nZostałeś wspomniany w prywatnej/zaszyfrowanej rozmowie pomiędzy %1$s i %2$s." Dodaj nowe konto Konta @@ -437,13 +391,12 @@ Wybierz Konto Dodaj konto Konto aktywne - Ma klucz prywatny - Tylko do odczytu, brak klucza prywatnego Wstecz Wybierz Udostępnij link przeglądarki Przekaż Udostępnij jako obrazek + Udostępnij jako adres Url obrazu Generowanie podglądu… Udostępnione przez Ametyst ID autora @@ -462,14 +415,12 @@ Zablokuj wątek Odblokuj wątek Zgłoś - Usuń Nie pokazuj więcej Spam lub oszustwa Wulgaryzmy lub obelgi Złośliwe podszywanie się Nagość lub obraźliwa grafika Antyspołeczne zachowanie - Złośliwe oprogramowanie Zablokowanie użytkownika ukryje jego zawartość w aplikacji. Twoje wpisy będą nadal widoczne publicznie, w tym dla osób, które blokujesz. Zablokowani użytkownicy są wymienieni na ekranie filtrów bezpieczeństwa. Zgłoś nadużycie @@ -497,7 +448,6 @@ Wybierz planowany czas Harmonogram dla… Opublikowano %1$s - Miał być wysłany %1$s temu Czas Zaplanuj post Anuluj planowanie @@ -583,7 +533,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Autor Zapytania Akceptacje - Nie znaleziono społeczności spełniających te kryteria. Zasady weryfikowalne (opcjonalne) Wspólnie ze społecznością publikuje dokument zawierający reguły w formacie nadającym się do odczytu maszynowego (NIP-9B). Klienci obsługujący ten standard blokują przed wysłaniem posty, które nie spełniają tych reguł. Dozwolone rodzaje zdarzeń @@ -612,26 +561,15 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Dodaj bramę WoT Maksymalna wielkość zdarzenia (opcjonalnie) Bajtów \u2014 zostaw puste dla braku globalnego limitu. - Otrzymano - Moje - Przyznane - Odkryj Nowa odznaka - Edytuj odznakę Znak wyróżnienia Zaakceptuj Odrzuć Usuń z profilu - ID odznaki (d-tag) - odwaga, współtwórca-2025… Nazwa Nazwa odznaki czytelna dla człowieka Opis Za co przyznawana jest ta odznaka? - Adres URL obrazu (1024×1024) - https://domena.pl/plakietka.png - URL miniatury (opcjonalnie) - https://domena.pl/miniatura-plakietki.png Wgraj obraz Wybierz kwadratowe zdjęcie, które posłuży jako wizerunek Twojej odznaki. Ładowanie odznaki… @@ -640,7 +578,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Usuń Odznaka bez nazwy Przyznano dla %1$d - Otrzymałeś odznakę Odznaki w profilu Odznaki · %1$d Wybierz, które z otrzymanych odznak pojawią się na Twoim profilu. @@ -686,12 +623,7 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Współdziel treningi Niech aplikacja Amethyst odczytuje zakończone treningi z serwisu Health Connect (Samsung Health, Google Fit, Fitbit, Garmin…) i proponuje wpis. Połącz - Wykryto nowy trening - Udostępnij - Odrzuć %1$s km - %1$s uderzeń na minutę - %1$s kcal Z Health Connect Bieganie Spacer @@ -705,7 +637,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Dieta Post Aplikacje - Aplikacje Źródło: %1$s v%1$s Pobierz @@ -714,12 +645,10 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Tematy Linki Najnowsze wydanie - Komentarze Bądź pierwszym, który skomentuje. przez Pokaż starsze wersje Ukryj starsze wersje - Kalendarze Filmiki Czaty publiczne Pakiety subskrybentów @@ -729,18 +658,14 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Czat Nest Scena Oczekiwanie na mówców… - Publiczność Podnieś rękę Opuść rękę Podłącz dźwięk - Rozłącz Wycisz Włącz dźwięk - Łączenie… Podłączanie pokoju Otwarcie przesyłu Nawiązywanie kontaktu audio - Dźwięk podłączony Wznawianie połączenia… Nasłuch nagrywania Nie można wysłać wiadomości @@ -748,9 +673,7 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Zamknąć ten pokój? Wszyscy uczestnicy zostaną odłączeni. Pokój będzie oznaczony jako ZAMKNIĘTY. Zamknij pokój - Wybierz przyszły czas rozpoczęcia. Błąd dźwięku: %1$s - Dźwięk nie jest dostępny dla tego pokoju Mów Zejść ze sceny Wycisz mikrofon @@ -758,7 +681,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Wejdź na żywo… Nieudana transmisja: %1$s Nieudane wyciszenie: %1$s - Dostęp do mikrofonu jest wymagany, aby rozmawiać w tym pokoju. Otwórz ustawienia Nests Kontynuuje odtwarzanie dźwięku, jeżeli pokój jest otwarty. @@ -769,7 +691,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Dołącz do Nest Kreator Otwórz - Ostatni czat Nikogo nie ma w pokoju. %1$d słucha Kreator @@ -799,8 +720,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Publiczność Ręce Brak publiczności. - Wyślij - Powiedz coś… Na razie nie ma wiadomości. Zacznij rozmowę jako pierwszy. Reaguj Edytuj pokój @@ -834,7 +753,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Akcja nieudana Nie udało się przygotować tej akcji. Udostępnij pokój - Zminimalizuj Minimalizuj aby słuchać Zanik dźwięku Wczytywanie pokoju… @@ -867,7 +785,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Wybierz serwery MoQ, na których Amethyst ma publikować Twoje Nesty. Pierwszy wpis jest domyślnie używany przy tworzeniu nowej strefy. Twoje serwery Zapisano jako zdarzenie typ-10112 z możliwością zmiany, aby inne aplikacje klienckie mogły odczytać Twoje preferencje. - Dodaj serwer Nest URL transmitera (Sieć przesyłu) URL uwierzytelniania (JWT mint) Dodaj @@ -880,13 +797,11 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Usuń serwer Brak serwerów Nest. Dodaj jeden poniżej lub wybierz polecany serwer. Filmy wideo - Artykuły Muzyka Playlisty Odcinki Podcasty Pokaż odcinki - Odcinki Brak odcinków %1$d odcinek @@ -900,9 +815,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Tytuł utworu Artysta Nazwa wykonawcy - Odnośnik audio - https://… .mp3 - Adres miniaturki (opcjonalnie) Album (opcjonalnie) Czas trwania w sekundach (opcjonalnie) Teksty lub wkład twórczy (opcjonalne) @@ -912,7 +824,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Dodaj do playlisty Nie masz jeszcze żadnych list odtwarzania. Skorzystaj z pola powyżej, aby utworzyć listę. Zarządzaj wszystkimi playlistami - Nowa playlista Nazwa playlisty Utwórz (niezatytułowana playlista) @@ -950,9 +861,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Usuń listę zakładek Zobacz posty Zobacz Artykuł - Zobacz linki - Zobacz Hashtagi - Nie masz jeszcze żadnych list zakładek. Naciśnij nowy przycisk poniżej, aby utworzyć listę. Zestawy hasztagów Nie masz jeszcze żadnych grup zainteresowań. Kliknij przycisk „Nowa Grupa” poniżej, aby utworzyć nową. Nowa Grupa @@ -971,7 +879,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Prywatnych postów: (%1$s) Publiczne posty Publicznych postów: (%1$s) - Artykuły prywatne Artykułów prywatnych: (%1$s) Artykuły publiczne Artykułów publicznych: (%1$s) @@ -998,16 +905,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Metadane listy obserwowanych są widoczne dla wszystkich użytkowników w sieci Nostr. Tylko Twoi uczestnicy prywatni są zaszyfrowani. Przenieś do Publicznych Przenieś do Prywatnych - Usługa Wallet Connect - Autoryzuje Nostr Secret do płacenia zapów bez opuszczania aplikacji. Strzeż pilnie i użyj prywatnego transmitera, jeśli to możliwe - Klucz publiczny Wallet Connect - Transmiter Wallet Connect - Klucz dostępu do portfela - Pokaż tajny klucz - klucz prywatny nsec / hex - Połączony - Nie połączony - Zaawansowane: wprowadź szczegóły połączenia ręcznie Kwoty Quick Zap Wyświetlane po naciśnięciu przycisku zap. Dotknij kwoty, aby ją usunąć. Jeśli pozostawisz to pole puste, za każdym razem otworzy się okno dialogowe umożliwiające wprowadzenie kwoty. Zamiast tego wyślij on-chain @@ -1039,14 +936,8 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Podłącz portfel Przejrzyj kanał transmitera Kwota zobowiązania w Satoszach - Wyślij Ankietę - Wymagane pola: - Odbiorcy zap - Podstawowy opis ankiety… - Opcja Opcja %s Opis opcji ankiety - Pola opcjonalne: Minimalny Zap Maksymalny Zap Konsensus @@ -1055,11 +946,8 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Wielokrotny wybór Data & godzina zakończenia ankiety Ankieta zostanie zamknięta za %1$s - Zamknij po - dni Nie można głosować Ankieta jest zamknięta dla nowych głosów - Kwota Zap Tylko jeden głos na użytkownika jest dozwolony dla tego typu ankiety "Szukam wydarzenia %1$s" Wyślij Zapa @@ -1095,11 +983,8 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Bez Zapów Brak śladu w Nostr, tylko w Lightning Anonimowo - Opublikuj jako nowa, jednorazowa tożsamość. Twoje konto nie zostanie powiązane z tą odpowiedzią. - Ta odpowiedź zostanie wysłana z nowej anonimowej tożsamości Serwer Plików Wybierz serwer, aby przesłać ten plik - LnAdres lub @Użytkownik Serwery Multimediów Ustaw swoje preferowane serwery przesyłania multimediów. Użyj pamięci podręcznej Blossom @@ -1108,10 +993,8 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Nie wykryto lokalnej pamięci podręcznej na porcie 24242. Buforuj tylko zdjęcia profilowe Ogranicz lokalną pamięć podręczną do zdjęć profilowych. Obrazy i filmy z kanałów będą pobierane bezpośrednio z oryginalnych serwerów. - Nie masz ustawionych własnych serwerów NIP-96. Możesz użyć listy Amethysta lub dodać jeden poniżej ↓ Nie masz ustawionych własnych serwerów multimediów. Możesz użyć listy Amethysta lub dodać jeden poniżej ↓ Polecane serwery multimediów - Wbudowane serwery multimediów Domyślna lista Amethyst-a. Możesz dodawać je pojedynczo lub dodać pełną listę. Użyj domyślnej listy Dodaj serwer multimediów @@ -1134,38 +1017,21 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Hashowanie Gotowe Błąd - Twoje transmitery (NIP-95) - Pliki są przechowywane przez Twoje retransmitery. Nowy NIP: sprawdź, czy jest obsługiwany Ustawienia prywatności - Tor/Orbot - Ustawienia - Połącz przez swoją konfigurację Orbota Dostosuj Ustawienia TORa - Odłączyć od Orbota i Tora? - Twoje dane zostaną natychmiast przekazane w ramach zwykłej sieci Tak Nie - Lista obserwowanych Wszystkie obserwacje Obserwowane osoby Domyślna lista obserwowanych - Obserwowani przez proxy W pobliżu Wszystkie Wybrane - Szachy Moje Zablokowane Listy obserwowanych Są to listy obserwowanych przeznaczone do prywatnego użytku. Możesz obserwować użytkowników dyskretnie lub otwarcie - Oznaczone zakładki - Ogólne zakładki - Publiczna - Prywatna - Mieszana - Wygląda na to, że nie masz jeszcze żadnej listy obserwowanych. - \nDotknij poniżej, aby odświeżyć, lub naciśnij przycisk Dodaj, aby utworzyć listę. - Nowa Dodaj autora do listy obserwowanych Dodaj lub usuń użytkownika z list, lub utwórz nową listę z tym użytkownikiem. @@ -1174,23 +1040,9 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest %1$s jest uczestnikiem prywatnym Dodaj jako uczestnika publicznego Dodaj jako uczestnika prywatnego - Publiczne - Prywatne - Profile publiczne - Profile prywatne - uczestnik - członkowie - Brak uczestników Pusto - %1$s nie jest na liście %1$s nie jest uczestnikiem %1$s na Twoich listach - Twoja lista obserwowanych - Nie znaleziono list obserwowanych lub nie masz żadnych list obserwowanych. Naciśnij poniżej, aby odświeżyć lub użyj menu, aby utworzyć nową. - Podczas pobierania wystąpił błąd: %1$s - Utwórz nową listę - \"Utwórz nową listę %1$s z członkiem - Tworzy zestaw obserwowanych %1$s i dodaje do niego %2$s. Nowa lista Nowy pakiet subskrybentów Kopiuj/Sklonuj listę obserwowanych @@ -1210,14 +1062,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Zmieniasz nazwę z do.. Domyślny port to 9050 - ## Połącz przez Tor z Orbotem - \n\n1. Zainstaluj [Orbota](https://play.google. om/store/apps/details?id= org.torproject.android) - \n2. Uruchom Orbota - \n3. W Orbocie sprawdź port Socks. Domyślna używany jest 9050 - \n4. Jeśli to konieczne, zmień port w Orbocie - \n5. Skonfiguruj port Socks w tym ekranie - \n6. Naciśnij przycisk Aktywuj, aby użyć Orbota jako proxy - Port Socks Orbota Aktywny silnik Tor Użyj wersji wewnętrznej lub Orbota @@ -1259,8 +1103,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Ukryj swój adres IP przy wszystkich połączeniach Stwórz swój własny Nieprawidłowy numer portu - Użyj Orbota - Odłącz Tor/Orbota Prywatne Wiadomości Powiadamia Cię, gdy nadejdzie prywatna wiadomość Otrzymano Zapy @@ -1317,12 +1159,8 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Bluetooth Połączenie głosowe Połączenie wideo - Czekam, aż dołączą inni Dodaj uczestnika Szukaj użytkowników\u2026 - Nie udało się nawiązać połączenia - Nie udało się przyjąć połączenia - Nie udało się utworzyć sesji połączenia Konieczne pozwolenie Ametysta potrzebuje dostępu do mikrofonu, aby rozpocząć rozmowę głosową. Proszę włączyć ją w ustawieniach aplikacji. Ametysta potrzebuje dostępu do aparatu i mikrofonu, aby rozpocząć rozmowę wideo. Proszę włączyć je w ustawieniach aplikacji. @@ -1345,6 +1183,18 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Uwierzytelnienie Utrzymuje aktywne połączenia z transmiterami skrzynki odbiorczej, umożliwiając otrzymywanie powiadomień w czasie rzeczywistym Powiadomienia Ametyst Aktywne + + Połączono z %1$d transmiterem odbiorczym + Połączono z %1$d transmiterami odbiorczymi + Połączono z %1$d transmiterami odbiorczymi + Połączono z %1$d transmiterami odbiorczymi + + + Podłączono do %1$d transmitera + Podłączono do %1$d transmiterów + Podłączono do %1$d transmiterów + Podłączono do %1$d transmiterów + Łączenie z transmiterami odbiorczymi\u2026 Usługa powiadomień zawsze włączona Utrzymuje stałe połączenie z transmiterami odbiorczymi, aby zapewnić natychmiastowe dostarczanie powiadomień. Wyświetla bieżące powiadomienia. Zużywa więcej baterii, ale gwarantuje, że nigdy nie przegapisz żadnej wiadomości. @@ -1356,24 +1206,13 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Android może ograniczać podłączenia transmiterów działające w tle. Wyłącz optymalizację baterii dla aplikacji Amethyst, aby zapewnić niezawodne powiadomienia. Napraw Powiadom: - Dołącz do dyskusji - ID Użytkownika lub Grupy - npub, nevent lub hex - Utwórz - Dołącz Dzisiaj Ostrzeżenie o zawartości Ostrzeżenie: %1$s Ten post zawiera wrażliwe treści, które niektóre osoby mogą uznać za obraźliwe lub niepokojące - Zawsze ukrywaj wrażliwe treści - Zawsze pokazuj wrażliwą zawartość - Zawsze pokazuj ostrzeżenia dotyczące zawartości Ukryj Pokaż Ostrzeżenie - Polecane: - Filtruj spam z nieznajomych - Ostrzegaj, gdy posty zostały zgłoszone przez osoby które obserwujesz Filtr spamu Ukrywa posty od nieznajomych, które były dokładnie takie same przez 5 lub więcej razy Dodaj tag klienta do moich zdarzeń @@ -1405,22 +1244,17 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Ilość w bajtach, która została wysłana do tego transmitera, w tym filtry i wydarzenia Ilość w bajtach, która została otrzymana z tego transmitera, w tym filtry i wydarzenia Zapisane zdarzenia - Wystąpił błąd podczas próby uzyskania informacji o transmiterze z %1$s Operator Używany przez Klucz dostępu do usług - Uruchamianie %1$s - Uruchamianie %1$s (%2$s) Wersja Oprogramowanie Kontakt Obsługiwane Nipy Obsługiwany Grasps - Opłaty za wstęp Wstęp Subskrypcja Publikacja - Płatności %1$s Adres URL płatności Odbiorcy docelowi Zasady i linki @@ -1428,7 +1262,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Ograniczenia Kraje Języki - Tagi Tematy Wszystkie kraje Wszystkie języki @@ -1443,64 +1276,48 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Otwórz Odczyt Zapis - RTT Sieć Typ Obsługiwane Nipy Wymagania - Ostatnie sprawdzenie %1$d ms Dopuszczalne typy Lokalizacja Aktywne subskrypcje - Wydarzenia oczekujące na wysłanie REQ Subskrypcje (%1$d) Subskrypcje KONTA (%1$d) Wydarzenia Wysłane (%1$d) - Brak aktywnych subskrypcji dla tego transmitera %1$d autorzy %1$d identyfikatorów od %1$s do %1$s limit %1$d - Długość wiadomości - Subskrybcje - Filtry - Długość identyfikatora subskrypcji Minimalny prefiks Maksymalna ilość tagów wydarzeń - Długość zawartości Maks. długość treści Odrzuć starsze niż Akceptuje do %1$s w przyszłości %1$s temu - %1$s zer %1$s bitów Zapisywanie zdarzeń Rozmiar treści Podłączenie Kontrola dostępu Minimalny poW - Autoryzacja Wymagane uwierzytelnienie - Płatność Wymagana płatność Maksymalna długość wiadomości Maks. subskrypcji Maks. liczba filtrów na Suba Maksymalny limit (Powracające zdarzenia) - Domyślny limit (Powracające zdarzenia) Maks. długość SubID Cashu Token Mint: %1$s Wykup - Wyślij do Zap Wallet - Otwórz w Portfelu Cashu Skopiuj token Otwórz w innej aplikacji Nie ustawiono adresu Lightning - Skopiowano token do schowka NA ŻYWO OFFLINE Zakończono @@ -1551,7 +1368,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Reset stanu Marmota. Nie można zresetować stanu Marmota: %1$s Zawsze - Tylko WiFi Nielimitowany Wi-Fi Nigdy Kompletny @@ -1576,7 +1392,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Wybierz styl wpisu Styl galerii Wybierz styl galerii - Załaduj obraz Spamerzy Wyciszone. Kliknij, aby włączyć dźwięk Dźwięk włączony. Kliknij, aby wyciszyć @@ -1588,18 +1403,13 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Adres Nostr został zweryfikowany Nieudana weryfikacja adresu Nostr Sprawdzanie adresu Nostr - Zaznacz/Odznacz wszystko Domyślne Przywróć ustawienia domyślne - Wybierz Transmiter, aby kontynuować - Przekaż zapy do: - Wspierający klient podzieli i przekaże zapy na LNAdres lub profil użytkownika poniżej zamiast Ciebie Wyświetl lokalizację jako Dodaje Geohash twojej lokalizacji do wpisu. Użytkownicy będą wiedzieli, że jesteś mniej niż 5 km od bieżącej lokalizacji Post ekskluzywny dla lokalizacji Tylko obserwatorzy z twojej lokalizacji to zobaczą. Twoi ogólni obserwatorzy nie zobaczą tego. Wpis hasztagowy - Tylko obserwujący ten hashtag to zobaczą. Twoi ogólni obserwujący nie zobaczą tego. Skomentuj na stronie internetowej Skomentuj na zewnętrznym serwisie Czas czytania: %1$d min. @@ -1624,20 +1434,30 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Wgraj plik audio Wybierz plik w formacie MP3, WAV lub FLAC. Po kliknięciu „Zapisz” zostanie on przesłany na Twój serwer multimediów. Plik audio gotowy do przesłania - Wgrywanie… Wgraj miniaturę i plik audio, a następnie opublikuj. Proces ten będzie kontynuowany nawet po opuszczeniu ekranu. - Błąd wgrywania: %1$s + Edytuj playlistę + Edytuj playlistę + Tytuł + Opis (opcjonalnie) + Uwagi (opcjonalne) + Wgraj miniaturkę + Wybierz kwadratowe zdjęcie, które posłuży jako grafika tej playlisty. + Ukryj tę playlistę w swoim publicznym profilu. + Pozwól innym dodawać utwory do tej playlisty. + Usuń tę playlistę + Publikować usunięcie NIP-09 dla tej playlisty? + Wgrywanie okładki i publikacja. Proces ten będzie kontynuowany nawet po opuszczeniu ekranu. + Brak utworów. Dodaj utwory z listy utworów, korzystając z opcji „Dodaj do listy odtwarzania”. + Przesuń utwór w górę + Przenieś utwór w dół + Usuń utwór z playlisty Pobieranie lokalizacji Brak dostępu do lokalizacji Dodaje ostrzeżenie o wrażliwych treściach przed wyświetleniem treści. Jest to idealne dla dowolnych treści NSFW lub treści, które niektóre osoby mogą uznać za obraźliwe lub przeszkadzające Powód (Opcjonalne) - Nowa Funkcjonalność - Aktywacja tego trybu wymaga wysłania wiadomości NIP-17 przez Ametyst. (Prezent, Zapieczętowane wiadomości bezpośrednie i grupowe). NIP-17 jest nowy, a większość klientów jeszcze go nie zaimplementowała. Upewnij się, że odbiorca używa kompatybilnego klienta. - Aktywuj Publiczna Grupa Nowa Grupa Publiczna lub Prywatna - Transmiter Prywatna Do Temat @@ -1649,9 +1469,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Wyjaśnienie dla członków Zmiana nazwy dla nowych celów. Wklej ze schowka - Nieprawidłowy NIP-47 URI - URI %1$s nie jest prawidłowym URI logowania NIP-47. - Podłącz do nowego portfela NWC Nie znaleziono portfela Amethyst nie znalazł żadnej aplikacji portfela obsługującej Nostr Wallet Connect (NWC). \n\nCo możesz zrobić: @@ -1668,7 +1485,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Automatycznie odtwarzaj filmy i pliki GIF Automatycznie odtwarzaj filmy, gdy są widoczne na ekranie Pokaż podgląd linków - Kiedy załadować obrazki Skopiuj Kopiuj do schowka Skopiowano do schowka @@ -1684,43 +1500,21 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Dodano pliki Pliki dodane do Twojej galerii profilu Utworzono - Zasady - O nas Wskazówki Moderatorzy Zaloguj się za pomocą Amber Zaktualizuj swój status - Błąd podczas analizowania komunikatu o błędzie Głosy są oceniane na podstawie ilości zapperów. Możesz ustawić minimalną kwotę, aby uniknąć spamerów i maksymalną kwotę, aby uniknąć przejęcia ankiety przez dużych zapperów. Użyj tej samej kwoty w obu polach, aby upewnić się, że każdy głos ma taką samą wartość. Pozostaw to pole puste, aby zaakceptować dowolną kwotę. Nie można wysłać zapa Wyślij wiadomość użytkownikowi Wiadomość %1$s OK - Nieudane połączenie z %1$s: %2$s - Nie udało się skompilować adresu URL NIP-11 dla %1$s: %2$s - Nieudane połączenie z %1$s: %2$s - Nie udało się przeanalizować wyniku z %1$s: %2$s - Transmiter odrzucił żądanie %1$s: %2$s - Nieudane połączenie z %1$s: %2$s - Nie udało się przeanalizować wyniku z %1$s: %2$s - %1$s nie powiódł się z kodem %2$s - Aktywny dla: - Strona główna - DMs - Czaty - Wszystkie - Szukaj Podziel i przekaż Zapy Wspierający klient podzieli i przekaże zapy do dodanego tutaj użytkownika, a nie do Ciebie Szukaj i dodaj użytkownika Nick lub Login Brakująca konfiguracja LN Użytkownik %1$s nie ma skonfigurowanego adresu LN, aby odbierać satosze - Procentowo - 25 - Podziel zapy z - Przesyłanie zapów do - Nie znaleziono portfeli Lightning Zapłacone Portfel %1$s Błąd podczas otwierania aplikacji logującej @@ -1729,7 +1523,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Kodek lub format nie jest obsługiwany na tym urządzeniu (%1$s). Spróbuj go otworzyć w przeglądarce. Otwórz w przeglądarce Prośba o zalogowanie została odrzucona - Prośba o zalogowanie odrzucona Upewnij się, że aplikacja logującego autoryzuje tę operację Nie znaleziono portfeli do zapłacenia faktury z Lightning (Error: %1$s). Proszę zainstalować Lightning wallet, aby używać zapów Nie znaleziono portfeli do zapłacenia faktury z Lightning. Proszę zainstalować Lightning wallet, aby używać zapów @@ -1745,40 +1538,23 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Wybierz opcję Nie można zapłacić faktury Nie można wypłacić - Nie można skonfigurować Wallet Connect - Błąd podczas analizowania ciągu połączeń NIP-47. Sprawdź, czy jest to poprawne z Twoim dostawcą portfela: %1$s. Błąd: %2$s - Błąd podczas analizowania ciągu połączeń NIP-47. Sprawdź u dostawcy portfela, czy jest to poprawne: %1$s. Nie można wykupić Cashu Mint dostarczył następujący komunikat błędu: %1$s - Tokeny Cashu zostały już wydane. Cashu odebrano %1$s satsy zostały wysłane do Twojego portfela. (opłata: %2$s satoszy) W systemie nie znaleziono kompatybilnego portfela Cashu Nie można pobrać faktury z serwerów odbiorcy Twój dostawca połączenia z portfelem zwrócił następujący błąd: %1$s - Połączenie z serwerem Tor nieudane Tor nie łączy się Amethyst nie zdołał uruchomić sieci Tor. Czy można skorzystać ze zwykłego połączenia (nie przez Tor), aby strona mogła się załadować? Zapamiętamy ten wybór na najbliższą godzinę, a potem spróbujemy ponownie połączyć się przez Tor. Użyj zwykłego połączenia Czekaj - Nie można pobrać pliku z transmitera Nie można stworzyć LNUrl z Adresu \"%1$s\". Sprawdź konfigurację użytkownika - Usługa lightning odbiorcy w %1$s jest niedostępna. Została obliczona na podstawie adresu lightning \"%2$s\". Błąd: %3$s. Sprawdź, czy serwer jest gotowy i czy adres lightning jest poprawny - Nie można rozwiązać %1$s. Sprawdź, czy jesteś połączony, czy serwer jest gotowy i czy lightning adres %2$s jest poprawny - Nie można rozwiązać %1$s. Sprawdź, czy jesteś połączony, czy serwer jest gotowy i czy lightning adres %2$s jest poprawny.\n\nWyjątkiem było: %3$s - Nie można pobrać faktury z %1$s Nie można pobrać faktury od %1$s: %2$s - Błąd przetwarzania JSON z adresu lightning. Sprawdź konfigurację lightning użytkownika Błąd przetwarzania JSON z %1$s. Sprawdź konfigurację lightning użytkownika - Adres zwrotny nie został znaleziony w konfiguracji serwera adresu lightning użytkownika Nie znaleziono zwrotnego adresu URL z odpowiedzi %1$s - Wystąpił błąd podczas analizowania JSON z pobierania faktury z Lightning Adresu. Sprawdź konfigurację lightning użytkownika - Błąd przetwarzania pliku JSON z pobierania faktury %1$s. Sprawdź konfigurację lightning użytkownika Nieprawidłowa kwota faktury (%1$s satoszy) od %2$s. Powinieno być %3$s Nie można utworzyć faktury przed wysłaniem zapa. Portfel odbiorcy wysłał następujący błąd: %1$s - Nie można utworzyć faktury. Wiadomość od %1$s: %2$s - Nie można utworzyć faktury przed wysłaniem zapa. Element pr nie został znaleziony w powstałym JSON. - Nie można utworzyć faktury od %1$s: Element pr nie został znaleziony w powstałym JSON. \"Tylko do odczytu\" Nie ustawiono odzewu Powiadomienia @@ -1804,13 +1580,11 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Wyślij sprzedawcy wiadomość Witaj %1$s, czy to nadal jest dostępne? Cześć, czy to jest nadal dostępne? - Sprzedaj przedmiot Tytuł iPhone 13 Stan Kategoria Cena (w Satoszach) - 1000 Lokalizacja Miasto, Województwo, Kraj Nowość @@ -1839,20 +1613,13 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Inne Nie udało się wgrać załącznika Nie można otworzyć skompresowanego pliku - Błąd podczas kompresji plików: %1$s Błąd wysyłania: %1$s Serwer nie podał adresu URL po załadowaniu Nie można pobrać przesłanych plików z serwera Nie można sprawdzić pobranego pliku po wgraniu: %1$s - Nie można przygotować pliku lokalnego do przesłania: %1$s Nie udało się wgrać pliku do %1$s: %2$s - Nie udało się przesłać: %1$s Nie udało się usunąć: %1$s Pliki są zbyt duże dla NIP-95 - Nie można załadować miniatury - Nie można przygotować informacji nagłówkowych: %1$s - Kompresja anulowana - Kompresja nie powiodła się przy zwracaniu pliku Szyfrowanie plików W celu zapewnienia prywatności zaszyfruj pliki przed ich przesłaniem. Niektóre serwery mogą nie akceptować zaszyfrowanych plików na bezpłatnych kontach. Nie udało się przesłać zaszyfrowanego pliku @@ -1879,27 +1646,18 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Nie można usunąć metadanych z AVIF: %1$s Edytuj wersję roboczą Zaloguj się przy użyciu QR kodu - Ścieżka Start - Szukaj Odkryj Wiadomości Powiadomienia - Wszystkie Filmiki - Zdjęcia - Treningi Kalendarze Listy kalendarzy Szachy Portfel - Saldo Wyślij Odbierz Transakcje - Nie podłączono portfela - Aby korzystać z portfela, skonfiguruj połączenie Nostr Wallet Connect (NWC) w ustawieniach zap. - Skonfiguruj portfel satosze Wstaw fakturę BOLT-11 Zapłać @@ -1927,8 +1685,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Spowoduje to usunięcie połączenia z portfelem. Zawsze możesz je później dodać ponownie. Nazwa portfela Mój Portfel - Twoje portfele - Zarządzaj portfelami Nie podłączono żadnych portfeli Połącz jeden lub więcej portfeli NWC, aby wysyłać i odbierać płatności. Dodaj połączenie NWC @@ -1946,13 +1702,11 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Minty Adres Minta Usuń Minta + Dodaj mint Historia - Edytuj portfel Klucz Nutzap (zaawansowany) Oddzielny klucz prywatny służący wyłącznie do odbierania NIP-61 Nutzaps. Nie jest to klucz tożsamości Nostr. Wygeneruj nowy klucz - Spowoduje to unieważnienie wszystkich oczekujących zleceń typu „nutzap” powiązanych z bieżącym kluczem. - Zachowaj aktualny klucz Klucz prywatny P2PK (hex) Edytuj portfel Cashu Aktualizuj dane mojego konta @@ -1972,7 +1726,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Popularne Minty Pasujące Minty - Poleć tego Minta Odbierz Wyślij LN Wyślij token @@ -1991,6 +1744,7 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Edytuj szczegóły portfela Minty, klucz nutzap Moje rekomendacje Minta + Publicznie rekomenduj minty, którym ufasz, i wycofuj rekomendacje. Nie poleciłeś jeszcze żadnego Minta. Kliknij ikonę kciuka w górę obok Minta, aby publicznie go polecić. Usuń rekomendację Wycofać rekomendację? @@ -2001,6 +1755,25 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Skanowanie Mintów… Nie znaleziono odzyskiwalnych dowodów. Odzyskano %1$s satoszy w ramach %2$s dowodów. + Zatrzymaj otrzymywanie nutzapów + Wycofaj swój „kind:10019”, aby inni nie mogli już wysyłać Ci „nutzapów”. Twój portfel i saldo pozostaną bez zmian. + Zatrzymaj otrzymywanie nutzapów? + Zastąpimy Twoje zdarzenie „nutzap-info” pustym zdarzeniem i zgłosimy prośbę o jego usunięcie. Użytkownicy nie będą już mogli wysyłać Ci „nutzapów”. Możesz ponownie włączyć tę funkcję, edytując swój portfel. Nie ma to wpływu na Twoje saldo. + Odtwórz klucz nutzap + Wygeneruj zupełnie nowy klucz do odbierania nutzapów. Jest to rzadko konieczne — zazwyczaj tylko wtedy, gdy Twój obecny klucz został ujawniony. Nutzapy wysłane już na Twój stary klucz, ale jeszcze nie zrealizowane, zostaną utracone. + Odtworzyć klucz Nutzap? + Zostanie wygenerowany nowy klucz P2PK i opublikowany w twoich wpisach o typach kind:10019 oraz kind:17375, przy zachowaniu dotychczasowych emisji. Nadawcy zaczną przypisywać nutzapy do nowego klucza. Wszelkie nutzapy wysłane już na twój stary klucz, których jeszcze nie zrealizowałeś, staną się nieodwracalnie utracone. Jest to rzadko wymagane. + Odtwórz klucz + Importuj klucz Nutzap + Zastąp swój klucz Nutzap kluczem wklejonym — np. w celu przywrócenia portfela z kopii zapasowej. Jest to rzadko potrzebne. Nutzapy przypisane do starego klucza nie będą już możliwe do zrealizowania. + Importować klucz nutzap? + Wklej klucz prywatny P2PK (hex), którego chcesz używać do odbierania nutzapów. Twoje kind:10019 i kind:17375 zostaną ponownie opublikowane z tym kluczem, przy zachowaniu dotychczasowych emisji. Nutzapy zablokowane na Twoim obecnym kluczu nie będą już możliwe do zrealizowania, chyba że klucz ten będzie zgodny. Jest to rzadko potrzebne. + Klucz prywatny P2PK (hex) + Importuj klucz + Usuń portfel + Usuń portfel i wyłącz usługę Nutzaps. Ewentualne pozostałe środki mogą stać się nieodzyskiwalne. + Usunąć ten portfel? + Niniejsza operacja powoduje usunięcie Twojego portfela typu:17375 oraz danych dotyczących nutzapów typu:10019. Twoje dowody ecash nie zostaną usunięte z mintów, jednak wraz z utratą klucza do portfela wszelkie pozostałe salda i niewykorzystane nutzapy mogą stać się nieodzyskiwalne. Upewnij się, że najpierw wydałeś lub przeniosłeś swoje środki. Czynności tej nie można cofnąć. Opłać fakturę Pobierz ofertę Proszę Minta o wycenę… @@ -2019,6 +1792,7 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Gotowe Proszę o wystawienie faktury… Czekam na opłacenie faktury… + Sprawdzanie minta… Tworzenie dowodów… Płatność przez Mint… Wymiana dowodów… @@ -2032,10 +1806,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Zapisz Zmień nazwę Zmień nazwę portfela - Edytuj - Nieprawidłowy URI połączenia NWC - W górę - W dół Transakcje w łańcuchu Brak dostępnego adresu w łańcuchu dla tego konta. Nie skonfigurowano backendu łańcucha. @@ -2120,17 +1890,13 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Płatności wysłane (%1$d paragonów %2$d opublikowanych), ale następnych paragonów nie można opublikować Płatności wysłane (%1$d paragony %2$d opublikowane), ale kolejnych paragonów nie udało się opublikować - Filtry bezpieczeństwa Import Obserwowanych Nowy post Nowe Króciaki: zdjęcia lub filmiki Nowy wpis w społeczności Nowy produkt - Nowy GEO-ekskluzywny Wpis Nowy artykuł Nowa ankieta - Nowa ankieta - Nowa standardowa ankieta Nowe zdjęcie Nowe wydarzenie w kalendarzu Edytuj wydarzenie z kalendarza @@ -2145,8 +1911,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Dzień Nadchodzące W przeszłości - Nie ma jeszcze zbliżających się ani minionych wydarzeń z wybranego wątku. - Brak kolekcji kalendarza. Twój kalendarz jest pusty W tym miejscu wyświetlane są wydarzenia udostępnione przez obserwowane osoby. Naciśnij przycisk +, aby utworzyć własne. Nie ma jeszcze żadnych kolekcji @@ -2173,8 +1937,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Następny tydzień Poprzedni dzień Następny dzień - Brak wydarzeń w tym dniu - Brak wydarzeń Kontynuacja Dzień %1$d z %2$d Dodaj do kalendarza w telefonie @@ -2240,7 +2002,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Nie udało się wgrać wybranego zdjęcia. Spróbuj ponownie lub wklej adres URL. Uczestnicy (%1$d) Wyszukaj nazwę, npub lub nip-05 - Wprowadź poprawny npub… lub 64-znakowy klucz hex. Usuń uczestnika Przypomnienia z kalendarza Wyślij przypomnienia @@ -2263,10 +2024,7 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Szczegóły wydarzenia Nowy krótki filmik Nowe długie wideo - Tytuł Podsumowanie (opcjonalnie) - Adres URL miniaturki (opcjonalnie) - Napisz artykuł w formacie markdown… Podgląd Edytuj Dodaj zdjęcie w nagłówku @@ -2350,18 +2108,14 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Transmiter %1$s Rozwiń listę transmiterów Opcje wpisu - Wybór listy transmiterów Ankieta Wyłącz Ankietę Faktura Bitcoin Anuluj fakturę Bitcoin - Anuluj sprzedaż przedmiotu Zapraiser Anuluj Zapraiser Lokalizacja Usuń lokalizację - Podział Zap - Anuluj podział Zap Dodaj ostrzeżenie o treści Usuń ostrzeżenie o treści Dodaj datę wygaśnięcia @@ -2376,11 +2130,8 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Nieprawidłowy adres Ametyst otrzymał URI do otwarcia, ale ten adres był nieprawidłowy: %1$s Transmitery Skrzynki Odbiorczej - Transmitery %1$s - Korzystanie ze zwykłych transmiterów Skonfiguruj prywatne transmitery odbiorcze To ustawienie pozwala wszystkim wiedzieć, których transmiterów użyć podczas wysyłania wiadomości do Ciebie. Bez nich możesz przegapić niektóre wiadomości. - Dobre opcje to:\n - inbox.nostr.wine (płatny)\n - you.nostr1.com (transmitery osobiste - płatny) Dobre opcje to:\n - auth.nostr1.com (darmowe)\n - inbox.nostr.wine (płatne)\n - relay.0xchat.com (darmowe) Wstaw od 1 do 3 transmiterów, które będą służyć jako Twoja prywatna skrzynka odbiorcza. Transmitery DM powinny akceptować dowolne wiadomości od każdego, ale pozwalać tylko na ich pobieranie. Konfiguruj @@ -2400,7 +2151,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Stworzenie listy transmiterów specjalnie zaprojektowanej do odbierania powiadomień ma kluczowe znaczenie dla korzystania z protokołu Nostr. Wstaw od 1 do 3 transmiterów, które będą odbierać powiadomienia. Upewnij się, że nie wymagają one płatności ani statusu \"web of trust\" od nadawcy, w przeciwnym razie będziesz otrzymywać powiadomienia tylko od płatników lub stałych użytkowników Dobre opcje to:\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social - Wgrywanie DM Ustawienia Transmiterów Zmień kolejność transmiterów Publiczne transmitery domowe @@ -2417,12 +2167,8 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Transmitery, na których publikowane są Twoje pakiety kluczy MLS (MIP-00). Inni użytkownicy pobierają te pakiety kluczy, aby zaprosić Cię do czatów grupowych w aplikacji Marmot. Wprowadź od 1 do 3 transmiterów, które akceptują zdarzenia związane z pakietami kluczy od Ciebie i zezwalają na publiczny dostęp do tych danych. Transmitery Prywatne Wstaw od 1 do 3 transmiterów przechowujących dane zdarzeń, których nikt inny nie widzi, takich jak Wersje robocze i/lub ustawienia aplikacji. Idealnie byłoby, gdyby te transmitery były lokalne lub wymagały uwierzytelnienia przed pobraniem treści każdego użytkownika. - Transmitery ogólne - Amethyst używa tych przekaźników, aby pobrać dla Ciebie posty. Podłączone Transmitery Aktualna lista używanych transmiterów - Polecane Transmitery - Dodaj te transmitery do głównej listy, aby otrzymywać wiadomości od wymienionych użytkowników. Transmitery wyszukujące Lista transmiterów używanych podczas wyszukiwania treści lub użytkowników. Tagowanie i wyszukiwanie nie będą działać, jeśli nie będą dostępne żadne opcje. Upewnij się, że zaimplementowano NIP-50. Lokalne Transmitery @@ -2457,11 +2203,8 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Ta wersja została Ci dostarczona przez: Wersja %1$s Dziękuję! - Maksymalny Limit Twórcy z ograniczeniami Sklonowany z - SKLONUJ - Repozytorium Git: %1$s Strona internetowa: Klonuj: Otwarte @@ -2486,20 +2229,13 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Redaguj artykuł Edytuj wpis Propozycja ulepszenia wpisu - Podsumowanie zmian - Szybkie poprawki… Zaakceptuj sugestię Uruchom wideo w pop-upie Pobierz - Tekst włączony - Tekst wyłączony - Zapieczętowana wiadomość wyłączona. Kliknij, aby włączyć zapieczętowaną wiadomość - Zapieczętowana wiadomość włączona. Kliknij, aby wyłączyć zapieczętowaną wiadomość Wyślij Odtwórz nazwę użytkownika jako dźwięk Pinezka Zeskanuj QR kod - Przejdź do Alby zewnętrznego dostawcy portfela Wybierz datę Nie jest możliwa odpowiedź na szkic wpisu Nie jest możliwe zacytowanie szkicu wpisu @@ -2541,23 +2277,18 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Niewystarczająca pojemność - serwer nie ma wystarczającej pojemność, aby pomyślnie przetworzyć żądanie Wykryta pętla - serwer wykrywa nieskończoną pętlę podczas przetwarzania żądania Wymagane uwierzytelnienie sieciowe - Klient musi być uwierzytelniony aby uzyskać dostęp do sieci - Serwery NIP-96 - Dodaj tyle serwerów, ile chcesz. Możesz wybrać, z którego chcesz skorzystać później podczas wgrywania zdjęcia Serwery Blossom Dodaj tyle serwerów, ile chcesz. Możesz wybrać, z którego chcesz skorzystać później podczas wgrywania zdjęcia Dodaj serwer NIP-96 Dodaj Blossom Serwer Usuń wszystko Czy na pewno chcesz usunąć wszystkie wersje robocze? - Stos: Plik torrent Pobierz Nie udało się otworzyć pliku Brak zainstalowanych aplikacji torrent do otwarcia i pobrania pliku. Zdarzenie nie ma wystarczającej ilości informacji, aby zbudować link magnetyczny - Moje Listy/Zestawy Moje listy - Użytkownicy Wybierz opcję, aby filtrować aktualności Kanały Hashtagi @@ -2588,7 +2319,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Wiadomość prywatna Publiczna wiadomość Transmiter Czatu - Transmiter, z którym łączą się wszyscy użytkownicy tego czatu Udostępnij zdjęcie… Nie można udostępnić obrazu, spróbuj ponownie później… Udostępnij film… @@ -2635,7 +2365,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Czy chcesz wysłać ostatni raport o awarii do Amethyst w DM? Żadne dane osobowe nie będą udostępnione Prześlij Ta wiadomość zniknie za %1$s - Ta wiadomość zniknie za %1$d dni Wybierz Sygnatariusza Już jest na liście Prywatni uczestnicy @@ -2657,7 +2386,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Nazwa pakietu Nowa nazwa pakietu Opis pakietu - Opis nowego pakietu Upowszechnij listę Upowszechnij pakiet Usuń listę @@ -2671,13 +2399,9 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Zwiń Rozwiń Nieudanych powtórzeń (%1$d) - +%1$d kolejnych przekazów - " (%1$d w toku)" - %1$d/%2$d transmiterów Czas się skończył Ponawiam próbę… Ponów - Pokaż Ignoruj %1$d/%2$d Przekaz @@ -2703,7 +2427,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Zrestartuj Akceptuj Odrzuć - Nowa gra Nowa gra w Szachy Ładowanie gry\u2026 Gra nie znaleziona @@ -2858,23 +2581,13 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Profil do wczytania z wyszukaj, npub1…, alicja@domena.pl Obsługuje npub, nprofile, NIP-05, hex, i namecoin (.bit, d/, id/) - Sprawdź listę obserwowanych Porada Znaleziono %1$d kont(a) Wybrano: %1$d - Rozwiązane przez Namecoin - Teraz obserwujesz %1$d kont(a) - Twój kanał jest gotowy. - Pomiń - Szukaj innego Obserwuj %1$d konta - Pobierz więcej - Kontynuuj Na razie pomiń - Rozwiązywanie %1$s… Pobieranie listy obserwowanych… Nie znaleziono obserwowanych - Obserwujesz %1$d kont(a)… "Wprowadź profil znajomego lub lidera społeczności. Możesz użyć ich npub-u, adresu NIP-05 lub nazwy jak alicja@domena.pl lub id/alicja dla zweryfikowanych przez blockchain tożsamości." Wybierz Wszystkie Czas działania %1$d%% @@ -2882,7 +2595,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Test połączenia Testowanie serwerów… Podłączony - Test nieudany Wyniki testu Diagnostyka Ostatni test @@ -2895,9 +2607,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Zaufaj Odrzuć Synchronizacja Transmiterów - Synchronizacja Transmiterów - Opublikuj ponownie swoje wpisy na wszystkich znanych transmiterach, aby zaktualizować transmitery odbiorcze, nadawcze i wiadomości prywatnych. Wymagane połączenie Wi-Fi — może to spowodować zużycie dużej ilości danych. - Otwórz transmiter synchronizacji… Jak to działa To narzędzie skanuje wszystkie transmitery, z którymi zetknęła się Twoja aplikacja, i przekierowuje zdarzenia do właściwych miejsc docelowych: Pobierz wszystkie wydarzenia, których jesteś autorem, i wyślij je do transmiterów nadawczych. @@ -2907,14 +2616,9 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Włączyć transmisje danych komórkowych? Rozpocznij synchronizację Uruchom mimo to (transmisja danych komórkowych) - Pauza - Wznów - Zacznij od początku Anuluj Transmitery: %1$d / %2$d Wydarzenia rozdystrybuowane: %1$d nowych z %2$d wysłanych i %3$d otrzymanych - Synchronizacja wstrzymana - Ukończono %1$d z %2$d transmiterów — %3$d wydarzeń rozdystrybuowane to tej pory. Naciśnij „Wznów”, aby kontynuować. Synchronizacja zakończona Przesłano %1$d wydarzeń do transmiterów docelowych spośród %2$d. %1$d wydarzeń zaakceptowanych jako nowe przez docelowe transmitery. @@ -2929,16 +2633,13 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest wysłano %1$s odebrano %1$s nowych %1$s - brak wydarzeń Eksplorator Bitcoin (OTS) - wydarzeń wydarzenia od Ciebie wydarzeń dla Ciebie wydarzenia podlegające wyszukiwaniu DMs profile lista transmiterów wysyłających - ustawienia transmiterów Ostatnio widziano %1$s temu Ostatnio widziano %1$s (%2$s temu) Ostatnio widziano przed chwilą @@ -2993,6 +2694,25 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Kliknij, aby wznowić i sprawdzić status. Wznów + + Środki zgromadzone w %1$d mint, z których nie korzystasz + Środki przechowywane na %1$d mintach, których nie używasz + Środki przechowywane na %1$d mintach, których nie używasz + Środki przechowywane na %1$d mintach, których nie używasz + + Te monety pochodzą z serwisu Nutzap. Przenieś je do zaufanego minta lub wypłać do sieci Lightning, aby zapewnić im bezpieczeństwo. + Nie w Twoim portfelu + Przenieś + Wyprowadź monety + %2$s satoszy leżało w mincie, którego nie używasz (%1$s). Przenieś je do bardziej bezpiecznego miejsca. + Przenieś do zaufanego minta + Przenieś + Z tej transakcji pobierana jest niewielka opłata Lightning, więc może być konieczne wysłanie kwoty nieco niższej niż pełne saldo. + Dodaj mint do swojego portfela, aby przenosić te monety między mintami, lub skorzystaj z poniższych opcji. + Wypłać przez sieć Lightning… + Eksportuj jako token Cashu… + Przenoszenie monet… + Przeniesiono %1$s do %2$s. <%1$s Łączenie Pobieranie @@ -3012,7 +2732,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Wyszukiwanie urządzeń w sieci Wi-Fi… Wgraj HLS - Publikuj strumień HLS na swoim serwerze multimedialnym Wybierz wideo Twoje wideo zostanie przekodowane do różnych rozdzielczości, dzięki czemu widzowie będą mogli cieszyć się płynnym odtwarzaniem niezależnie od szybkości połączenia. Zmień @@ -3027,10 +2746,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest H.265 nie jest dostępny na tym urządzeniu – wróć do H.264. Wersje Rozdzielczość źródłowa: %1$d×%2$d - Wygeneruje: %1$s - (%1$s pominięto — źródło powyżej) - %1$d kbps - powyższe źródło — zostanie pominięte Opublikuj wideo HD Publikowanie „%1$s”… Transkodowanie %1$s @@ -3042,7 +2757,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Wideo opublikowane Twój film w jakości HD jest już dostępny na Nostr. Coś poszło nie tak - Zobacz publikację Gotowe Spróbuj ponownie Akcje pakietu @@ -3057,30 +2771,21 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Certyfikat Ważny Nieważny - Zaakceptowany - Odrzucony Weryfikacja - Zweryfikowany Unieważniony Ważny od %1$s Ważny do %1$s Wniosek o certyfikat - Wniosek o certyfikację wydarzenia Rekomendacja certyfikatora Zalecane dla typów: Poziom biegłości certyfikatora - Biegłość w sprawdzaniu typów: %1$s - Certyfikat dla Żądanie certyfikatu do Przedział czasu Od Do Teraz Cały czas - Ostatnia synchronizacja %1$s - Od ostatniej synchronizacji Zakładki - Brak zakładek. Naciśnij + aby dodać nową zakładkę. Dodaj zakładkę Edytuj zakładkę Adres URL @@ -3113,6 +2818,24 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest %1$s +%2$d więcej + Policja + Fotoradar + Korek + Wypadek + Droga zamknięta + Roboty drogowe + Zagrożenie + Uszkodzenie nawierzchni + Wyboje + Mgła + Oblodzenie + Zwierzęta na drodze + Wydarzenie drogowe + Wydarzenie drogowe + Wciąż tam + Już tam nie ma + Potwierdzenie zgłoszenia drogowego + Zgłasza, że wypadek został usunięty Kwota zbiorki (w satoszach) 100000 Opisz cel zbiórki @@ -3123,13 +2846,10 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest https://domena.pl/img.jpg Adres strony (opcjonalnie) https://domena.pl - Termin ukończenia (opcjonalnie) Ustaw ostateczny termin Nowy cel zbiórki - Utwórz zbiórkę Prośba o usunięcie Poproś transmitery o całkowite usunięcie wszystkich Twoich danych z okresu do wybranej daty. Działanie to opiera się na standardzie NIP-62 i w niektórych jurysdykcjach ma moc prawną. - Wybierz transmiter Transmitery docelowe WSZYSTKIE TRANSMITERY Spowoduje to wysłanie żądania do WSZYSTKICH przekaźników o usunięcie wszystkich danych powiązanych z Twoim kluczem do wybranej daty. Informacja ta zostanie rozpowszechniona tak szeroko, jak to tylko możliwe. Czynności tej nie można cofnąć. @@ -3145,7 +2865,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Wybierz datę Wybierz godzinę Wyczyść historię - Odśwież Oto Twoje wcześniejsze prośby o usunięcie danych znalezione na podłączonych transmiterach. Transmitery oznaczone w tych wydarzeniach nie powinny przechowywać żadnych Twoich danych sprzed daty wydarzenia. Nie znaleziono wniosków o usunięcie Nie wysłano jeszcze żadnych żądań do usunięcia wydarzeń. @@ -3188,7 +2907,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Zbanuj wydarzenie Aprobuj typ Blokuj IP - Klucz publiczny (hex) ID wydarzenia (hex) Numer typu Adres IP @@ -3199,7 +2917,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Nazwa transmitera Opis transmitera Adres ikony transmitera - Zarządzaj Transmiterem Zarządzaj Członkowie Członkowie %1$s @@ -3270,7 +2987,6 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Opcje pakietu emotikon Moje pakiety emotikonów Emotikony - Przeglądaj zestawy emotikonów Prywatna Prywatna emotikona Publiczne emotikony są widoczne dla wszystkich i pojawiają się w menu odezw oraz w oknie podpowiedzi \":\", jeśli ten pakiet znajduje się na liście emotikonów. @@ -3295,4 +3011,10 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Zrzut „Nowhere” Sztuka na „Nowhere” Forum „Nowhere” + + Usługa lightning odbiorcy w %1$s jest niedostępna. Została obliczona na podstawie adresu lightning \"%2$s\". Błąd: %3$s. Sprawdź, czy serwer jest gotowy i czy adres lightning jest poprawny + Nie można rozwiązać %1$s. Sprawdź, czy jesteś połączony, czy serwer jest gotowy i czy lightning adres %2$s jest poprawny.\n\nWyjątkiem było: %3$s + Błąd przetwarzania pliku JSON z pobierania faktury %1$s. Sprawdź konfigurację lightning użytkownika + Nie można utworzyć faktury. Wiadomość od %1$s: %2$s + Nie można utworzyć faktury od %1$s: Element pr nie został znaleziony w powstałym JSON. diff --git a/amethyst/src/main/res/values-pt-rBR/strings.xml b/amethyst/src/main/res/values-pt-rBR/strings.xml index c551ff1c59..042d68a122 100644 --- a/amethyst/src/main/res/values-pt-rBR/strings.xml +++ b/amethyst/src/main/res/values-pt-rBR/strings.xml @@ -32,8 +32,6 @@ Outro Assédio Violência - Desconhecido - Ícone do relay Autor desconhecido Copiar texto Copiar PubKey do usuário @@ -48,12 +46,9 @@ Denunciar spam/fraude Denunciar representação - Denunciar conteúdo explícito Denunciar comportamento ilegal Reportar Malware - Reportar Mod Malware - Mod Faça login com uma chave privada para poder responder Faça login com uma chave privada para poder impulsionar postagens Faça login com uma chave privada para curtir postagens @@ -67,17 +62,14 @@ Faça login com uma chave privada para poder remover seguidores Você está usando uma chave pública e as chaves públicas são somente de leitura. Faça login com uma chave privada para poder ocultar uma palavra ou frase. Você está usando uma chave pública e as chaves públicas são somente de leitura. Faça login com uma chave privada para poder mostrar uma palavra ou frase. - Você está usando uma chave pública, e chaves públicas são somente leitura. Faça login com uma chave privada para poder alterar as configurações Você está usando uma chave pública, e chaves públicas são somente leitura. Faça login com uma chave privada para poder fazer upload Você está usando uma chave pública, e chaves públicas são somente leitura. Faça login com uma chave privada para poder assinar eventos Descriptografia não autorizada O assinador não autorizou a descriptografia necessária para realizar esta operação. Ative as descriptografias NIP-44 no seu aplicativo de assinatura e tente novamente Assinador não encontrado O aplicativo de assinatura foi desinstalado? Verifique se ele está instalado e com esta conta. Saia e entre novamente se ele foi alterado. - Assinador se comportou de forma inesperada O assinador externo retornou dados estranhos para a solicitação. Pode haver um bug no Amethyst ou no assinador. Zaps - Contagem de visualizações Impulsionar impulsionado editado @@ -90,9 +82,7 @@ Adicionar "respondendo para " " e " - "no canal " Banner do perfil - Pagamento bem-sucedido Erro ao analisar mensagem de erro " Seguindo" " Seguidores" @@ -165,7 +155,6 @@ Saldo insuficiente em um mint que este destinatário aceita. Recarregue sua carteira Cashu primeiro. Disponível para este destinatário: %1$s sats Taxa de rede - seu app de carteira Transação: %1$s Doação Lightning Nota ao Destinatário @@ -179,16 +168,13 @@ Prefixo Visível 😎 Adicionar à postagem - "Erro ao analisar a visualização para %1$s: %2$s" "Visualize a imagem do cartão para %1$s" Artigo - Novo Canal Nome do Canal Meu grupo URL da foto URL da imagem (opcional) Descrição - Descrição não encontrada "Sobre nós.. " O que você está pensando? Escreva uma mensagem… @@ -198,42 +184,25 @@ Criar Renomear Cancelar - Falha ao enviar imagem - Endereço do Relay - Postagens - Bytes Erro Erros Porcentagem de conexões bem-sucedidas ao relay - O número de erros de conexão nesta sessão - Feed principal - Feed de mensagens privadas - Feed Chat Público - Feed Global - Fonte de pesquisa Pesquisar e adicionar usuário - Adicionar um usuário Adicionar um Relay - Nome - Nome (para @marcar) Meu nome de @tag Nome de Exibição Meu nome de exibição McAwesome Ostrich Bem-vindo, Ostrich! Usuário - Meu usuário Sobre mim URL da foto de perfil URL do Banner URL do Site Pronomes - Endereço LN - LN URL (desatualizado) Os relays de origem podem estar desatualizados Aviso de relay desatualizado Salvar no celular - Salvar na Galeria Imagem salva para a galeria O download do vídeo foi iniciado… O download da mídia foi iniciado… @@ -250,15 +219,12 @@ Tirar uma foto Gravar um vídeo Gravar uma mensagem - Gravar uma mensagem Clique e segure para gravar uma mensagem Gravar novamente Gravando Gravando %1$s - Enviando… Erro de upload Falha ao enviar mensagem de voz - Estado de upload inesperado O NIP-95 ainda não é suportado para mensagens de voz Falha no upload de voz: %1$s Nenhum @@ -270,8 +236,6 @@ Usuário não tem um endereço lightning configurado para receber sats "responda aqui.. " Neste chat - Copia o ID do canal (note) para compartilhar - Copiar ID do canal (Note) Editar os dados do canal Entrar Conhecidos @@ -285,7 +249,6 @@ Respostas Suas Galeria - "Seguindo" "Denúncias" "%1$s Relatórios" Mais opções @@ -293,11 +256,8 @@ Site Endereço Lightning Copiar a chave Nsec (sua senha) para backup - Copiar Chave Privada Mostrar código QR de chave privada Mostrar o código QR da chave privada criptografado - Copia a chave public para ser compartilhada - Copiar chave pública (NPub) Enviar uma mensagem direta Muda os dados do usuário Seguir @@ -326,8 +286,6 @@ Como deveríamos chamar você? Não tem uma conta Nostr? Já tem uma conta Nostr? - Criar uma nova conta - Gerar uma nova chave Carregando feed Carregando conta criptografado @@ -343,13 +301,7 @@ Enquete aberta Feed está vazio Atualizar - criado - com descrição de - e foto - mudou nome do canal para Novo perfil de chat: - descrição para - e foto para Sair Desseguir Canal criado @@ -386,7 +338,6 @@ Endereço Nostr nunca agora - segundos h m d @@ -394,7 +345,6 @@ Palavrões / Discurso de ódio Denunciar discurso de ódio Denunciar nudez / pornografia - outros Marcar todos conhecidos como lidos Marcar todas novas solicitações como lidas Marcar todas como lidas @@ -413,8 +363,6 @@ Autenticação falhou A autenticação biométrica falhou ao autenticar o proprietário deste telefone A autenticação biométrica falhou ao autenticar o proprietário deste telefone. Erro: %1$s - Erro - "Criado por %1$s" "Imagem da medalha para %1$s" Imagem do prêmio Você recebeu uma nova medalha @@ -422,7 +370,6 @@ Texto copiado Copiado @npub do autor Copiado ID da nota (@note1) - Selecionar texto "<Não foi possível descriptografar a mensagem privada>\\n\\nVocê foi citado em uma conversa privada/criptografada entre %1$s and %2$s." Adicionar Nova Conta Contas @@ -434,8 +381,6 @@ Selecionar Conta Adicionar Nova Conta Ativar conta - Tem chave privada - Somente leitura, sem chave privada Voltar Selecionar Compartilhar link do navegador @@ -459,14 +404,12 @@ Silenciar tópico Reativar tópico Denunciar - Excluir Não mostar novamente Spam ou golpes Palavrões ou conduta odiosa Personificação maliciosa Nudez ou conteúdo gráfico Comportamento ilegal - Malware Bloquear um usuário ocultará seu conteúdo em seu aplicativo. Suas anotações ainda podem ser visualizadas publicamente, inclusive para as pessoas que você bloquear. Os usuários bloqueados são listados na tela Filtros de segurança. Denunciar abuso @@ -494,7 +437,6 @@ Escolher horário agendado Agendar para… Publica em %1$s - Devia ter sido publicado há %1$s Hora Agendar post Cancelar agendamento @@ -569,7 +511,6 @@ Autor Solicitações Aprovações - Nenhuma comunidade corresponde a este filtro. Regras verificáveis (opcional) Publica um documento de regras legível por máquina (NIP-9B) junto com a comunidade. Clientes que o suportam bloqueiam posts que não correspondem antes de enviar. Tipos de evento permitidos @@ -598,26 +539,15 @@ Adicionar regra de WoT Tamanho máximo global do evento (opcional) Bytes — deixe em branco para sem limite global. - Recebidos - Meus - Concedidos - Descobrir Novo selo - Editar selo Conceder selo Aceitar Rejeitar Remover do perfil - ID do selo (d-tag) - bravura, contribuidor-2025… Nome Nome legível do selo Descrição Por que este selo é concedido? - URL da imagem (1024×1024) - https://exemplo.com.br/badge.png - URL da miniatura (opcional) - https://exemplo.com.br/badge-thumb.png Enviar imagem Escolha uma imagem quadrada para ser a face do seu selo. Carregando selo… @@ -626,7 +556,6 @@ Remover Selo sem título Concedido a %1$d - Você recebeu um selo Selos de perfil Selos · %1$d Escolha quais dos selos que você recebeu aparecerão no seu perfil. @@ -672,9 +601,6 @@ Compartilhe seus treinos Permita que o Amethyst leia treinos concluídos do Health Connect (Samsung Health, Google Fit, Fitbit, Garmin…) e sugira uma publicação. Conectar - Novo treino detectado - Compartilhar - Dispensar Do Health Connect Corrida Caminhada @@ -688,7 +614,6 @@ Dieta Jejum Aplicativos - Aplicativos Fonte: %1$s v%1$s Baixar @@ -697,12 +622,10 @@ Tópicos Links Versão mais recente - Comentários Seja o primeiro a comentar. por Mostrar versões antigas Ocultar versões antigas - Calendários Curtas Chats públicos Pacotes de seguidos @@ -712,18 +635,14 @@ um Nest Palco Aguardando oradores… - Plateia Levantar mão Abaixar mão Conectar áudio - Desconectar Silenciar Ativar som - Conectando… Resolvendo sala Abrindo transporte Negociando áudio - Áudio conectado Reconectando… Ouvir gravação Não foi possível enviar a mensagem @@ -731,9 +650,7 @@ Fechar esta sala? Todos os participantes serão desconectados. A sala aparecerá como FECHADA no feed. Fechar sala - Escolha um horário futuro. Áudio falhou: %1$s - O áudio não está disponível para esta sala Falar Sair do palco Silenciar microfone @@ -741,7 +658,6 @@ Entrando ao vivo… Transmissão falhou: %1$s Falha ao silenciar: %1$s - É necessário acesso ao microfone para falar nesta sala. Abrir configurações Salas de áudio Mantém o áudio tocando enquanto a sala está aberta. @@ -752,7 +668,6 @@ Entrar no nest Anfitrião Abrir - Conversa recente Não há ninguém na sala no momento. %1$d ouvindo Anfitrião @@ -780,8 +695,6 @@ Audiência Mãos Ainda não há ninguém na audiência. - Enviar - Diga algo… Ainda sem mensagens. Seja o primeiro a conversar. Reagir Editar sala @@ -815,7 +728,6 @@ Falha na ação A ação não pôde ser preparada. Compartilhar sala - Minimizar Minimizar para continuar ouvindo Áudio caiu Carregando sala… @@ -848,7 +760,6 @@ Escolha em quais servidores MoQ o Amethyst publica seus nests. A primeira entrada é usada por padrão ao iniciar um novo espaço. Seus servidores Salvo como evento substituível kind-10112 para que outros clientes possam ler sua preferência. - Adicionar servidor de nest URL do relay (WebTransport) URL de autenticação (JWT mint) Adicionar @@ -861,13 +772,11 @@ Remover servidor Ainda não há servidores. Adicione um abaixo ou escolha um recomendado. Vídeos - Artigos Música Listas de reprodução Episódios Podcasts Ver episódios - Episódios Nenhum episódio encontrado ainda %1$d episódio @@ -879,9 +788,6 @@ Título da faixa Artista Nome do artista - URL do áudio - https://… .mp3 - URL da imagem de capa (opcional) Álbum (opcional) Duração em segundos (opcional) Letra ou créditos (opcional) @@ -891,7 +797,6 @@ Adicionar à playlist Você ainda não tem playlists. Use o campo acima para criar uma. Gerenciar todas as playlists - Nova playlist Nome da playlist Criar (playlist sem título) @@ -927,9 +832,6 @@ Excluir lista de favoritos Ver posts Ver artigos - Ver links - Ver hashtags - Você ainda não tem nenhuma lista de favoritos. Toque no botão abaixo para criar uma. Conjuntos de interesses Você ainda não tem nenhum conjunto de interesses. Toque no botão novo abaixo para criar um. Novo conjunto de interesses @@ -948,7 +850,6 @@ Posts privados(%1$s) Posts públicos Posts públicos(%1$s) - Artigos privados Artigos privados(%1$s) Artigos públicos Artigos públicos(%1$s) @@ -975,16 +876,6 @@ Os metadados das listas de favoritos podem ser vistos por qualquer pessoa no Nostr. Somente seus membros privados são criptografados. Mover para público Mover para privado - Serviço Wallet Connect - Use sua chave privada para pagar zaps sem sair do app. Qualquer pessoa com acesso à sua chave privada Nostr poderá gastar o saldo da sua carteira. Guarde apenas os fundos que você pode perder e use um retransmissor privado, se possível. O operador de Relay pode ver seus metadados de pagamentos. - Chave pública do Wallet Connect - Relay do Wallet Connect - Segredo do Wallet Connect - Mostrar chave secreta - chave privada nsec / hex - Conectado - Não conectado - Avançado: inserir detalhes de conexão manualmente Valores Rápidos de Zap Exibido ao pressionar o botão de zap. Toque em um valor para removê-lo. Se deixar vazio, abrirá o diálogo para inserir um valor todas as vezes. Enviar on-chain em vez disso @@ -1016,14 +907,8 @@ Conectar Carteira Ver feed do Relay Valor em Sats - Postar enquete - Campos obrigatórios: - Destinatários Zap - Descrição da enquete principal… - Opção Opção %s Descrição da opção de enquete - Campos opcionais: Zap mínimo Zap máximo Consenso @@ -1032,11 +917,8 @@ Múltipla escolha Data e hora de encerramento da enquete Enquete encerra em %1$s - Fechar depois - dias Impossibilitado de votar A enquete está fechada para novos votos - Valor do Zap Apenas um voto por usuário é permitido neste tipo de enquete "Procurando o evento %1$s" Enviar Zap @@ -1072,11 +954,8 @@ Sem Zap Nenhum traço no Nostr, apenas na Lightning Anônimo - Postar como uma nova identidade descartável. Sua conta não será vinculada a esta resposta. - Esta resposta será postada a partir de uma nova identidade anônima Servidor de arquivos Escolha um servidor para onde enviar este arquivo - LnAddress ou @Usuário Servidores de Mídia Defina seus servidores de upload de mídia preferidos. Usar cache Blossom local @@ -1085,10 +964,8 @@ Cache local não detectado na porta 24242. Apenas armazenar fotos de perfil em cache Restringir o cache local apenas a fotos de perfil. Imagens e vídeos do feed serão buscados diretamente dos servidores originais. - Você não tem nenhum servidor NIP-96. Você pode usar a lista de Amethyst, ou adicionar um abaixo ↓ Você não tem nenhum servidor de Blossom configurado. Você pode usar a lista de Amethyst, ou adicionar um abaixo ↓ Servidores de Mídia Recomendados - Servidores de Mídia Integrados Lista padrão do Amethyst. Você pode adicioná-los individualmente ou adicionar a lista. Usar Lista Padrão Adicionar servidor de mídia @@ -1111,36 +988,21 @@ Hashando Concluído Erro - Seus relays (NIP-95) - Os arquivos são hospedados por seus relays. Novo NIP: verifique se eles suportam Opções de Privacidade - Configuração do Tor/Orbot - Conecte-se através da configuração do Orbot Ajustar Configurações Tor - Desconectar do Orbot/Tor? - Seus dados serão transferidos imediatamente na rede aberta Sim Não - Lista de seguidores Seguindo Seguindo do Usuários Lista Padrão de Seguir - Segue via proxy Perto de mim Global Curada - Xadrez Meus Lista Silenciada Listas de seguidores Essas são listas de seguidores criadas para seu próprio uso. Você pode seguir usuários de forma privada ou pública. - Favoritos com etiqueta - Favoritos gerais - Público - Privado - Misto - Parece que você ainda não tem conjuntos de seguimento.\nToque abaixo para atualizar ou use o botão de adicionar para criar um novo. Novo Adicionar autor à lista de seguidores Adicionar ou remover usuário de listas, ou criar uma nova lista com este usuário. @@ -1149,23 +1011,9 @@ %1$s é um membro privado Adicionar como membro público Adicionar como membro privado - Membros Públicos - Membros Privados - Perfis públicos - Perfis privados - membro - membros - Nenhum membro Vazio - %1$s não está nesta lista %1$s não é membro Suas listas e %1$s - Suas listas - Nenhuma lista de seguidores encontrada, ou você não possui nenhuma. Toque abaixo para atualizar ou use o menu para criar uma nova. - Houve um problema ao buscar: %1$s - Criar nova lista - Criar nova lista %1$s com usuário - Cria um conjunto de seguimento %1$s e adiciona %2$s a ele. Nova lista de seguidores Novo pacote de recomendações Copiar/Clonar lista de seguidores @@ -1185,14 +1033,6 @@ Você está renomeando de para.. Porta padrão é 9050 - ## Conecte-se através do Tor com o Orbot - \n\n1. Instale o [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Iniciar Orbot - \n3. No Orbot, verifique a porta Socks. O padrão usa 9050 - \n4. Se necessário altere a porta no Orbot - \n5. Configure a porta Socks nesta tela - \n6. Pressione o botão Ativar para usar o Orbot como proxy - Porta Socks Orbot Motor Tor Ativo Use a versão interna ou o Orbot @@ -1234,8 +1074,6 @@ Oculte seu IP em todas as conexões Faça o seu próprio Número de porta inválido - Usar Orbot - Desconectar Tor/Orbot Mensagens privadas Notifica você quando chega uma mensagem privada Zaps Recebidos @@ -1292,12 +1130,8 @@ Bluetooth Chamada de voz Chamada de vídeo - Aguardando outros participantes\u2026 Adicionar participante Buscar usuários\u2026 - Falha ao iniciar chamada - Falha ao aceitar chamada - Falha ao criar sessão de chamada Permissão necessária O Amethyst precisa de acesso ao microfone para iniciar uma chamada de voz. Habilite-o nas configurações do aplicativo. O Amethyst precisa de acesso à câmera e ao microfone para iniciar uma chamada de vídeo. Habilite-os nas configurações do aplicativo. @@ -1331,24 +1165,13 @@ O Android pode restringir conexões de relay em segundo plano. Desative a otimização de bateria para o Amethyst para garantir notificações confiáveis. Corrigir agora Notificar: - Entrar na conversa - ID do usuário ou grupo - npub, nevent ou hex - Criar - Entrar Hoje Aviso de conteúdo Aviso: %1$s Esta nota contém conteúdo sensível que algumas pessoas podem achar ofensivo ou perturbador - Sempre ocultar conteúdo sensível - Sempre mostrar conteúdo sensível - Sempre mostrar avisos de conteúdo Ocultar Exibir Avisar - Recomenda: - Filtrar spam de estranhos - Avise quando as postagens tiverem denuncias de seus seguidores Filtrar spam Esconde publicações de desconhecidos que eram exatamente o mesmo por 5 ou mais vezes Adicionar tag de cliente aos meus eventos @@ -1380,22 +1203,17 @@ A quantidade em bytes que foi enviada para este relé, incluindo filtros e eventos A quantidade em bytes que foi recebida deste relé, incluindo filtros e eventos Eventos armazenados - Ocorreu um erro ao tentar obter informações do relay de %1$s Proprietário Usado por Chave de serviço - Executando %1$s - Executando %1$s (%2$s) Versão Programa Contato NIPs Suportados GRASPs compatíveis - Taxas de admissão Entrada Assinatura Publicação - Pagamentos %1$s URL de pagamentos Público-alvo Políticas & links @@ -1403,7 +1221,6 @@ Limitações Países Línguas - Cerquilhas Tópicos Todos os países Todos os idiomas @@ -1418,64 +1235,48 @@ Abrir Leitura Escrita - RTT Rede Tipo NIPs Suportados Requisitos - Última verificação %1$d ms Tipos Aceitos Localização Assinaturas Ativas - Eventos Pendentes na Outbox Assinaturas REQ (%1$d) Assinaturas COUNT (%1$d) Eventos da Outbox (%1$d) - Nenhuma assinatura ativa para este relay %1$d autores %1$d IDs desde %1$s até %1$s limite %1$d - Tamanho da mensagem - Assinaturas - Filtros - Comprimento do ID da assinatura Prefixo mín. Máx. tags de evento - Tamanho do conteúdo Máx. tamanho do conteúdo Descarta mais antigos que Aceita até %1$s no futuro há %1$s - %1$s zeros %1$s bits Retenção de eventos Tamanho do conteúdo Conectividade Controle de acesso Dificuldade mínima de PoW - Autenticação Autenticação obrigatória - Pagamento Pagamento obrigatório Máx. tamanho da mensagem Máx. inscrições Máx. filtros por inscrição Limite máx. (eventos retornados) - Limite padrão (eventos retornados) Comprimento máx. do SubID Token Cashu Mint: %1$s Resgatar - Enviar para Zap Wallet - Abrir na Carteira Cashu Copiar Token Abrir em outro aplicativo Nenhum endereço Lightning definido - Token copiado para a área de transferência AO VIVO DESLIGADA FINALIZADA @@ -1526,7 +1327,6 @@ Estado do Marmot redefinido. Falha ao redefinir o estado do Marmot: %1$s Sempre - Somente wifi WiFi não medida Nunca Concluído @@ -1551,7 +1351,6 @@ Escolha o estilo da publicação Estilo da Galeria de Perfil Escolha o estilo da galeria - Carregar imagem Spammers Silenciado. Clique para ativar o som Som ligado. Clique para silenciar @@ -1563,18 +1362,13 @@ O endereço Nostr foi verificado Endereço Nostr falhou na verificação Verificando o endereço Nostr - Selecionar/desmarcar tudo Padrão Redefinir para os Padrões - Selecione um relay para continuar - Encaminhar Zaps para: - Os clientes que suportam encaminharão zaps para o endereço lightning ou perfil de usuário abaixo, em vez do seu Expor localização como Adicione um geohash da sua localização à postagem. O público saberá que você está a 5 km (3 milhas) do local atual Postagem exclusiva de localização Somente seguidores da localização verão isso. Seus seguidores gerais não verão isso. Postagem exclusiva de Hashtag - Somente seguidores da hashtag verão isso. Seus seguidores gerais não verão isso. Comentar em um site Comentar em um recurso externo %1$d min de leitura @@ -1595,20 +1389,14 @@ Enviar um arquivo de áudio Escolha um MP3, WAV ou FLAC. Ele será enviado ao seu servidor de mídia ao salvar. Arquivo de áudio pronto para envio - Enviando… Enviando capa + áudio e publicando. Isso continuará mesmo se você sair da tela. - Falha no envio: %1$s Carregando localização Sem permissões para localização Adiciona aviso de conteúdo sensível antes de mostrar seu conteúdo. Isso é ideal para qualquer conteúdo NSFW ou conteúdo que algumas pessoas possam considerar ofensivo ou perturbador Motivo (opcional) - Novo recurso - Ativando este modo requer o Amethyst para enviar uma mensagem de NIP-17 (GiftWrapped, Sealed Direct and Group Messages). NIP-17 é novo e a maioria dos clientes ainda não o implementaram. Certifique-se de que o destinatário está usando um cliente compatível. - Ativar Público Grupo Novo Grupo Público ou Privado - Relé Privado Para Assunto @@ -1620,9 +1408,6 @@ Explicação aos membros Mudando o nome dos novos objetivos. Colar da área de transferência - URI NIP-47 inválido - O URI %1$s não é um URI de login NIP-47 válido. - Conectar a nova carteira NWC Carteira não encontrada O Amethyst não conseguiu encontrar nenhum aplicativo de carteira que suporte Nostr Wallet Connect (NWC). \n\nO que você pode fazer: @@ -1638,7 +1423,6 @@ Reproduz automaticamente vídeos e GIFs Reproduzir vídeos automaticamente quando visíveis na tela Mostrar visualizações de URL - Quando carregar imagens Copiar a Pilha Copiar para a Área de Transferência Copiado para a área de transferência @@ -1654,43 +1438,21 @@ Mídia adicionada Mídia adicionada à sua Galeria de Perfil Criado em - Regras - Sobre nós Diretrizes Moderadores Login com Amber O que você está fazendo? - Erro ao analisar mensagem de erro Os votos são ponderados pelo valor do zap. Você pode definir um valor mínimo para evitar spammers e um valor máximo para evitar que grandes zappers assumam o controle da enquete. Use o mesmo valor em ambos os campos para garantir que cada voto tenha o mesmo valor. Deixe em branco para aceitar qualquer valor. Não foi possível enviar o Zap Mensagem ao usuário Mensagem %1$s OK - Falha ao acessar %1$s: %2$s - Falha ao montar NIP-11 url para %1$s: %2$s - Falha ao acessar %1$s: %2$s - Falha ao analisar a resposta do %1$s: %2$s - Relay recusou pedido %1$s: %2$s - Falha ao acessar %1$s: %2$s - Falha ao analisar o resultado de %1$s: %2$s - %1$s falhou com o código %2$s - Ativo para: - Início - Mensagens diretas - Bate-papos - Global - Pesquisa Dividir e encaminhar Zaps Os clientes que suportam dividirão e encaminharão zaps para os usuários adicionados aqui em vez dos seus Pesquisar e adicionar usuário Nome de usuário ou nome de exibição Configuração Lightning ausente O usuário %1$s não possui um endereço lightning configurado para receber sats - Percentual - 25 - Dividindo zaps com - Encaminhando zaps para - Carteira Lightning não encontrada Pago Carteira %1$s Erro ao abrir o aplicativo para assinar evento @@ -1699,7 +1461,6 @@ O codec ou formato não é compatível com este dispositivo (%1$s). Tente abri-lo no seu navegador. Abrir no navegador Solicitação de assinatura rejeitada - Solicitação de assinatura rejeitada Certifique-se de que a aplicação assinante autorizou esta transação Nenhuma carteira encontrada para pagar uma fatura Lightning (Erro: %1$s). Instale uma carteira Lightning para usar zaps Nenhuma carteira encontrada para pagar uma fatura Lightning. Instale uma carteira Lightning para usar zaps @@ -1715,40 +1476,23 @@ Selecione uma Opção Não foi possível pagar a fatura Não foi possível sacar - Não foi possível configurar o Wallet Connect - Erro ao analisar a sequência de conexão NIP-47. Verifique se esta está correta com o seu provedor de carteira: %1$s. Erro: %2$s - Erro ao analisar a sequência de conexão NIP-47. Verifique se esta está correta com o seu provedor de carteira: %1$s. Não foi possível resgatar o Cashu O Mint forneceu a seguinte mensagem de erro: %1$s - Tokens Cashu já foram gastos. Cashu Recebido %1$s sats foram enviados para a sua carteira. (Taxas: %2$s sats) Nenhuma carteira Cashu compatível encontrada no sistema Não foi possível obter a fatura dos servidores do destinatário Seu provedor de Wallet Connect retornou o seguinte erro: %1$s - Não foi possível conectar ao Tor O Tor não está conectando O Amethyst não conseguiu concluir a inicialização do Tor. Usar uma conexão normal (sem Tor) para que o feed possa carregar? Vamos lembrar dessa escolha pela próxima hora e tentar o Tor novamente depois. Usar conexão normal Continuar esperando - O baixar do documento do relay indisponível Não foi possível montar o LNUrl a partir do Endereço Lightning \"%1$s\". Verifique a configuração do usuário - O serviço Lightning do destinatário em %1$s não está disponível. Foi calculado a partir do endereço Lightning \"%2$s\". Erro: %3$s. Verifique se o servidor está funcionando e se o endereço Lightning está correto - Não foi possível resolver %1$s. Verifique se você está conectado, se o servidor está funcionando e se o endereço Lightning %2$s está correto - Não foi possível resolver %1$s. Verifique se você está conectado, se o servidor está funcionando e se o endereço Lightning %2$s está correto.\n\nExceção foi: %3$s - Não foi possível obter a fatura de %1$s Não foi possível obter a fatura de %1$s: %2$s - Erro ao analisar JSON do Endereço Lightning. Verifique a configuração de Lightning do usuário Erro ao analisar JSON do %1$s. Verifique a configuração lightning do usuário - URL de retorno não encontrada na configuração do servidor de endereço Lightning do usuário URL de retorno de chamada não encontrado da resposta %1$s - Erro ao analisar o pedido de fatura do endereço Lightning. Verifique a configuração de Lightning do usuário - Erro ao analisar JSON da busca de fatura %1$s. Verifique a configuração de iluminação do usuário Quantidade incorreta na fatura (%1$s sats) de %2$s. Deveria ser %3$s Não foi possível criar uma fatura Lightning antes de enviar o zap. A carteira Lightning do destinatário enviou o seguinte erro: %1$s - Não foi possível criar uma fatura com raios. Mensagem do %1$s: %2$s - Não foi possível criar uma fatura Lightning antes de enviar o zap. O elemento pr não foi encontrado no JSON resultante. - Não foi possível criar uma fatura lightning a partir de %1$s: Elemento pr não encontrado no JSON resultante. Usuário somente leitura Nenhuma configuração de reações Notificações @@ -1774,13 +1518,11 @@ Envie uma mensagem para o vendedor Oi %1$s, ainda está disponível? Olá, ainda está disponível? - Vender um Item Título iPhone 13 Condição Categoria Preço (em Sats) - 1000 Localização Cidade, Estado, País Novo @@ -1809,20 +1551,13 @@ Outros Não foi possível carregar a multimídia Não foi possível abrir o arquivo compactado - Erro ao comprimir a mídia: %1$s Erro ao carregar: %1$s O servidor não forneceu uma URL após o upload Não foi possível baixar o arquivo de mídia carregado do servidor Não foi possível verificar o arquivo baixado após o upload: %1$s - Não foi possível preparar o arquivo local para enviar: %1$s Falha ao acessar %1$s: %2$s - Falha ao enviar: %1$s Falha ao excluir: %1$s Mídia muito grande para NIP-95 - Não foi possível carregar a miniatura - Não foi possível preparar informações do cabeçalho: %1$s - Compressão cancelada - Compressão falhou ao retornar um arquivo Criptografar arquivos Criptografar arquivos antes do upload para privacidade. Alguns servidores podem não aceitar arquivos criptografados em contas gratuitas. Falha no upload criptografado @@ -1849,27 +1584,18 @@ Não foi possível remover os metadados do AVIF: %1$s Editar rascunho Entrar com Código QR - Rota Início - Buscar Descobrir Mensagens Notificações - Global Vídeos Curtos - Imagens - Treinos Calendários Listas de calendário Xadrez Carteira - Saldo Enviar Receber Transações - Nenhuma carteira conectada - Configure uma conexão Nostr Wallet Connect (NWC) nas configurações de zap para usar a carteira. - Configurar Carteira sats Cole uma fatura BOLT-11 Pagar @@ -1897,8 +1623,6 @@ Isto removerá a conexão da carteira. Você sempre pode adicioná-la novamente mais tarde. Nome da carteira Minha carteira - Suas carteiras - Gerenciar carteiras Nenhuma carteira conectada Conecte uma ou mais carteiras NWC para enviar e receber pagamentos. Adicionar conexão NWC @@ -1917,12 +1641,9 @@ URL do mint Remover mint Histórico - Editar carteira Chave de nutzap (avançado) Uma chave privada separada, usada apenas para receber nutzaps NIP-61. Não é a chave da sua identidade Nostr. Gerar uma nova chave - Invalidará quaisquer nutzaps pendentes vinculados à chave atual. - Manter chave atual Chave privada P2PK (hex) Editar carteira Cashu Salvar alterações @@ -1938,7 +1659,6 @@ Mints populares Mints correspondentes - Recomendar este mint Receber Enviar LN Enviar token @@ -1998,10 +1718,6 @@ Salvar Renomear Renomear carteira - Editar - URI de conexão NWC inválida - Mover para cima - Mover para baixo Transações on-chain Nenhum endereço on-chain disponível para esta conta. Nenhum backend on-chain configurado. @@ -2076,17 +1792,13 @@ Pagamento enviado (%1$d de %2$d recibo publicado), mas o próximo recibo não pôde ser publicado Pagamento enviado (%1$d de %2$d recibos publicados), mas o próximo recibo não pôde ser publicado - Filtros de Segurança Importar Seguidos Novo Post Novos Vídeos Curtos: imagens ou vídeos Nova Nota da Comunidade Produto Novo - Nova Postagem Geo-Exclusiva Novo artigo Nova Enquete - Nova Enquete Zap - Nova Enquete Regular Nova Foto Novo evento de calendário Editar evento de calendário @@ -2101,8 +1813,6 @@ Dia Próximos Passados - Ainda não há eventos de calendário (futuros ou passados) do feed selecionado. - Ainda não há listas de calendário. Seu calendário está vazio Eventos compartilhados por pessoas que você segue aparecem aqui. Toque no botão + para criar os seus. Ainda não há listas @@ -2129,8 +1839,6 @@ Próxima semana Dia anterior Próximo dia - Sem eventos neste dia - Sem eventos Continua Dia %1$d de %2$d Adicionar ao calendário do telefone @@ -2190,7 +1898,6 @@ A imagem escolhida não pôde ser enviada. Tente novamente ou cole uma URL. Participantes (%1$d) Buscar nome, npub ou nip-05 - Insira um npub… válido ou pubkey hex de 64 caracteres. Remover participante Lembretes de calendário Enviar lembretes @@ -2211,10 +1918,7 @@ Detalhes do evento Novo Vídeo Curto Novo Vídeo Longo - Título Resumo (opcional) - URL da imagem de capa (opcional) - Escreva seu artigo em markdown… Pré-visualização Editar Adicionar imagem de cabeçalho @@ -2298,18 +2002,14 @@ Repassar %1$s Expandir lista de repasse Opções de nota - Seletor de lista de repasse Enquete Desativar enquete Fatura de Bitcoin Cancelar Fatura de Bitcoin - Cancelar Venda de Item Avaliador Zap Cancelar Avaliador Zap Localização Remover Localização - Divisão Zap - Cancelar Divisão Zap Adicionar aviso de conteúdo Remover aviso de conteúdo Adicionar data de expiração @@ -2324,11 +2024,8 @@ Endereço inválido O Amethyst recebeu um URI para abrir, mas esse URI era inválido: %1$s Relés da Caixa de Entrada de DM - Relés: %1$s - Usando Relés Regulares Configurar seus relés de Caixa de Entrada Privada Esta configuração permite que todos saibam quais relés usar ao enviar mensagens para você. Sem eles, você pode perder algumas mensagens. - Boas opções são:\n - inbox.nostr.wine (pago)\n - you.nostr1.com (relés pessoais - pago) Opções boas são:\n - auth.nostr1.com (free)\n - inbox.nostr.wine (paid)\n - relay.0xchat.com (gratuito) Insira entre 1–3 relés para servir como sua caixa de entrada privada. Relés de Caixa de Entrada de DM devem aceitar qualquer mensagem de qualquer pessoa, mas permitir apenas você a baixá-las. Configurar agora @@ -2348,7 +2045,6 @@ Criar uma lista de relays especificamente projetada para receber notificações é essencial para sua experiência no Nostr. Insira entre 1–3 relays que recebam notificações para você. Certifique-se de que eles não exijam pagamento ou rede de confiança do remetente, caso contrário você receberá notificações apenas de pagadores ou usuários de longo prazo. Boas opções são:\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social - Envio de DM Configurações de Relay Reordenar relay Relés Públicos de Casa @@ -2365,12 +2061,8 @@ Relays onde seus MLS KeyPackages são publicados (MIP-00). Outros usuários os buscam para convidá-lo para chats em grupo Marmot. Insira de 1 a 3 relays que aceitem eventos KeyPackage seus e permitam leitura pública. Relés privados Insira entre 1–3 retransmissores para armazenar eventos que ninguém mais possa ver, como seus rascunhos e/ou configurações de aplicativo. Idealmente, esses relés são locais ou requerem autenticação antes de baixar o conteúdo de cada usuário. - Relés Gerais - Amethyst usa esses relés para baixar postagens para você. Relays conectados Lista atual de relays em uso - Relés Recomendados - Adicione os seguintes retransmissores à sua lista de Relés Gerais, a fim de receber mensagens dos usuários listados. Relés de Pesquisa Lista de relés para usar em pesquisas e marcação de usuários. A marcação e a pesquisa não funcionarão se não houver opções disponíveis. Relés locais @@ -2405,11 +2097,8 @@ Esta versão foi trazida a você por: Versão %1$s Obrigado! - Limite máximo Gravações Restritas Forkado de - FORK - Repositório Git: %1$s Site: Clonar: Aberto @@ -2434,20 +2123,13 @@ Editar artigo Editar postagem Proposta para melhorar sua postagem - Resumo das alterações - Correções rápidas… Aceitar a Sugestão Iniciar o vídeo em um popup Baixar - Letras ligadas - Letras desligadas - Mensagem selada desligada. Clique para ligar a mensagem selada - Mensagem selada ligada. Clique para desligar a mensagem selada Enviar Reproduzir nome de usuário como áudio Piones Escanear código QR - Navegar para o provedor de carteira de terceiros Alby Selecionar data Não é possível responder uma nota em rascunho Não é possível citar uma nota em rascunho @@ -2489,23 +2171,18 @@ Armazenamento insuficiente - O servidor não possui armazenamento suficiente para processar a requisição com sucesso Loop detectado - O servidor detecta um loop infinito enquanto processa a requisição Autenticação de rede necessária - O cliente deve ser autenticado para acessar a rede - Servidores NIP-96 - Adicione quantos servidores você desejar. Você pode escolher qual usar mais tarde quando enviar sua foto Servidores de Blossom Adicione quantos servidores você desejar. Você pode escolher qual usar mais tarde quando enviar sua foto Adicionar um servidor NIP-96 Adicionar um Servidor de Blossom Apagar tudo Você tem certeza de que deseja excluir todos os rascunhos? - Pilha: Arquivo Torrent Baixar Falha ao abrir o arquivo Nenhum aplicativo torrent instalado para abrir e baixar o arquivo. O evento não tem informações suficientes para criar um link magnético - Minhas listas/conjuntos Minhas listas - Usuários Selecione uma lista para filtrar o feed Feeds Hashtags @@ -2536,7 +2213,6 @@ Mensagem Privada Mensagem pública Relé de chat - O relé a qual todos os usuários deste chat se conectam Compartilhar imagem… Não é possível compartilhar a imagem, por favor tente novamente mais tarde… Compartilhar vídeo… @@ -2583,7 +2259,6 @@ Gostaria de enviar o relatório de falha recente para o Amethyst em uma DM? Nenhuma informação pessoal será compartilhada Enviar Esta mensagem desaparecerá em %1$s - Esta mensagem desaparecerá em %1$d dias Selecionar assinador Já está na lista Membros privados @@ -2605,7 +2280,6 @@ Nome do pacote Novo nome do pacote Descrição do pacote - Nova descrição do pacote Transmitir lista Transmitir pacote de recomendações Excluir lista @@ -2619,13 +2293,9 @@ Recolher Expandir Tentar novamente falhas (%1$d) - +%1$d envios adicionais - " (%1$d em andamento)" - %1$d/%2$d relés Tempo esgotado Tentando novamente… Tentar novamente - Ver Dispensar %1$d/%2$d Enviando @@ -2651,7 +2321,6 @@ Reiniciar Aceitar Recusar - Novo Jogo Novo Jogo de Xadrez Carregando jogo… Jogo não encontrado @@ -2806,23 +2475,13 @@ Perfil para importar busca por nome, npub1…, alice@example.com Suporta npub, NIP-05, hex e Namecoin (.bit / d/ / id/) - Buscar lista de seguidos Dica %1$d contas encontradas %1$d selecionados - Resolvido via Namecoin - Seguindo %1$d contas agora - Seu feed está pronto. - Pular - Buscar outro Seguir %1$d contas - Importar mais - Continuar Pular por agora - Resolvendo %1$s… Buscando lista de seguidos… Nenhum seguido encontrado - Seguindo %1$d contas… "Digite o perfil de um amigo ou líder de comunidade. Você pode usar o npub, endereço NIP-05 ou um nome Namecoin como alice@example.bit ou id/alice para identidades verificadas por blockchain." Selecionar tudo %1$d%% de disponibilidade @@ -2830,7 +2489,6 @@ Testar Conexão Testando servidores… Conectado - Falhou Resultados do Teste Diagnóstico Último teste @@ -2843,9 +2501,6 @@ Confiar Rejeitar Sincronização de Relays - Sincronização de Relays - Republique seus eventos em todos os relays conhecidos para manter seus relays de saída, entrada e DM atualizados. Requer Wi-Fi — pode consumir muitos dados. - Abrir sincronização de relays… O que isso faz Esta ferramenta verifica todos os relays que seu app conhece e redistribui seus eventos para os destinos corretos: Baixar todos os eventos que você criou e enviá-los para seus relays de saída. @@ -2855,14 +2510,9 @@ Usar dados móveis? Iniciar sincronização Iniciar mesmo assim (dados móveis) - Pausar - Retomar - Recomeçar Cancelar Relés: %1$d / %2$d Eventos redistribuídos: %1$d novos de %2$d enviados e %3$d recebidos - Sincronização pausada - %1$d de %2$d relays concluídos — %3$d eventos redistribuídos até agora. Toque em Retomar para continuar. Sincronização concluída %1$d eventos encaminhados para relays de destino de %2$d recebidos. %1$d eventos aceitos como novos pelos relays de destino. @@ -2877,16 +2527,13 @@ env. %1$s receb. %1$s novos %1$s - nenhum evento Explorador Bitcoin (OTS) - eventos eventos de você eventos para você eventos pesquisáveis DMs perfils listas de saída - configurações de Relay Visto pela última vez há %1$s Visto pela última vez em %1$s (há %2$s) Visto agora mesmo @@ -2944,7 +2591,6 @@ Procurando dispositivos na sua Wi-Fi… Upload HLS - Publique HLS multi-resolução em seu servidor de mídia Escolher um vídeo Seu vídeo será transcodificado em múltiplas resoluções para que os espectadores tenham reprodução suave em qualquer conexão. Trocar @@ -2959,10 +2605,6 @@ H.265 não disponível neste dispositivo — usando H.264. Versões Resolução da origem: %1$d×%2$d - Será gerado: %1$s - (%1$s ignorado — acima da origem) - %1$d kbps - acima da origem — será ignorado Publicar vídeo HD Publicando “%1$s”… Transcodificando %1$s @@ -2974,7 +2616,6 @@ Vídeo publicado Seu vídeo HD está publicado no Nostr. Algo deu errado - Ver nota Concluído Tentar novamente Ações do pacote @@ -2989,30 +2630,21 @@ Atestação Válida Inválida - Aceita - Rejeitada Verificando - Verificada Revogada Válida a partir de %1$s Válida até %1$s Solicitação de atestação - Solicitando atestação para um evento Recomendação do atestante Recomendado para tipos: Competência do atestante - Competente na verificação de tipos: %1$s - Atesta Solicita atestação para Intervalo de datas De Até Agora Todo o período - Última sincronização: %1$s - Desde a última sincronização Marcadores Web - Nenhum marcador web ainda. Toque em + para adicionar. Adicionar Marcador Web Editar Marcador Web URL @@ -3051,13 +2683,10 @@ https://exemplo.com.br/imagem.jpg URL do site (opcional) https://exemplo.com - Prazo (opcional) Definir um prazo Nova Meta - Criar Meta Pedido para Desaparecer Solicite aos relays que excluam permanentemente todos os seus dados até a data selecionada. Esta ação é baseada no NIP-62 e é legalmente vinculante em algumas jurisdições. - Selecionar um relay Relays Alvo TODOS OS RELAYS Isso solicitará a TODOS os relays que excluam tudo associado à sua chave até a data selecionada. Este evento será transmitido o mais amplamente possível. Esta ação não pode ser desfeita. @@ -3073,7 +2702,6 @@ Selecionar data Selecionar hora Histórico de Desaparecimento - Atualizar Estes são seus eventos passados de Pedido para Desaparecer encontrados nos relays conectados. Relays marcados nesses eventos não devem manter nenhum dos seus dados anteriores à data do evento. Nenhum pedido de desaparecimento encontrado Você ainda não enviou nenhum evento de Pedido para Desaparecer. @@ -3116,7 +2744,6 @@ Banir Evento Permitir Tipo Bloquear IP - Chave pública (hex) ID do Evento (hex) Número do tipo Endereço IP @@ -3127,7 +2754,6 @@ Nome do Relay Descrição do Relay URL do Ícone do Relay - Gerenciar Relay Gerenciar Membros Membros de %1$s @@ -3198,7 +2824,6 @@ Ações do pacote de emoji Meus pacotes de emojis Emojis - Procurar pacotes de emojis Privado Emoji privado Emojis públicos são visíveis para todos e aparecem no seu menu de reações e no seletor de autocompletar \":\" quando este pacote está na sua lista de emojis. @@ -3223,4 +2848,10 @@ Nowhere Drop Nowhere Arte Nowhere Fórum + + O serviço Lightning do destinatário em %1$s não está disponível. Foi calculado a partir do endereço Lightning \"%2$s\". Erro: %3$s. Verifique se o servidor está funcionando e se o endereço Lightning está correto + Não foi possível resolver %1$s. Verifique se você está conectado, se o servidor está funcionando e se o endereço Lightning %2$s está correto.\n\nExceção foi: %3$s + Erro ao analisar JSON da busca de fatura %1$s. Verifique a configuração de iluminação do usuário + Não foi possível criar uma fatura com raios. Mensagem do %1$s: %2$s + Não foi possível criar uma fatura lightning a partir de %1$s: Elemento pr não encontrado no JSON resultante. diff --git a/amethyst/src/main/res/values-pt-rPT/strings.xml b/amethyst/src/main/res/values-pt-rPT/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-pt-rPT/strings.xml +++ b/amethyst/src/main/res/values-pt-rPT/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-ru-rRU/strings.xml b/amethyst/src/main/res/values-ru-rRU/strings.xml index 1b3c9e06cb..87e672f442 100644 --- a/amethyst/src/main/res/values-ru-rRU/strings.xml +++ b/amethyst/src/main/res/values-ru-rRU/strings.xml @@ -28,8 +28,6 @@ Другие Домогательство Насилие - Неизвестно - Иконка релея Неизвестный автор Копировать текст Копировать ID автора @@ -41,12 +39,9 @@ Сообщить о спаме / мошенничестве Сообщить о выдаче себя за другого - Сообщить о запрещённом контенте Сообщить о незаконных действиях Сообщить об вредоносных ПО - Сообщить о моде Вирус - Мод Вы используете публичный ключ, они - только для чтения. Войдите в систему приватным ключом, чтобы ответить Вы используете публичный ключ, они - только для чтения. Войдите в систему приватным ключом, чтобы продвигать записи Вы используете публичный ключ, они - только для чтения. Войдите с приватным ключом, чтобы лайкать посты @@ -59,13 +54,11 @@ Вы используете публичный ключ, они - только для чтения. Войдите в систему приватным ключом, чтобы иметь возможность отписаться Вы используете публичный ключ, они - только для чтения. Войдите в систему приватным ключом, чтобы иметь возможность скрыть слово или предложение Вы используете публичный ключ, они - только для чтения. Войдите в систему приватным ключом, чтобы иметь возможность показать слово или предложение - Вы используете публичный ключ. Войдите приватным ключом, чтобы редактировать Вы используете публичный ключ, они - только для чтения. Войдите в систему приватным ключом, чтобы иметь возможность загружать Вы используете публичный ключ. Войдите приватным ключом, чтобы редактировать Подписчик не авторизовал расшифровку, необходимую для выполнения этой операции. Активируйте расшифровки NIP-44 в приложении для подписчика и попробуйте еще раз Подпись не найдена Запы - Просмотры Продвинуть изменено изменить #%1$s @@ -76,9 +69,7 @@ Добавить "ответ на " " и " - "в канале " Баннер профиля - Платёж выполнен Ошибка при анализе сообщения об ошибке " Подписок" " Подписчиков" @@ -99,16 +90,13 @@ Мое скрытое сообщение Видимый префикс Добавить к посту - "Не удалось создать предпросмотр для %1$s : %2$s" "Предпросмотр для %1$s" Статья - Новый канал Название канала Моя новая группа URL фотографии Url (необязательно) Описание - Описание не найдено "О нас.. " Что нового? Написать сообщение… @@ -118,41 +106,24 @@ Создать Переименовать Отменить - Не удалось загрузить фото - Адрес релея - Записи - Байт Ошибка Ошибки Процент успешных соединений к трансляции - Количество ошибок соединения в этой сессии - Домашняя лента - Лента личных сообщений - Лента чатов - Глобальная лента - Поиск Найти и добавить пользователя - Добавить пользователя Добавить релей - Имя - Имя Мой @тег Отображаемое имя Моё отображаемое имя Ostrich McAwesome Добро пожаловать Ostrich! Никнейм - Мой никнейм Обо мне URL фотографии URL баннера URL сайта Местоимения - LN адрес - LN URL (устаревш.) Ретрансляторы могут быть устаревшими Сохранить в телефон - Сохранить в галерею Фото сохранено в галерею Скачивание видео было запущено… Загрузка вложений было запущено… @@ -165,15 +136,12 @@ Сделать фото Снять видео Записать сообщение - Записать сообщение Нажмите и удерживайте, чтобы записать сообщение Перезаписать Запись Запись %1$s - Загрузка… Ошибка загрузки Неудалось загрузить голосовое сообщение - Неожиданное состояние загрузки Отсутствует Глубокий Высокий @@ -182,8 +150,6 @@ Обрабатывает ваш голос. Внимание: основные изменения тона потенциально могут быть отменены определенными слушателями. Пользователь не установил Lightning адрес для получения чаевых "ответить.. " - Копирует ID записи для отправки - Скопировать ID канала (записи) Редактирует метаданные канала Войти Известные @@ -196,7 +162,6 @@ Ответы Ваш Галерея - "Подписок" "Жалоб" "%1$s Отчётов" Больше опций @@ -204,11 +169,8 @@ Сайт Lightning адрес Копирует Nsec ID (ваш пароль) для резервного копирования - Скопировать приватный ключ Показать QR-код приватного ключа Показать зашифрованный QR-код приватного ключа - Копирует публичный ключ для отправки - Скопировать публичный ключ (NPub) Отправить сообщение Редактирует метаданные пользователя Подписаться @@ -237,8 +199,6 @@ Как нам вас называть? Нет учетной записи Nostr? Уже есть учетная запись Nostr? - Создать новый аккаунт - Сгенерировать ключ Загрузка ленты Загрузка аккаунта @@ -249,13 +209,7 @@ Открыть опрос Лента пуста. Обновить - создал(а) - с описанием - и фото - сменил(а) название на Новый профиль чата: - описание на - и фото на Выйти Отписаться Канал создан @@ -272,7 +226,6 @@ Не переводить с %1$s никогда сейчас - секунды ч м д @@ -280,7 +233,6 @@ Брань / Оскорбления Сообщить об оскорблениях Сообщить о наготе / порно - другое Отметить все известные прочитанными Отметить все новые прочитанными Отметить всё прочитанным @@ -295,23 +247,18 @@ Ошибка входа Биометрия не смогла подтвердить личность владельца этого телефона Биометрия не смогла подтвердить личность владельца этого телефона. Ошибка: %1$s - Ошибка - "Создан %1$s" "Картинка значка-награды %1$s" Вы получили в награду новый значок Значок награда выдан Копировать текст ID (npub) автора скопирован ID записи (note1) скопирован - Выделить текст "<Не удалось расшифровать сообщение!>\n\nВас упомянули в приватном/зашифрованном чате между %1$s и %2$s." Добавить аккаунт Аккаунты Выбор аккаунта Добавить аккаунт Текущий аккаунт - С приватным ключом - Только чтение, без приватного ключа Назад Выделить Поделиться ссылкой @@ -329,14 +276,12 @@ Удалить @string/block_only Пожаловаться - Удалить Больше не показывать @string/spam @string/profanity_hateful_speech @string/impersonation @string/nudity @string/illegal_behavior - Вредоносное ПО Блокировать и скрыть пользователя для вас. Ваши записи останутся видны тем, кого вы заблокировали. Блокированные пользователи перечислены на экране «Фильтры безопасности». Пожаловаться @@ -366,7 +311,6 @@ Закрепить в профиле Новый список закладок Удалить список закладок - Приватные статьи Удалить закладку из списка Добавить закладку в список Добавить в Публичные закладки @@ -375,26 +319,11 @@ Метаданные списков закладок могут быть видны любым пользователем Nostr. Только ваши частные участники зашифрованы. Переместить в публчный Переместить в личные - Служба Wallet Connect - Позволяет оплачивать запы с помощью секрета, не выходя из приложения. Храните секрет в безопасности и по возможности используйте приватный релей - Публичный ключ Wallet Connect - Релей Wallet Connect - Секрет Wallet Connect - Показать секрет - nsec / приватный ключ в hex - Подключено - Дополнительно: ввести детали соединения вручную Определяет, как отображается ваша личность, когда вы отправляете зап. Подключить кошелек Сумма взноса в sat - Отправить опрос - Обязательные поля: - Получатели запов - Описание опроса - Вариант ответа Вариант %s Описание варианта - Опциональные поля: Минимальный зап Максимальный зап Консенсус @@ -402,11 +331,8 @@ Один вариант ответа Несколько вариантов ответа Дата закрытия опроса & Время - Закрытие после - дней Невозможно проголосовать Опрос закрыт - Сумма запа В этом опросе можно голосовать только один раз "Поиск события %1$s" Добавить публичное сообщение @@ -436,36 +362,17 @@ Никто не видит отправителя платежа Не-зап Без следа в Nostr, обычный Lightning платеж - Опубликовать в качестве одноразовой идентификации. Ваша учетная запись не будет связана с этим ответом. - Этот ответ будет опубликован от новой анонимной идентификации Сервер для загрузки Выберите сервер для загрузки этого файла - LnAddress или @User Список Amethyst. Вы можете добавить его индивидуально или добавить список. Загрузка - Ваши релеи (NIP-95) - Файл хранится на ваших релеях. Новый NIP: может не работать в других клиентах - Настройка Tor/Orbot - Подключение через настройки Orbot - Отключиться от Orbot/Tor? Да Нет - Подписки Все подписки Глобально - ## Подключение через Tor с помощью Orbot - \n\n1. Установите [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Запустите Orbot - \n3. В Orbot проверьте Socks порт. По умолчанию используется 9050 - \n4. При необходимости измените порт в Orbot - \n5. Настройте порт Socks на этом экране - \n6. Нажмите кнопку активации, чтобы использовать Orbot как прокси-сервер - Порт Orbot Socks Денежные операции Неверный порт - Исп. Orbot - Отключить Tor/Orbot Личные сообщения Уведомления о входящих сообщениях Запы @@ -475,24 +382,12 @@ за %1$s Уведомление: - npub, nevent или hex - Войти Сегодня - Всегда скрывать чувствительный контент - Всегда показывать чувствительный контент - Рекомендации: - Фильтр спама от незнакомцев - Предупреждать, когда есть репорты на подписчиков Владелец Версия Контакты Языки - Теги - Длина сообщения - Подписки - Фильтры Копировать токен - Скопирован в буфер обмена В ЭФИРЕ ОФЛАЙН ЗАКОНЧЕН @@ -511,7 +406,6 @@ (translated) row titles. Marked translatable="false" so protocol terms (blossom, nsec, negentropy, …) stay searchable in every locale and aren't sent to translators. --> Всегда - Только с Wi-Fi Никогда Как в системе Светлая @@ -535,10 +429,7 @@ Автоматически загружать изображения и GIF Автоматически воспроизводить видео и GIF Копировать в буфер обмена - Правила Обновить статус - Чаты - Поиск Скрытые слова Добавить новое слово или предложение Картинка профилей @@ -604,4 +495,5 @@ + diff --git a/amethyst/src/main/res/values-ru-rUA/strings.xml b/amethyst/src/main/res/values-ru-rUA/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-ru-rUA/strings.xml +++ b/amethyst/src/main/res/values-ru-rUA/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-ru/strings.xml b/amethyst/src/main/res/values-ru/strings.xml index 2c8f565159..f24ee05437 100644 --- a/amethyst/src/main/res/values-ru/strings.xml +++ b/amethyst/src/main/res/values-ru/strings.xml @@ -15,8 +15,6 @@ Спам Выдача себя за другое лицо Незаконные действия - Неизвестно - Иконка релея Неизвестный автор Копировать текст Копировать ID автора @@ -27,7 +25,6 @@ Сообщить о спаме / мошенничестве Сообщить о выдаче себя за другого - Сообщить о запрещённом контенте Сообщить о незаконных действиях Вы используете публичный ключ, они - только для чтения. Войдите в систему приватным ключом, чтобы ответить Вы используете публичный ключ, они - только для чтения. Войдите в систему приватным ключом, чтобы продвигать записи @@ -39,16 +36,13 @@ Вы используете публичный ключ, они - только для чтения. Войдите в систему приватным ключом, чтобы иметь возможность скрыть слово или предложение Вы используете публичный ключ, они - только для чтения. Войдите в систему приватным ключом, чтобы иметь возможность показать слово или предложение Запы - Просмотры Продвинуть Цитата Новая сумма в sat Добавить "ответ на " " и " - "в канале " Баннер профиля - Платёж выполнен Ошибка при анализе сообщения об ошибке " Подписок" " Подписчиков" @@ -63,9 +57,7 @@ Большое спасибо! Сумма в sat Отправить - "Не удалось создать предпросмотр для %1$s : %2$s" "Предпросмотр для %1$s" - Новый канал Название канала Моя новая группа URL фотографии @@ -76,35 +68,20 @@ Сохранить Создать Отменить - Не удалось загрузить фото - Адрес релея - Записи - Байт Ошибки - Домашняя лента - Лента личных сообщений - Лента чатов - Глобальная лента - Поиск Добавить релей Отображаемое имя Моё отображаемое имя Никнейм - Мой никнейм Обо мне URL фотографии URL баннера URL сайта - LN адрес - LN URL (устаревш.) Фото сохранено в галерею Не удалось сохранить фото Загрузить фото - Загрузка… Пользователь не установил Lightning адрес для получения чаевых "ответить.. " - Копирует ID записи для отправки - Скопировать ID канала (записи) Редактирует метаданные канала Войти Известные @@ -114,16 +91,12 @@ Обсуждения Записи Ответы - "Подписок" "Жалоб" Больше опций " Релеев" Сайт Lightning адрес Копирует Nsec ID (ваш пароль) для резервного копирования - Скопировать приватный ключ - Копирует публичный ключ для отправки - Скопировать публичный ключ (NPub) Отправить сообщение Редактирует метаданные пользователя Подписаться @@ -143,19 +116,12 @@ Нужно принять условия использования Нужно ввести ключ Войти - Сгенерировать ключ Загрузка ленты Загрузка аккаунта "Не удалось загрузить ответы: " Повторить Лента пуста. Обновить - создал(а) - с описанием - и фото - сменил(а) название на - описание на - и фото на Выйти Отписаться Канал создан @@ -178,7 +144,6 @@ Брань / Оскорбления Сообщить об оскорблениях Сообщить о наготе / порно - другое Отметить все известные прочитанными Отметить все новые прочитанными Отметить всё прочитанным @@ -188,23 +153,18 @@ Ошибка входа Биометрия не смогла подтвердить личность владельца этого телефона Биометрия не смогла подтвердить личность владельца этого телефона. Ошибка: %1$s - Ошибка - "Создан %1$s" "Картинка значка-награды %1$s" Вы получили в награду новый значок Значок награда выдан Копировать текст ID (npub) автора скопирован ID записи (note1) скопирован - Выделить текст "<Не удалось расшифровать сообщение!>\n\nВас упомянули в приватном/зашифрованном чате между %1$s и %2$s." Добавить аккаунт Аккаунты Выбор аккаунта Добавить аккаунт Текущий аккаунт - С приватным ключом - Только чтение, без приватного ключа Назад Выделить Поделиться ссылкой @@ -221,7 +181,6 @@ Удалить @string/block_only Пожаловаться - Удалить Больше не показывать @string/spam @string/profanity_hateful_speech @@ -246,29 +205,14 @@ Добавить в Публичные закладки Убрать из Личных закладок Убрать из Публичных закладок - Служба Wallet Connect - Позволяет оплачивать запы с помощью секрета, не выходя из приложения. Храните секрет в безопасности и по возможности используйте приватный релей - Публичный ключ Wallet Connect - Релей Wallet Connect - Секрет Wallet Connect - Показать секрет - nsec / приватный ключ в hex Сумма взноса в sat - Отправить опрос - Обязательные поля: - Получатели запов - Описание опроса Вариант %s Описание варианта - Опциональные поля: Минимальный зап Максимальный зап Консенсус - Закрытие после - дней Невозможно проголосовать Опрос закрыт - Сумма запа В этом опросе можно голосовать только один раз "Поиск события %1$s" Добавить публичное сообщение @@ -297,29 +241,12 @@ Не-зап Без следа в Nostr, обычный Lightning платеж Сервер для загрузки - LnAddress или @User - Ваши релеи (NIP-95) - Файл хранится на ваших релеях. Новый NIP: может не работать в других клиентах - Настройка Tor/Orbot - Подключение через настройки Orbot - Отключиться от Orbot/Tor? Да Нет - Подписки Все подписки Глобально - ## Подключение через Tor с помощью Orbot - \n\n1. Установите [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Запустите Orbot - \n3. В Orbot проверьте Socks порт. По умолчанию используется 9050 - \n4. При необходимости измените порт в Orbot - \n5. Настройте порт Socks на этом экране - \n6. Нажмите кнопку активации, чтобы использовать Orbot как прокси-сервер - Порт Orbot Socks Неверный порт - Исп. Orbot - Отключить Tor/Orbot Личные сообщения Уведомления о входящих сообщениях Запы @@ -328,24 +255,12 @@ От %1$s за %1$s Уведомление: - npub, nevent или hex - Войти Сегодня - Всегда скрывать чувствительный контент - Всегда показывать чувствительный контент - Рекомендации: - Фильтр спама от незнакомцев - Предупреждать, когда есть репорты на подписчиков Владелец Версия Контакты Языки - Теги - Длина сообщения - Подписки - Фильтры Копировать токен - Скопирован в буфер обмена В ЭФИРЕ ОФЛАЙН ЗАКОНЧЕН @@ -360,7 +275,6 @@ Добавляет предупреждение о чувствительном содержимом перед показом Настройки Всегда - Только с Wi-Fi Никогда Как в системе Светлая @@ -384,10 +298,7 @@ Автоматически загружать изображения и GIF Автоматически воспроизводить видео и GIF Копировать в буфер обмена - Правила Обновить статус - Чаты - Поиск Скрытые слова Добавить новое слово или предложение Картинка профилей diff --git a/amethyst/src/main/res/values-sa-rIN/strings.xml b/amethyst/src/main/res/values-sa-rIN/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-sa-rIN/strings.xml +++ b/amethyst/src/main/res/values-sa-rIN/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-sl-rSI/strings.xml b/amethyst/src/main/res/values-sl-rSI/strings.xml index 72c2046720..4f45f72c63 100644 --- a/amethyst/src/main/res/values-sl-rSI/strings.xml +++ b/amethyst/src/main/res/values-sl-rSI/strings.xml @@ -20,6 +20,12 @@ %1$d sredstva v paketu %1$d sredstev v paketu + + +%1$d\nodgovor + +%1$d\nodgovora + +%1$d\nodgovorov + +%1$d\nodgovorov + Dogodek se nalaga ali pa ni najden v tvojih relejih 👀 Slika kanala @@ -36,8 +42,6 @@ Drugo Nadlegovanje Nasilje - Nepoznano - Ikona releja Avtor neznan Kopiraj tekst Kopiraj ID avtorja @@ -52,12 +56,9 @@ Prijavi nezaželeno vsebino / prevaro Prijavi oponašalca - Prijavi eksplicitno vsebino Prijavi nedovoljeno obnašanje Zlonamerna programska vsebina - Prijavi moderatorja Zlonamerna programska vsebina - Moderator Uporabljaš javni ključ in javni ključi omogočajo le branje. Prijavi se s privatnim ključem, da omogočiš tudi pisanje Uporabljaš javni ključ in javni ključi omogočajo le branje. @@ -79,8 +80,6 @@ Prijavi se s privatnim ključem, za odstranitev iz seznama sledljivih Prijavi se s privatnim ključem, za cenzuro besed ali stavkov Uporabljaš javni ključ in javni ključi omogočajo le branje. Prijavi se s privatnim ključem, za prikaz skritih besed in stavkov - Uporabljaš javni ključ in javni ključi omogočajo le branje. -Za spreminjanje nastavitev, se prijavi s privatnim ključem Uporabljaš javni ključ in javni ključi omogočajo le branje. Za nalaganje se je potrebno prijaviti s privatnim ključem Uporabljaš javni ključ in javni ključi omogočajo le branje. @@ -89,10 +88,8 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Podpisnik ni odobril dešifriranja, ki je potrebno za to operacijo. V aplikaciji za podpisovanje aktivirajte NIP-44 možnost dešifriranja in poskusite znova Ne najdem podpisnika Ali je bila aplikacija za podpisovanje odstranjena? Preverite, ali je aplikacija za podpisovanje nameščena in ima dostop do tega računa. Odjavite se in ponovno prijavite, če se je aplikacija morda spremenila. - Napačno delovanje podpisnika Zunanji podpisnik je vrnil neobičajen odgovor. Morda gre za napako v aplikaciji Amethyst ali v podpisniku. Zapi - Števec vpogledov Pošlji naprej poslano naprej posodobljeno @@ -105,9 +102,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Dodaj "odgovoriti " " in " - "v kanalu " Pasica profila - Plačilo uspešno Napaka pri razčlembi sporočila o napaki " Sledi" " Sledilcev" @@ -121,13 +116,13 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Poteklo CLINK ponudba Za - Pridobivanje računa … + Pridobivanje računa… Plačilo prek debetne storitve ni uspelo. Potrdi plačilo Plačaj %1$s preko %2$s? Plačaj ta račun preko %1$s? Vsote(sat) - + Vnesite veljaven znesek za to ponudbo. Dovoljen razpon: %1$s–%2$s satov CLINK ponudba (noffer) Proračun @@ -142,7 +137,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Samo plačilo CLINK Debet Plačila in zapi prek vnaprej odobrene denarnice. Samo poraba — brez stanja ali zgodovine. - Napačen CLINK debit kazalnik. Pričakovan niz, ki se začne z ndebit1… + Napačen CLINK debit kazalnik. Pričakovan niz, ki se začne z ndebit1…. Prilepi ndebit kazalnik Plačaj Pošlji plačilo @@ -176,11 +171,10 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Plačaj %1$s satov Plačaj Ta profil nima plačilnih metod, ki bi jih Amethyst lahko plačal neposredno. - On-chain zapi zahtevajo vsaj %1$s satov. + On-chain zapi zahtevajo vsaj %1$s satov Premalo stanja v mintu, ki ga podpira prejemnik. Najprej napolni Cashu denarnico. Za tega prejemnika je na voljo: %1$s satov Provizija omrežja - tvoja aplikacija denarnice Transakcija: %1$s Lightning napitnine Sporočilo prejemniku @@ -194,16 +188,13 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Vidna predpona 😎 Dodaj v zapisek - "Napaka pri razčlembi predogleda za %1$s : %2$s" "Predogled kartne slike za %1$s" Članek - Nov kanal Ime kanala Moja vrhunska skupina URL slike URL slike (poljubno) Opis - Ne najdem opisa "O nas… " O čem razmišljaš? Napiši sporočilo… @@ -213,42 +204,25 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Ustvari Preimenuj Prekliči - Neuspelo nalaganje slike - Naslov releja - Pošlji - Bajti Napaka Napake Delež uspešnih povezav z relejem - Število napak pri povezovanju v tej seji - Domač vir vsebin - Vir vsebin privatnih sporočil - Vir vsebin javnih novic - Globalni vir vsebin - Išči vir vsebin Išči in dodaj uporabnika - Dodaj Uporabnika Dodaj rele - Ime - Ime (za @označbe) Moje ime @oznake Prikazano ime Moje prikazno ime Janez Slovenc Dobrodošel Nojek! Uporabniško ime - Moje uporabniško ime O meni URL avatarja URL pasice URL spletne strani Zaimki - Lightning naslov (LUD-16) - Zastarel lightning naslov (LUD-06) Izvorni releji morda niso posodobljeni Opozorilo o neposodobljenih relejih Shrani v telefon - Shrani v galerijo Slika shranjena v foto galerijo telefona Prenos videa se je začel… Začenjam prenos medija… @@ -264,16 +238,14 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Naloži datoteko Zajemi sliko Posnemi video + Na tej napravi ni nameščene nobene aplikacije za kamero Posnemi sporočilo - Posnemi sporočilo Klikni in drži za snemanje sporočila Ponovno posnemi Snemam Snemam %1$s - Nalaganje … Naloži napako Neuspešno nalaganje zvočnega sporočila - Nepričakovan status nalaganja NIP-95 še ne podpira zvočnih posnetkov Neuspešno nalaganje zvočnega posnetka: %1$s Nič @@ -285,8 +257,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Uporabnik nima nastavljenega \"lightning\" naslova za sprejem satoshi-jev "odgovori tukaj… " v tem klepetu - Kopira ID zapiska v odložišče za deljenje v Nostr - Kopiraj ID kanala (zapisek) v odložišče Uredi metapodatke kanala Pridruži se Poznani @@ -300,7 +270,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Pogovori Vaše Galerija - "sledilcev" "Prijave" "%1$s Prijav" Več možnosti @@ -308,11 +277,8 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Spletna stran Lightning naslov Kopira Nsec ID (tvoje geslo) v odložišče za varnostno kopiranje - Kopiraj privatni ključ v odložišče Pokaži QR kodo zasebnega ključa Pokaži QR kodo šifriranega zasebnega ključa - Kopira javni ključ v odložišče za deljenje - Kopiraj javni ključ (NPub) v odložišče Pošlji direktno sporočilo Uredi uporabnikove metapodatke Sledi @@ -341,8 +307,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Kako naj te kličemo? Še nimate Nostr računa? Že imam Nostr račun? - Ustvari nov račun - Ustvari nov ključ Nalagam vir vsebin Račun se nalaga šifrirano @@ -358,13 +322,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Aktivna anketa Vir vsebin je prazen. Osveži - ustvarjeno - z opisom - in sliko - ime kanala spremenjeno v Nov profil klepeta: - opis za - in fotografijo Zapusti Prenehaj slediti Kanal ustvarjen @@ -401,7 +359,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Nostr naslov t. i. Nip-05 nikoli zdaj - sekunde h m d @@ -409,7 +366,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Psovke / Sovražni govor Prijavi sovražni govor Prijavi goloto / pornografijo - drugo Označi vse znane kot prebrane Označi vse nove kot prebrane Označi vse kot prebrane @@ -430,8 +386,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Neuspela overitev Neuspela overitev lastnika telefona z biometrijo Neuspela overitev lastnika telefona z biometrijo. Napaka: %1$s - Napaka - "Ustvaril/a %1$s" "Slika nagradne značke za %1$s" \"Slika nagradne značke Prejel/a si novo nagradno značko @@ -439,7 +393,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Tekst zapiska kopiran v odložišče Avtorjev @npub kopiran v odložišče Zapiskov ID (@note1) kopiran v odložišče - Izberi tekst "<Unable to decrypt private message>\n\nOmenjeni ste bili v zasebnem/šifriranem pogovoru med %1$s in %2$s." Dodaj nov račun Računi @@ -451,8 +404,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Izberi račun Dodaj nov račun Aktivni račun - Ima privatni ključ - Samo za branje, brez privatnega ključa Nazaj Izberi Deli povezavo brskalnika @@ -477,14 +428,12 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Utišaj niz objav Vklopi zvok niza objav Prijavi - Izbriši Ne prikaži ponovno Nezaželena vsebina ali prevara Nesramnost ali sovražno vedenje Zlonamerno lažno predstavljanje Golota ali grafična vsebina Nelegalno obnašanje - Zlonamerna programska oprema / vsebina Blokiranje uporabnika bo skrilo njegove objave v tvoji aplikaciji. Tvoji zapiski še vedno ostajajo javno dostopni. Blokirani uporabniki so vidni v Varnost in filtri. Prijavi zlorabo @@ -512,7 +461,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Izberi načrtovani čas Načrtovano za… Objavljleno v %1$s - Poteklo pred %1$s Čas Načrtovana objava Prekliči načrtovanje @@ -597,7 +545,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Avtor Zahtevki Odobritve - Nobena skupnost ne ustreza temu filtru. Preverljiva pravila (poljubno) Objavi strojno berljiv dokument s pravili (NIP-9B) skupaj s skupnostjo. Nostr odjemalci, ki to podpirajo, blokirajo neustrezne objave še pred pošiljanjem. Dovoljeni tipi (kind) dogodka @@ -626,26 +573,15 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Dodaj WoT vrata Največja velikost dogodka (izbirno) Bajtov \u2014 pustite prazno za brez omejitve. - Prejeto - Moje - Podeljene - Razišči Nova značka - Uredi značko Podeli značko Sprejmi Zavrni Odstrani iz profila - ID značke (d-tag) - Podpornikom za pogum-2025… Ime Prikazno ime značke Opis Zakaj se podeli ta značka? - URL slike (1024 × 1024) - https://example.com/badge.png - URL sličice (neobvezno) - https://example.com/badge-thumb.png Naloži sliko Izberite kvadratno sliko, ki bo krasila vašo značko. Nalaganje značke… @@ -654,7 +590,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Odstrani Neimenovana značka Podeljena za %1$d - Prejeli ste značko Značke v profilu Značke · %1$d Izberite, katere od prejetih značk bodo vidne na vašem profilu. @@ -665,6 +600,9 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Priporočene aplikacije Izberi, katere Nostr aplikacije javno priporočaš. Priporočila bodo vidna na tvojem profilu in bodo pomagala drugim odkriti aplikacije za vsebino, ki je ta aplikacija ne more odpreti. Ni najdenih aplikacij. Pojavile se bodo tukaj, ko jih aplikacija odkrije na tvojih relejih. + Išči aplikacijo po imenu + Ni zadetkov + Ni aplikacij, ki bi ustrezale tem filtrom. Neimenovana aplikacija Ne objavlja informacij o vsebini, ki jo podpira Priporoča @@ -700,12 +638,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Deli svoje vadbe Dovoli aplikaciji Amethyst branje zaključenih vadb iz Health Connect (Samsung Health, Google Fit, Fitbit, Garmin…) , da ti predlaga objavo Poveži - Zaznana nova vadba - Deli - Prekliči %1$s km - %1$s bpm - %1$s kcal Iz Health Connect Tek Hoja @@ -719,7 +652,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Dieta Post Aplikacije - Aplikacije Vir: %1$s v%1$s Prenos @@ -728,12 +660,10 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Teme Povezave Najnovejša različica - Komentarji Napiši prvi komentar. od Prikaži starejše različice Skrij starejše različice - Koledarji Kratki posnetki Javni klepeti Paketi sledenih @@ -743,18 +673,14 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Gnezdo Prizorišče Čakanje na govornike… - Občinstvo Dvigni roko Spusti roko Poveži avdio - Odklopi Utišaj Vklopi zvok - Povezujem Iskanje sobe Odpiranje prenosa Usklajevanje zvoka - Avdio povezan Povezujem znova… Poslušaj posnetek Sporočila ni bilo mogoče poslati @@ -762,9 +688,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Zaprem to sobo? Vsi udeleženci bodo odklopljeni. Soba bo v viru vsebin prikazana kot ZAPRTA. Zapri sobo - Izberite čas začetka v prihodnosti. Napaka pri zvoku: %1$s - Zvok v tej sobi ni na voljo Govori Zapusti oder Izklopi mikrofon @@ -772,7 +696,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Grem v živo… Oddajanje neuspešno: %1$s Utišanje neuspešno: %1$s - Za govor v tej sobi je potreben dostop do mikrofona. Odpri nastavitve Gnezda Ohrani predvajanje zvoka, ko je soba odprta. @@ -783,7 +706,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Pridruži se gnezdu Gostitelj Odpri - Nedavni klepeti Trenutno v sobi ni nikogar %1$d jih posluša Gostitelj @@ -813,8 +735,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Občinstvo Roke V občinstvu še ni nikogar. - Pošlji - Povej kaj… Še ni sporočil. Začni klepet. Odzovi se Uredi sobo @@ -848,7 +768,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Dejanje ni uspelo Priprava dejanja ni uspela. Deli sobo - Pomanjšaj Pomanjšaj za nadaljnje poslušanje Izpad zvoka Nalagam sobo… @@ -881,7 +800,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Izberite strežnike MoQ, na katerih Amethyst objavlja vaša gnezda. Prvi vnos bo privzeto uporabljen ob začetku novega pogovora. Vaši strežniki Shranjeno kot zamenljiv dogodek kind-10112, da lahko vaše nastavitve berejo tudi drugi odjemalci. - Dodaj strežnik gnezda Rele (WebTransport) URL URL za avtentikacijo (JWT mint) Dodaj @@ -894,13 +812,11 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Odstrani strežnik Seznam strežnikov gnezda je prazen. Dodajte ga spodaj ali izberite priporočenega. Videoposnetki - Članki Glasba Predvajalni seznami Epizode Podkasti Prikaži epizode - Epizode Trenutno ni najdenih epizod %1$d epizoda @@ -914,9 +830,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Naslov skladbe Izvajalec Ime izvajalca - URL avdia - https://… .mp3 - URL naslov naslovne slike (neobvezno) Album (neobvezno) Trajanje v sekundah (neobvezno) Besedilo ali zasluge (neobvezno) @@ -926,7 +839,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Dodaj na seznam predvajanja Nimaš še nobenega seznama predvajanja. Uporabi zgornje polje in ga ustvari. Uredi vse sezname predvajanja - Nov seznam predvajanja Ime seznama predvajanja Ustvari (neimenovan seznam predvajanja) @@ -964,9 +876,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Izbriši seznam zaznamkov Preglej objave Preglej članke - Preglej povezave - Preglej ključnike - Nimate še nobenega seznama zaznamkov. Tapnite \"Nov\" gumb spodaj, da ga ustvarite. Nabor ključnikov Nimate še nabora zanimanj. Dotaknite se spodnjega gumba »Novo« in ustvarite prvega. Nov nabor zanimanj @@ -985,7 +894,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Zasebne objave(%1$s) Javne objave Javne objave(%1$s) - Zasebni članki Zasebni članki(%1$s) Javni članki Javni članki(%1$s) @@ -1012,16 +920,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Metapodatki seznama zaznamkov so vidni vsem na Nostru. Le tvoji zasebni člani so šifrirani. Premakni v javno Premakni v zasebno - Storitev Wallet Connect - Pooblasti Nostr skrivnost (Nostr secret) za plačevanje z Zapi brez zapuščanja aplikacije. Nostr skrivnost (Nostr secret) hranite na varnem in, če je mogoče, uporabite zasebni rele - Wallet Connect javni ključ - Wallet Connect rele - Wallet Connect skrivnost - Prikaži skrivni ključ - nsec / hex privatni ključ - Povezan - Ni povezan - Napredno: ročni vnos podatkov o povezavi Zneski za hitre zape Prikaže se ob pritisku na gumb za zape. Tapnite znesek, da ga odstranite. Če pustite prazno, se bo ob vsakem zapu odprlo okno za vnos poljubnega zneska. Pošlji raje on-chain @@ -1053,14 +951,8 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Poveži denarnico Pogled rele vira vsebin Prispevaj vsoto v sat - Pošlji anketo - Zahtevana polja: - Prejemniki Zapov - Opis primarne ankete… - Izbira Izbira %s Opis izbire v anketi - Izbirna polja: Zap minimum Zap maksimum Soglasje @@ -1069,11 +961,8 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Več izbire Datum in čas konca glasovanja Anketa se zaključi %1$s - Zapri po - dni Nezmožen za glasovanje Anketa je zaprta za nove glasove - Zap vsota Dovoljen je le en glas na uporabnika pri tem tipu ankete "Iskanje dogodka %1$s" Pošlji zap @@ -1109,11 +998,8 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Ni-Zap Brez sledi v Nostr, samo v Lightning Anonimno - Objavite z novo začasno identiteto. Vaš račun ne bo povezan s tem odgovorom. - Ta odgovor bo objavljen z novo anonimno identiteto Datotečni strežnik Izberi strežnik za nalaganje te datoteke - LnNaslov ali @Uporabnik Medijski strežniki Nastavi svoje prednostne medijske strežnike za nalaganje medijev. Uporabi lokalni predpomnilnik Blossom @@ -1122,10 +1008,8 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Na vratih 24242 ni zaznati lokalnega predpomnilnika. V predpomnilnik shrani le slike profilov Lokalni predpomnilnik omeji le na slike profilov. Slike in videoposnetki iz vira vsebin se bodo prenašali neposredno z izvornih strežnikov. - Nimate nastavljenih NIP-96 strežnikov. Uporabite lahko Amethyst-ov seznam ali dodajte enega spodaj ↓ Nimate nastavljenih Blossom strežnikov. Uporabite lahko Amethyst-ov seznam ali dodajte enega spodaj ↓ Priporočljivi medijski strežniki - Vgrajeni medijski strežniki Privzeti seznam Amethysta. Lahko jih dodate posamično ali dodate celoten seznam. Uporabi privzeti seznam Dodaj medijski strežnik @@ -1148,38 +1032,21 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Razpršujem Končano Napaka - Tvoji releji (NIP-95) - Datoteke so gostovane preko tvojih relejev. Nov NIP: Preveri če podpirajo Nastavitve zasebnosti - Tor/Orbot nastavitve - Poveži se preko tvojih Orbot nastavitev Prilagodi Tor nastavitve - Prekini povezavo od tvojega Orbot/Tor? - Vaši podatki bodo takoj preneseni v običajno omrežje Da Ne - Seznam sledenih Vsa sledenja Vsi sledeni sledenih Privzeti seznam sledenih - Sledi preko posrednika V moji okolici Globalno Urejeno - Šah Moje Seznam utišanih Seznam sledenih To so seznami sledenih, namenjeni za vašo lastno uporabo. Uporabnike lahko sledite javno ali zasebno - Označeni zaznamki - Splošni zaznamki - Javno - Zasebno - Mešano - Videti je, da še nimate nabora sledenih. - \nTapnite spodaj za osvežitev ali dodajte nov seznam. - Nov Dodaj avtorja v seznam sledenih Dodaj ali odstrani uprabnika iz seznama, ali pa ustvari nov seznam s tem uporabnikom. @@ -1188,23 +1055,9 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem %1$s je zasebni član Dodaj kot javni člana Dodaj kot zasebni član - Javni člani - Zasebni člani - Javni profili - Zasebni profili - član - člani - Ni članov Prazno - %1$s ni v tem seznamu %1$s ni član Tvoj seznam ter %1$s - Tvoji seznami - Ni bilo najdenih seznamov sledenih ali pa nimate nobenega. Tapnite spodaj za osvežitev ali pa uporabite meni da dodate novega. - Pri pridobivanju podatkov je prišlo do napake: %1$s - Ustvari nov seznam - Nov seznam s %1$s člani - Ustvari nov set sledenih, ter doda %1$s kot %2$s člana. Nov seznam sledenih Nov paket sledenih Kopiraj/Kloniraj seznam sledenih @@ -1224,14 +1077,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Preimenuješ iz v.. Prevzeta vrata so 9050 - ## Poveži se preko Tor omrežja z Orbot - \n\n1. Namesti [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Zaženi Orbot aplikacijo - \n3. V Orbot aplikaciji, preveri \"Socks port\". Pradnastavitev uporablja vrata 9050 - \n4. Po potrebi spremenite vrata v Orbot - \n5. Prilagodi vrata na tem zaslonu - \n6. Pritisni gumb aktiviraj za uporabo Orbot aplikacije kot proxy - Orbot socks vrata Aktivni Tor stroj Uporabi interno različico ali Orbot @@ -1273,8 +1118,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Skrij svoj IP v vseh povezavah Ustvari svojega Neveljavna številka vrat - Uporabi Orbot - Odklopi Tor/Orbot Zasebna sporočila Ob prejemu zasebnega sporočila te obvesti Prejeti Zapi @@ -1331,12 +1174,8 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Bluetooth Govorni klic Video klic - Čakamo, da se pridružijo še ostali\u2026 Dodajte udeleženca Poišči uporabnike\u2026 - Klic ni uspel - Sprejem klica ni uspel - Vzpostavitev klicne seje ni uspela Potrebno je dovoljenje Amethyst potrebuje dostop do mikrofona za začetek glasovnega klica. Omogoči ga v nastavitvah aplikacije. Amethyst potrebuje dostop do kamere in mikrofona za začetek video klica. Omogoči ju v nastavitvah aplikacije. @@ -1359,35 +1198,38 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Akreditivi Ohranja aktivne povezave z vašimi releji za obvestila v realnem času Amethyst obvestila so aktivna + + Povezano z %1$d vhodnimi releji + Povezano z %1$d vhodnima relejema + Povezano z %1$d vhodnimi releji + Povezano z %1$d vhodnimi releji + + + Povezano z %1$d relejem + Povezano z %1$d relejema + Povezano z %1$d releji + Povezano z %1$d releji + Povezovanje vhodnih relejev\u2026 Vedno aktivna obvestila Ohranja stalno povezavo z vašimi releji za takojšnjo dostavo obvestil. Prikazuje trajno obvestilo. Porabi več baterije, a zagotavlja, da ne zamudite nobenega sporočila. Razdeli opozorila glede na sledilce Prikaže dva zavihka z obvestili — Sledim (ljudje, ki jim slediš) in Vsi ostali. Indikator neprebranih obvestil sveti le za aktivnosti ljudi, ki jim slediš. + Prikaži sporočilo + V zavihek Obvestila vključite neposredna in skupinska sporočila. Izklopite, če želite sporočila ohraniti samo v zavihku Sporočila. Sledim Vsi Optimizacija baterije je aktivna Android lahko omeji povezave z releji v ozadju. Onemogočite optimizacijo baterije za Amethyst, da zagotovite zanesljivo prejemanje obvestil. Popravi zdaj Obvesti: - Pridruži se pogovoru - ID uporabnika ali skupine - npub, nevent ali hex - Ustvari - Pridruži se Danes Opozorilo o vsebini Opozorilo: %1$s Ta objava vsebuje občutljivo vsebino, ki jo lahko nekateri smatrajo za žaljivo ali vznemirjajočo - Vedno skrij občutljivo vsebino - Vedno prikaži občutljivo vsebino - Vedno prikaži opozorilo o vsebini Skrij Prikaži Opozori - Priporoča: - Filtriraj nezaželeno vsebino od neznancev - Opozori, ko objave vsebujejo prijave od oseb, ki jim slediš Filtriraj nezaželeno vsebino Skrije objave neznancev, ki so bile popolnoma enake več kot petkrat Vključi oznako Nostr odjemalca v moje dogodke @@ -1419,22 +1261,17 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Količina bajtov, ki je bila poslana temu releju, vključno s filtri in dogodki Količina bajtov, ki je bila prejeta od tega releja, vključno s filtri in dogodki dogode shranjen - Prišlo je do napake pri pridobivanju informacij o releju iz %1$s Lastnik V uporabi pri Servisni ključ - V teku %1$s - V teku %1$s (%2$s) Različica Program Kontakt Podprti NIP-i Podprti upravljalniki vsebine - Vstopnina Vstopnina Naročnina Publikacija - Plačila %1$s URL za plačila Ciljna skupina Pravilnik & Povezave @@ -1442,7 +1279,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Omejitve Države Jeziki - Oznake Teme Vse države Vsi jeziki @@ -1457,64 +1293,48 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Odprto Branje Pisanje - RTT Omrežje Vrsta Podprti NIP-i Zahteve - Zadnje preverjanje %1$d ms Sprejeti tipi (kind) Lokacija Aktivne naročnine - Izhodni dogodki v teku REQ Naročnine (%1$d) COUNT Naročnine (%1$d) Izhodni dogodki (%1$d) - Ni aktivne naročnine za ta rele %1$d avtorjev %1$d ids od %1$s do %1$s limit %1$d - Dolžina sporočila - Naročnine - Filtri - Dolžina id naročnine Minimalna predpona Največ oznak v dogodku - Dolžina vsebine Največja dolžina vsebine Zavrži starejše od Sprejme do %1$s v prihodnost Pred %1$s - %1$s ničel %1$s bitov Zadržanje dogodka Velikost vsebine Povezljivost Nadzor dostopa Minimalen PoW - Auth Potrebna je avtentikacija - Plačilo Potrebno je plačilo Največja dolžina sporočila Največ naročnin Največ filtrov na naročnino Največja omejitev (vrnjenih dogodkov) - Privzeta omejitev (vrnjenih dogodkov) Največja dolžina SubID Cashu žeton Kovnica: %1$s Unovči - Pošlji v Zap denarnico - Odpri Cashu denarnico Kopiraj žeton Odpri z drugo aplikacijo Lightning naslov ni nastavljen - Žeton kopiran v odložišče V ŽIVO ODKLOPLEN KONČANO @@ -1565,7 +1385,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Ponastavitev stanja Marmot. Neuspešna ponastavitev stanja Marmot: %1$s Vedno - Samo Wifi Samo z WiFi Nikoli Celovit @@ -1590,7 +1409,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Izberi stil objave Slog galerije profila Izberi slog galerije - Naloži sliko Pošiljatelji nezaželenih vsebin Utišano. Klikni za vklop zvoka Zvok je prižgan. Klikni da ga utišaš @@ -1602,18 +1420,13 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Nostr naslov je preverjen Preverjanje Nostr naslova ni uspelo Preverjanje Nostr naslova - Izberi/Prekliči izbiro vsega Privzeto Ponastavi na privzeto - Izberi rele za nadaljevanje - Posreduj Zape k: - Podprti Nostr odjemalci bodo Zape preusmerili na spodnji LN-naslov ali uporabniški profil, namesto na vašega Prikaži lokacijo kot Doda Geohash vaše lokacije k objavi. Javnost bo vedela, da se nahajate v radiju 5km (3milj) od trenutne lokacije Lokacijsko-ekskluzivna objava To bodo videli samo sledilci lokacije. Vaši splošni sledilci tega ne bodo videli. Ekskluzivna objava ključnika - Vidno bo le sledilcem tega ključnika. Tvoji splošni sledilci tega ne bojo videli. Komentiraj na spletni strani Komentiraj na zunanjem viru %1$d min branja @@ -1638,9 +1451,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Naloži zvočno datoteko Izberi MP3, WAV ali FLAC. Ob shranjevanju bo naložen na tvoj medijski strežnik. Zvočna datoteka je pripravljena za nalaganje. - Nalagam… Nalaganje naslovnice in zvoka ter objavljanje. Postopek se bo nadaljeval, tudi če zapustiš ta zaslon. - Nalaganje ni uspelo: %1$s Uredi seznam predvajanja Uredi seznam predvajanja Naslov @@ -1661,13 +1472,9 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Brez dovoljenj za lokacijo Doda opozorilo o občutljivi vsebini pred prikazom vaše vsebine. To je primerno za vsebino NSFW ali vsebino, ki jo nekateri lahko smatrajo za žaljivo ali vznemirjajočo Razlog (neobvezen) - Nova funkcija - Za aktivacijo tega načina mora Amethyst poslati sporočilo NIP-17 (GiftWrapped, šifrirana neposredna in skupinska sporočila). NIP-17 je nov in večina Nostr odjemalcev ga še ni implementirala. Prepričajte se, da prejemnik uporablja združljiv Nostr odjemalec. - Aktiviraj Javno Skupina Nova javna ali zasebna skupina - Rele Zasebno Za Zadeva @@ -1679,9 +1486,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Razlaga članom Spreminjanje imena za dosego novih ciljev. Prilepi iz odložišča - Napačen NIP-47 URI - URI %1$s ni veljaven NIP-47 vpis URI. - Poveži z novo NWC denarnico Ne najdem denarnice Amethyst ni našel nobene denarnice, ki podpira Nostr Wallet Connect (NWC). \n\nKaj lahko storiš: @@ -1698,7 +1502,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Samodejno predvajaj video in GIF-e Video predvajaj samodejno, ko je viden na ekranu Prikaži predogled URL-jev - Kdaj naložiti slike Kopiraj nabor Kopiraj v odložišče Kopirano v odložišče @@ -1714,43 +1517,21 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Medij dodan Medij dodan v galerijo profila Ustvarjeno ob - Pravila - O nas Smernice Moderatorji Prijavi se z Amber Posodobi svoj status - Napaka pri razčlembi sporočila o napaki Glasovi so ovrednoteni glede na količino zapov. Lahko nastavite minimalni znesek, da se izognete nezaželjenim glasovom, in največji znesek, da preprečite, da bi bogatejši volilci prevzeli glasovanje. V obeh poljih uporabite enak znesek, da zagotovite, da je vsak glas enako ovrednoten. Pustite prazno, če želite sprejeti poljubno količino. Zap ni uspel Pošlji sporočilo uporabniku Sporočilo %1$s OK - Neuspela povezava z %1$s: %2$s - Ni uspelo sestaviti URL-ja NIP-11 za %1$s: %2$s - Neuspela povezava z %1$s: %2$s - Neuspešna analiza odgovora %1$s: %2$s - Rele zavrnil zahtevo %1$s: %2$s - Ni uspelo vzpostaviti povezave z %1$s: %2$s - Ni uspelo razčleniti rezultata od %1$s: %2$s - %1$s ni uspelo s kodo %2$s - Aktiven: - Domov - ZS - Pogovori - Globalno - Išči Razdeli in posreduj Zape Podprti Nostr odjemalci bojo razdelili in posredovali Zap-e, uporabnikom dodanim tukaj namesto k vam Išči in dodaj uporabnika Uporabniško ime ali prikazano ime Manjka \"lightning\" nastavitev Uporabnik %1$s nima nastavljenega \"lightning\" naslova za prejemanje satoshi-jev - Odstotek - 25 - Razdeli Zape z - Posreduj Zape - Ne najdem \"lightning\" denarnic Plačano Denarnica %1$s Napaka pri odpiranju aplikacije za podpisovanje @@ -1759,7 +1540,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Kodek ali format na tej napravi ni podprt (%1$s). Poskusi odpreti v brskalniku. Odpri v brskalniku Zahteva za vpis zavrnjena - Podpisovanje je bilo zavrnjeno Prepričajte se, da je aplikacija za podpisovanje odobrila to transakcijo Denarnica za plačilo z \"lightning\" ni najdena (Napaka: %1$s). Prosimo, namestite \"lightning\" denarnico da boste lahko Zap-ali ostale Denarnica za plačilo z \"lightning\" ni najdena. Prosimo, namestite \"lightning\" denarnico da boste lahko Zap-ali ostale @@ -1775,40 +1555,23 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Uporabi možnost Fakture ni bilo mogoče plačati Ni bilo mogoče dvigniti - Ni bilo mogoče nastaviti \"Wallet Connect\" - Napaka pri razčlenjevanju NIP-47 connection string. Preverite pri vašem ponudniku denarnice, ali je to pravilno: %1$s. Napaka: %2$s - Napaka pri razčlenjevanju NIP-47 connection string. Preverite pri vašem ponudniku denarnice, ali je to pravilno: %1$s. Cashu žetona ni bilo mogoče unovčiti Kovnica je posredovala naslednje sporočilo o napaki: %1$s - Cashu žeton je že zapravljen. Prejeli ste Cashu žeton V vašo denarnico je bilo poslanih %1$s satoshi-jev. (Provizija: %2$s sat) Na sistemu ni najdene združljive Cashu denarnice Ni mogoče pridobiti fakture s strežnikov prejemnika Vaš \"Wallet Connect\" ponudnik je vrnil naslednjo napako: %1$s - Ni bilo mogoče povezati s Tor Tor se ne povezuje Amethystu ni uspelo zagnati povezave Tor. Želite uporabiti običajno povezavo za nalaganje vira vsebin? To izbiro bomo ohranili eno uro, nato bomo ponovno poskusili s Torom. Uporabi običajno povezavo Nadaljuj s čakanjem - Prenos rele dokumentacije ni na voljo Ni bilo mogoče sestaviti LNUrl iz \"lightning\" naslova \'%1$s\'. Preverite uporabnikove nastavitve - Prejemnikova \"lightning\" storitev na %1$s ni na voljo. Izračunana je bila iz \"lightning\" naslova \'%2$s\'. Napaka: %3$s. Preverite, ali strežnik deluje in ali je \"lightning\" naslov pravilen - Ni bilo mogoče razrešiti %1$s. Preverite, ali ste povezani, ali je strežnik dosegljiv in ali je lightning naslov %2$s pravilen - Ni bilo mogoče razrešiti %1$s. Preverite, ali ste povezani, ali je strežnik dosegljiv in ali je lightning naslov %2$s pravilen.\n\nIzjema je bila: %3$s - Ni bilo mogoče pridobiti fakture od %1$s Ni bilo mogoče pridobiti fakture od %1$s: %2$s - Napaka pri razčlenjevanju JSON iz \"lightning\" naslova. Preverite uporabnikove nastavitve za \"Lightning\" Napaka pri razčlenjevanju JSON iz %1$s. Preverite uporabnikove nastavitve za \"lightning\" - Povratnega URL-ja ni bilo mogoče najti v konfiguraciji strežnika za lightning naslov uporabnika Povratni URL ni bil najden v odzivu od %1$s - Napaka pri razčlenjevanju JSON med pridobivanjem fakture iz \"lightning\" naslova. Preverite uporabnikove nastavitve za \"Lightning\" - Napaka pri razčlenjevanju JSON med pridobivanjem fakture iz %1$s. Preverite uporabnikove nastavitve za \"Lightning\" Napačen znesek fakture (%1$s sat) od %2$s. Moral bi biti %3$s Ni mogoče ustvariti lightning fakture pred plačilom. Lightning denarnica prejemnika je poslala naslednjo napako: %1$s - Ni mogoče ustvariti lightning fakture. Sporočilo od %1$s: %2$s - Ni mogoče ustvariti lightning fakture pred plačilom. Element \'pr\' ni bil najden v JSON-u. - Ni mogoče ustvariti lightning fakture od %1$s: Element \'pr\' ni bil najden v JSON-u. Uporabnik samo za branje Ni nastavitev za reakcije Obvestila @@ -1834,13 +1597,11 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Pošlji prodajalcu sporočilo Živjo %1$s, je to še na voljo? Živjo, je to še na voljo? - Prodaj stvar Naslov Nokia 3310 Stanje Kategorija Cena (v Satoshi) - 1000 Lokacija Mesto, Regija, Država Novo @@ -1869,20 +1630,13 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Drugo Nalaganje medija ni uspelo Stisnjene datoteke ni bilo mogoče odpreti - Napaka pri stiskanju medija: %1$s Napaka pri nalaganju: %1$s Strežnik po nalaganju ni posredoval URL naslova Prenos naloženega medija s strežnika ni uspel Ni bilo mogoče preveriti prenesene datoteke po nalaganju: %1$s - Lokalne datoteke ni bilo mogoče pripraviti za nalaganje: %1$s Nalaganje na %1$s ni uspelo: %2$s - Nalaganje ni uspelo: %1$s Izbris ni uspel: %1$s Medij je prevelik za NIP-95 - Predogleda ni mogoče naložiti - Ni bilo mogoče pripraviti informacij glave: %1$s - Stiskanje preklicano - Stiskanje ni vrnilo datoteke Šifriraj datoteke Za večjo zasebnost datoteke pred nalaganjem šifrirajte. Nekateri strežniki pri brezplačnih računih morda ne sprejemajo šifriranih datotek. Šifrirano nalaganje ni uspelo @@ -1909,27 +1663,18 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Iz datoteke AVIF ni mogoče odstraniti metapodatkov: %1$s Uredi osnutek Vpiši se z QR kodo - Pot Domov - Iskanje Odkrij Sporočila Obvestila - Globalno Kratki mediji - Fotografije - Vadbe Koledarji Seznami koledarjev Šah Denarnica - Bilanca Pošlji Prejmi Transakcije - Denarnica ni povezana - Za uporabo denarnice v nastavitvah zapov vzpostavite povezavo Nostr Wallet Connect (NWC). - Nastavi denarnico sats prilepi BOLT-11 fakturo Plačaj @@ -1957,8 +1702,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem S tem boste odstranili povezavo z denarnico. Pozneje jo lahko kadar koli znova dodate. Ime denarnice Moja denarnica - Vaše denarnice - Upravljanje denarnic Ni povezanih denarnic Povežite eno ali več NWC denarnic, za pošiljanje in sprejemanje plačil. Dodaj NWC povezavo @@ -1978,12 +1721,9 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Odstrani kovnico Dodaj kovnico Zgodovina - Uredi denarnico Ključ Nutzap (napredno) Ločen zasebni ključ, uporabljen le za prejemanje NIP-61 nutzapov. To ni tvoj ključ identitete Nostr. Generiraj nov ključ - To bo razveljavilo vse čakajoče nutzape, zaklenjene na trenutni ključ. - Ohrani trenutni ključ Zasebni ključ P2PK (hex) Urejanje denarnice Cashu Shrani spremembe @@ -2003,7 +1743,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Popularne kovnice Ujemajoče kovnice - Priporoči kovnico Prejmi Pošlji LN Pošlji žeton @@ -2084,10 +1823,6 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Shrani Preimenuj Preimenuj denarnico - Uredi - Neveljaven NWC URI povezave - Premakni navzgor - Premakni navzdol On-chain transakcije Za ta račun ni na voljo nobenega on-chain naslova. Zaledni sistem verige ni nastavljen. @@ -2174,17 +1909,13 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Plačilo je poslano (objavljenih %1$d od %2$d potrdil), vendar naslednjega potrdila ni bilo mogoče objaviti Plačilo je poslano (objavljeno %1$d od %2$d potrdil), vendar naslednjega potrdila ni bilo mogoče objaviti - Varnostni filtri Uvozi sledilce Nova objava Novi kratki mediji: slike ali posnetki Novo zapisek skupnosti Nov produkt - Nova geo-ekskluzivna objava Nov članek Nova anketa - Nova anketa z zapi - Nova navadna anketa Nova slika Nov koledarski dogodek Uredi koledarski dogodek @@ -2199,8 +1930,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Dan Prihajajoči Pretekli - Ni prihajajočih ali preteklih dogodkov v izbranem viru vsebin. - Nimaš še nobenih zbirk koledarjev. Vaš koledar je prazen Tukaj se prikažejo dogodki, ki jih delijo ljudje, ki jim slediš. Dotakni se gumba +, da ustvariš svojega. Nimate še nobenih zbirk @@ -2227,8 +1956,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Naslednji teden Prejšnji dan Naslednji dan - Ni dogodkov na ta dan - Ni dogodgov Ponavljajoč Dan %1$d od %2$d Dodaj v koledar telefona @@ -2294,7 +2021,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Izbrane slike ni bilo mogoče naložiti. Poskusi znova ali prilepi URL. Udeleženci (%1$d) Išči ime, npub, nip-05 - Vnesi veljaven npub… ali 64-znakovni javni ključ hex. Odstrani udeleženca Opomniki koledarja Pošlji opomnike @@ -2317,10 +2043,7 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Podrobnosti dogodka Novi kratki videoposnetek Novi dolg videoposnetek - Naslov Povzetek (poljubno) - URL naslov naslovne slike (poljubno) - Napiši članek v obliki Markdown… Predogled Uredi Dodaj sliko v glave @@ -2404,18 +2127,14 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Rele %1$s Razširi seznam relejev Možnosti zapiska - Izbirnik seznama relejev Anketa Onemogoči anketo Bitcoin račun Prekliči Bitcoin fakturo - Prekliči prodajo Zapraiser Prekliči Zapraiser Lokacija Odstrani lokacijo - Zap razdelitev - Prekliči Zap razdelitev Dodaj opozorilo o vsebini Odstrani opozorilo o vsebini Dodaj datum poteka @@ -2430,11 +2149,8 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Neveljaven naslov Amethyst je prejel zahtevo da odpre URI, vendar je bil ta URI neveljaven: %1$s Releji predala zasebnih sporočil - Releji: %1$s - Uporaba običajnih relejev Nastavite releje za predal zasebnih sporočil Ta nastavitev omogoča vsem, da vedo, katere releje uporabiti, ko vam pošiljajo sporočila. Brez njih bi lahko zgrešili nekatera sporočila. - Dobre možnosti so:\n - inbox.nostr.wine (plačljiv)\n - auth.nostr1.com (brezplačen)\n - you.nostr1.com (osebni releji - plačljivi) Dobre možnosti so:\n - auth.nostr1.com (brezplačen)\n - inbox.nostr.wine (plačljiv)\n - relay.0xchat.com (brezplačen) Vnesite 1–3 releje, ki bodo služili kot vaš predal za zasebna sporočila. Releji za zasebna sporočila bi morali sprejeti katero koli sporočilo od kogar koli, vendar samo vam dovoliti njihov prenos. @@ -2455,7 +2171,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Ustvarjanje seznama relejev, namensko zasnovanega za prejem obvestil, je ključnega pomena za vašo izkušnjo v Nostru. Vstavite med 1 in 3 releje, ki za vas prejemajo obvestila. Poskrbite, da ta niso plačljiva ali uporabljajo WoT (mreža zaupanja), sicer boste prejemali obvestila le od plačnikov ali dolgoletnih Nostr uporabnikov. dobre opcije so::\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social - Naloži ZS Nastavitve relejev Razvrsti releje Javni za odhajajočo pošto/domači releji @@ -2472,12 +2187,8 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Releji, kjer so objavljeni vaši MLS KeyPackage-i (MIP-00). Drugi uporabniki jih pridobijo, da vas lahko povabijo v skupinske klepete Marmot. Vstavite od 1 do 3 releje, ki sprejemajo vaše KeyPackage dogodke in omogočajo javno branje. Zasebni domači releji Vnesite 1–3 releje za shranjevanje dogodkov, ki jih nihče drug ne more videti, kot so vaši osnutki in/ali nastavitve aplikacije. Idealno je, da so ti releji bodisi lokalni ali zahtevajo preverjanje pristnosti pred prenosom vsebine posameznega uporabnika. - Splošni releji - Amethyst uporablja te releje za prenos objav za vas. Povezani releji Trenutni seznam relejev v uporabi - Priporočljivi releji - Dodajte naslednje releje na svoj seznam Splošnih relejev, da boste prejeli objave od navedenih uporabnikov. Iskalni releji Seznam relejev za uporabo pri iskanju vsebine ali uporabnikov. Označevanje in iskanje ne bosta delovala, če možnosti niso na voljo. Prepričajte se, da podpirajo NIP-50. Lokalni releji @@ -2512,11 +2223,8 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, To različico so za vas pripravili: Različica %1$s Hvala! - Največji Limit Omejeni zapis Razcepljeno od - RAZCEP - Git skladišče: %1$s Splet: Klon: Odprto @@ -2541,20 +2249,13 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Uredi članek Uredi objavo Prošnja za izboljšavo objave - Povzetek sprememb - Hitri popravki… Sprejmi predlog Zaženi video v pojavnem oknu Prenesi - Vklopi besedilo - Izklopi besedilo - Zapečateno sporočilo je izklopljeno. Kliknite, da vklopite zapečateno sporočilo - Zapečateno sporočilo je vklopljeno. Kliknite, da izklopite zapečateno sporočilo. Pošlji Predvajaj uporabniško ime Pushpin Skeniraj QR kodo - Pojdite na stran tretjega ponudnika denarnice Alby Izberi datum Ni mogoče odgovoriti na osnutek zapiska Ni mogoče citirati osnutka zapiska @@ -2596,23 +2297,18 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Premalo prostora za shranjevanje – Strežnik nima dovolj prostora za uspešno obdelavo zahteve Zaznana zanka – Strežnik je zaznal neskončno zanko med obdelavo zahteve Zahtevana overitev omrežja – Odjemalec mora biti overjen za dostop do omrežja - NIP-96 strežnik - Dodajte poljubno število strežnikov. Kasneje lahko izberete, katerega želite uporabiti pri nalaganju slike Blossom strežniki Dodajte poljubno število strežnikov. Kasneje lahko izberete, katerega želite uporabiti pri nalaganju slike Dodaj NIP-96 strežnik Dodaj Blossom strežnik Izbriši vse Ali ste prepričani, da želite izbrisati vse osnutke? - Sklad: Torent datoteka Prenesi Datoteke ni bilo mogoče odpreti Ni nameščenih torent aplikacij za odpiranje in prenos datoteke. Dogodek nima dovolj podatkov za sestavo magnetne povezave. - Moji seznami/seti Moji seznami - Uporabniki Izberite seznam za filtriranje vira vsebin Viri vsebin Ključniki @@ -2643,7 +2339,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Zasebno sporočilo Javno sporočilo Rele za klepet - Rele, na katerega so povezani vsi uporabniki tega klepeta Deli sliko… Deljenje slike ni uspelo, prosimo poskusite znova… Deli video… @@ -2690,7 +2385,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Želite poslati poročilo o napaki Amethyst-u preko zasebnega sporočila? Vaši osebni podatki NE bojo posredovani. Pošlji To sporočilo bo izginilo čez %1$s - To sporočilo bo izginilo čez %1$d dni Izberi podpisnika Že na seznamu Zasebni člani @@ -2712,7 +2406,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Ime paketa Novo ime paketa Opis paketa - Nov opis paketa Razpošlji seznam Razpošlji paket Izbriši seznam @@ -2726,13 +2419,9 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Strni Razširi Ponovni poskus ni uspel (%1$d) - +%1$d več oddajanj - " (%1$d v teku)" - %1$d/%2$d releji Čas je potekel Poskušam ponovno… Poskusi ponovno - Ogled Zavrni %1$d/%2$d Oddajam @@ -2758,7 +2447,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Ponovno zaženi Sprejmi Zavrni - Nova igra Nova partija šaha Nalagam partijo\u2026 Partija ni najdena @@ -2913,23 +2601,13 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Profil, iz katerega želite uvoziti Iskanje, npub1…, janez@example.com Podpira npub, nprofile, NIP-05, hex in namecoin (.bit, d/, id/) - Poišči seznam sledenih Daj napitnino Najdeno %1$d računov Izbranih %1$d - Razrešeno prek Namecoina - Zdaj sledite %1$d računom - Vaš vir vsebin je pripravljen. - Preskoči - Poišči še koga Sledi %1$d računom - Dodaten uvoz - Nadaljuj Preskoči za zdaj - Razreševanje %1$s… Pridobivanje seznama sledenih… Ni najdenih sledilcev - Sledenje %1$d računom… "Vnesite profil prijatelja ali vodje skupnosti. Uporabite lahko njihov npub, naslov NIP-05 ali ime Namecoin (npr. janez@primer.bit ali id/janez) za identitete, preverjene prek verige blokov." Izberi vse %1$d%% časa delovanja @@ -2937,7 +2615,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Test povezave Testiranje strežnikov… Povezano - Ni uspelo Izidi testov Diagnostika Zadnji test @@ -2950,9 +2627,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Zaupaj Zavrni Sinhronizacija relejev - Sinhronizacija relejev - Ponovno objavite svoje dogodke na vseh znanih relejih, da posodobite svoje izhodne, vhodne in releje ZS. Zahtevana je povezava Wi-Fi — postopek lahko porabi veliko podatkov. - Odpri sinhronizacijo relejev… Kaj to naredi To orodje pregleda vse releje, ki jih je zaznala vaša aplikacija, in vaše dogodke prerazporedi na ustrezne cilje: Prenesite vse dogodke katere ste ustvarili, in jih pošljite v vaše izhodne releje. @@ -2962,14 +2636,9 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Uporabi mobilne podatke? Začni sinhronizacijo Vseeno začni (mobilni podatki) - Premor - Nadaljuj - Začni znova Prekini Releji: %1$d / %2$d Prerazporejeni dogodki: %1$d novih od %2$d poslanih in %3$d prejetih - Premor sinhronizacije - Zaključenih %1$d od %2$d relejev — do zdaj prerazporejenih %3$d dogodkov. Dotaknite se »Nadaljuj« za nadaljevanje. Sinhronizacija zaključena Naprej posredovanih %1$d od %2$d prejetih dogodkov do ciljnih relejev. Število dogodkov, ki jih je ciljni rele sprejel kot nove: %1$d. @@ -2984,16 +2653,13 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, poslano %1$s sprejeto %1$s nov %1$s - ni dogodkov Bitcoin Raziskovalec (OTS) - dogodki vaši dogodki dogodki za vas iskalni dogodki ZS profili izhodni seznami - nastavitve releja Nazadnje viden pred %1$s Nazadje viden na %1$s (%2$s nazaj) Nazadnje viden prav zdaj @@ -3086,7 +2752,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Iščem naprave na vašem WI-Fi… Naloži HLS - Objava HLS v več ločljivostih na medijski strežnik Izberi video Vaš video bo pripravljen v več ločljivostih, da bo predvajanje teklo gladko na vsaki povezavi. Sprememba @@ -3101,10 +2766,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Naprava ne podpira H.265 — izbran bo H.264. Izvedbe Resolucija vira: %1$d×%2$d - Ustvarilo bo: %1$s - (%1$s preskočen — zgornji vir) - %1$d kbps - Zgornji vir — bo preskočen Objavite HD video Objavljam “%1$s”… Priprava videa: %1$s @@ -3116,7 +2777,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Video je objavljen Vaš HD-video je dostopen na Nostru. Prišlo je do napake - Poglej zapisek Končano Poskusi znova Možnosti paketa @@ -3131,30 +2791,21 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Overitev Veljaven Neveljaven - Sprejeto - Zavrnjeno Preverjam - Preverjeno Preklicano Veljaven od %1$s Veljaven do %1$s Prošnja za overitev - Pridobivanje overitve za dogodek Priporočeni potrjevalci Priporočeno za tipe: Usposobljenost potrjevalca - Izurjen za preverjanje tipov (Kinds): %1$s - Jamči za Zahteva jamstvo za Časovno obdobje Od Do Zdaj Vse do zdaj - Zadnja sinhronizacija: %1$s - Od zadnje sinhronizacije Spletni zaznamki - Seznam spletnih zaznamkov je prazen. Dodajte ga s pritiskom na +. Dodaj spletni zaznamek Uredi spletni zaznamek URL @@ -3187,6 +2838,24 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, %1$s in še %2$d drugih + Policija + Hitrostna kamera + Zastoj + Nesreča + Cesta zaprta + Delo na cesti + Nevernost + Stanje cest + Udarna jama + Megla + Led + Žival na cestišču + Dogodek na cesti + Dogodek na cesti + Še vedno tam + Ni več tam + Potrdi prometno poročilo + Označi kot odstranjeno Ciljni znesek (sat) 100000 Opiši svoj cilj @@ -3197,13 +2866,10 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, https://example.com/image.jpg URL spletišča (poljubno) https://example.com - Končni rok (poljubno) Izberi končni rok Nov cilj - Ustvari cilj Zahteva za izbris sledi Zahtevajte od relejev, da trajno izbrišejo vse vaše podatke do izbranega datuma. To dejanje temelji na standardu NIP-62 in je v nekaterih regijah pravno zavezujoče. - Izberi rele Naslovni releji VSI RELEJI S tem boste vsem relejem poslali zahtevo za izbris vse vsebine, povezane z vašim ključem, do izbranega datuma. Ta dogodek bo oddan v najširšem možnem obsegu. Tega dejanja ni mogoče razveljaviti. @@ -3219,7 +2885,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Izberi datum Izberi čas Pregled zahtev za izbris - Osveži To so vaše pretekle zahteve za izbris sledi, najdene na povezanih relejih. Releji, ki so označeni v teh dogodkih, ne bi smeli vsebovati nobenih vaših podatkov, ustvarjenih pred datumom dogodka. Ni najdenih zahtevkov za izbris Doslej še niste poslali nobene zahteve za izbris sledi. @@ -3262,7 +2927,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Blokiraj dogodek Dovoli tip (kind) Blokiraj IP - Javni ključ (hex) ID dogodka (hex) Številka tipa (kind) IP naslov @@ -3273,7 +2937,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Ime releja Opis releja URL ikone releja - Upravljanje releja Upravljanje Člani Člani %1$s @@ -3344,7 +3007,6 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Možnosti paketa emojijev Moji emoji paketi Emojiji - Išči med naborom emojijev Zasebno Zasebni emojiji Javni emojiji so vidni vsem. Ko dodate ta paket, se bodo pojavili v meniju za odzive in v izbirniku ob vpisu dvopičja (\":\"). @@ -3369,4 +3031,92 @@ Za ohranitev zasebnosti to denarnico polni in prazni prek ne-zasebnih računov, Nowhere Drop Umetnost Nowhere Forum Nowhere + + Marmot skupine + Ustvari skupino + Ustvari Marmot skupino + Ustvarjena bo nova skupina MLS. Člane lahko dodate kasneje. + Marmot skupina + Skupina %1$s… + %1$s… + Znano + Znano (%1$d) + Nova prošnja + Nova prošnja (%1$d) + Nimate še nobenih skupin + Ustvari skupino ali sprejmi povabilo. + Ni povabil + Povabila v skupine se bodo prikazala tukaj, dokler jih ne sprejmete. + Zaenkrat, še ni sporočil + + %1$d sporočilo + %1$d sporočili + %1$d sporočila + %1$d sporočilo + + + %1$d član + %1$d člana + %1$d člani + %1$d članov + + Ime skupine + Vnesi ime skupine + Vnesite opis skupine (neobvezno) + Spremembe bodo potrjene prek MLS in poslane vsem članom skupine. + Podatki o skupini so posodobljeni + Posodobitev ni uspela: %1$s + Skupine ni bilo mogoče ustvariti: %1$s + KeyPackage releji niso nastavljeni + Še nimate seznama relejev za KeyPackage (MIP-00). Ta seznam drugim sporoča, kje je objavljen vaš KeyPackage, da vas lahko povabijo v skupinske klepete. + +Ali želite za to uporabiti trenutne releje iz odhodnega predala? + Uporabi odhodne releje + Zaenkrat preskoči + Podatki o skupini + Uredi podatke o skupini + Zapusti skupino + ta skupina + Ste prepričani, da želite zapustiti skupino \"%1$s\"? Po tem ne boste več prejemali sporočil iz te skupine. + Skupine ni bilo mogoče zapustiti: %1$s + Dodajam %1$s… + Dodajanje ni uspelo \"%1$s\": %2$s + neznana napaka + Če želite osebo dodati, mora najprej objaviti svoj KeyPackage (kind: 30443). + Dodaj v skupino + Dodaj člana + Dodaj člana + Ime, npub, ali NIP-05 + (vi) + - administrator + Član odstranjen + Člana ni bilo mogoče odstraniti: %1$s + Odstrani člana + Ste prepričani, da želite odstraniti »%1$s« iz te skupine? + Podeli + Podeli administratorske pravice + Podeli administratorske pravice + Želite »%1$s« postaviti za administratorja skupine? Administratorji lahko dodajajo ali odstranjujejo člane, spreminjajo podatke o skupini in drugim članom podeljujejo administratorske pravice. + Administratorske pravice so bile podeljene + Administratorskih pravic ni bilo mogoče podeliti: %1$s + Prekliči + Prekliči administratorske pravice + Prekliči administratorske pravice + Revoke admin privileges from \"%1$s\"? They will remain a member of the group. + Administratorske pravice so bile preklicane + Administratorskih pravic ni bilo mogoče preklicati: %1$s + Releji + ni dogodkov + zadnji dogodek%1$s + Ni član te skupine + Kopiraj + Ponastavi na samodejno izbiro + URL vmesnika Explorer API + Plačaj račun iz DVM + Plačaj %1$s satov DVM-ju + Prejemnikova \"lightning\" storitev na %1$s ni na voljo. Izračunana je bila iz \"lightning\" naslova \'%2$s\'. Napaka: %3$s. Preverite, ali strežnik deluje in ali je \"lightning\" naslov pravilen + Ni bilo mogoče razrešiti %1$s. Preverite, ali ste povezani, ali je strežnik dosegljiv in ali je lightning naslov %2$s pravilen.\n\nIzjema je bila: %3$s + Napaka pri razčlenjevanju JSON med pridobivanjem fakture iz %1$s. Preverite uporabnikove nastavitve za \"Lightning\" + Ni mogoče ustvariti lightning fakture. Sporočilo od %1$s: %2$s + Ni mogoče ustvariti lightning fakture od %1$s: Element \'pr\' ni bil najden v JSON-u. diff --git a/amethyst/src/main/res/values-sr-rSP/strings.xml b/amethyst/src/main/res/values-sr-rSP/strings.xml index 72caf7fa04..b1a26a27e5 100644 --- a/amethyst/src/main/res/values-sr-rSP/strings.xml +++ b/amethyst/src/main/res/values-sr-rSP/strings.xml @@ -15,8 +15,6 @@ Спам лажно представљање Незаконито понашање - Непознат - Икона релеја Непознати аутор Копирај текст Копирај ИД аутора @@ -27,7 +25,6 @@ Пријави нежељену пошту/превару Пријавите лажно представљање - Пријавите експлицитни садржај Пријавите незаконито понашање Користите јавни кључ и јавни кључеви су само за читање. Пријавите се са приватним кључем да бисте могли да одговорите Користите јавни кључ и јавни кључеви су само за читање. Пријавите се са приватним кључем да бисте могли да појачате постове @@ -52,4 +49,5 @@ + diff --git a/amethyst/src/main/res/values-sv-rSE/strings.xml b/amethyst/src/main/res/values-sv-rSE/strings.xml index 5edc0cd1c5..c4ff8c892e 100644 --- a/amethyst/src/main/res/values-sv-rSE/strings.xml +++ b/amethyst/src/main/res/values-sv-rSE/strings.xml @@ -32,8 +32,6 @@ Annat Trakasseri Våld - Okänd - Relä ikon Okänd användare Kopiera Text Kopiera användarens ID @@ -48,12 +46,9 @@ Rapportera Spam / Scam Rapportera identitetsstöld - Rapportera explicit innehåll Rapportera olagligt beteende Anmäl skadlig programvara - Anmäl Mod Skadlig kod - Mod Logga in med en privat nyckel för att kunna svara Logga in med en privat nyckel för att kunna boosta inlägg Logga in med en privat nyckel för att gilla inlägg @@ -67,17 +62,14 @@ Logga in med en privat nyckel för att kunna sluta följa Du använder en offentlig nyckel, och offentliga nycklar är endast läsbara. Logga in med en privat nyckel för att kunna dölja ett ord eller en mening Du använder en offentlig nyckel, och offentliga nycklar är endast läsbara. Logga in med en privat nyckel för att kunna visa ett ord eller en mening - Du använder en publik nyckel som är skrivskyddad. Logga in med en privat nyckel för att ändra inställningar Du använder en publik nyckel som är skrivskyddad. Logga in med en privat nyckel för att ladda upp Du använder en publik nyckel som är skrivskyddad. Logga in med en privat nyckel för att signera händelser Otillåten dekryptering Signatären har inte godkänt den dekryptering som krävs. Aktivera NIP-44-dekryptering i din signeringsapp och försök igen Signatör saknas Har signeringsappen avinstallerats? Kontrollera om den är installerad och innehåller det här kontot. Logga ut och in igen om den har ändrats. - Signatären betedde sig oväntat Extern signatär returnerade data som är ovanliga för begäran. Det kan finnas en bugg i antingen Amethyst eller signatären. Zaps - Antal visningar Boosta boostad redigerat @@ -90,9 +82,7 @@ Lägg till "Svarar till " " och " - "i kanalen " Profil Banner - Betalning lyckades Fel vid tolkning av felmeddelande " Följer" " Följare" @@ -165,7 +155,6 @@ Inte tillräckligt saldo i en mint som denna mottagare accepterar. Fyll på din Cashu-plånbok först. Tillgängligt för denna mottagare: %1$s sats Nätverksavgift - din plånboksapp Transaktion: %1$s Lightning Dricks Notering till mottagaren @@ -179,16 +168,13 @@ Synligt Prefix 😎 Lägg till inlägg - "Fel vid analys av förhandsvisning för %1$s : %2$s" "Förhandsgranska kortbild för %1$s" Artikel - Ny kanal Kanal Namn Min fantastiska grupp Bild Url Bild-URL (valfritt) Beskrivning - Beskrivning saknas "Om oss.. " Vad tänker du på? Skriv ett meddelande… @@ -198,42 +184,25 @@ Skapa Byt namn Avbryt - Det gick inte att ladda upp bilden - Relä Adress - Inlägg - Bytes Fel Fel Andel lyckade anslutningar till reläet - Antal anslutningsfel under denna session - Hem Flöde - Privata Meddelande Flöde - Publik Chat Flöde - Globalt Flöde - Sök i Flödet Sök och lägg till användare - Lägg till en användare Lägg till Relä - Namn - Namn (för @taggning) Mitt @tag-namn Visningsnamn Mitt visningsnamn Struts McAwesome Välkommen struts! Användarnamn - Mitt användarnamn Om mig Profilbild URL Banner URL Websida URL Pronomen - LN Adress - LN URL (Utdaterad) Källrelän kan vara föråldrade Varning om föråldrat relä Spara till telefon - Spara i Galleri Bild sparad till galleriet Nedladdning av video har startat… Nedladdning av media har startat… @@ -250,15 +219,12 @@ Ta en bild Spela in video Spela in ett meddelande - Spela in ett meddelande Tryck och håll in för att spela in ett meddelande Spela in igen Spelar in Spelar in %1$s - Laddar upp… Uppladdningsfel Misslyckades med att ladda upp röstmeddelandet - Oväntat uppladdningstillstånd NIP-95 stöds ännu inte för röstmeddelanden Uppladdning av röst misslyckades: %1$s Ingen @@ -270,8 +236,6 @@ Användaren har inte en Lightningadressinställning för att ta emot sats "svara här.. " I den här chatten - Kopierar antecknings-ID till urklipp för delning - Kopiera kanal-ID (anteckningen) till Urklipp Redigerar kanalmetadata Gå med Känd @@ -285,7 +249,6 @@ Svar Dina Galleri - "Följer" "Rapporter" "%1$s Rapporter" Fler alternativ @@ -293,11 +256,8 @@ Websida Lightning Adress Kopierar Nsec ID (ditt lösenord) till urklipp för säkerhetskopiering - Kopiera hemlig nyckel till urklipp Visa QR-kod för privat nyckel Visa QR-kod för krypterad privat nyckel - Kopierar den publika nyckeln till urklipp för delning - Kopiera Public Key (NPub) till Urklipp Skicka ett direkt meddelande Redigerar användarens metadata Följ @@ -326,8 +286,6 @@ Hur ska vi kalla dig? Har du inget Nostr konto? Har du redan ett Nostr konto? - Skapa ett nytt konto - Skapa en ny nyckel Ladda flöde Laddar kontot krypterat @@ -343,13 +301,7 @@ Öppen omröstning Flöde är tomt. Uppdatera - Skapad - med beskrivning av - och bild - ändra chat namn till Ny chattprofil: - beskrivning till - och bild till Lämna Sluta följa Kanal skapad @@ -386,7 +338,6 @@ Nostr-adress aldrig nu - sekunder t m d @@ -394,7 +345,6 @@ Svordomar / Hatiskt tal Anmäl hattal Rapportera nakenhet/porr - andras Markera alla kända som lästa Markera alla nya som lästa Markera allt som läst @@ -413,8 +363,6 @@ Autentisering misslyckades Biometri misslyckades med att autentisera ägaren av denna telefon Biometri misslyckades med att autentisera ägaren av denna telefon. Fel: %1$s - Fel - "Skapad av %1$s" "Tilldelad Badge för %1$s" Bild på utmärkelse Du har blivit tilldelad en ny Badge @@ -422,7 +370,6 @@ Kopierade anteckningstext till urklipp Kopierade författarens @npub till urklipp Kopierade antecknings-ID (@note1) till urklipp - Välj Text "<Kan inte dekryptera privat meddelande>\n\nDu citerades i en privat/krypterad konversation mellan %1$s och %2$s." Lägg till nytt konto Konton @@ -434,8 +381,6 @@ Välj konto Lägg till nytt konto Aktivt konto - Har privat nyckel - Läs bara, ingen privat nyckel Tillbaka Välj Dela webbläsarlänk @@ -459,14 +404,12 @@ Tysta tråd Avtysta tråd Rapportera - Radera Visa inte igen Spam eller scams Svordomar eller hatiskt beteende Skadlig identitetsstöld Nakenhet eller grafiskt innehåll Olagligt beteende - Skadlig kod Blockering av en användare kommer att dölja deras innehåll i din app. Dina anteckningar är fortfarande offentliga, inklusive för personer du blockerar. Blockerade användare listas på skärmen Säkerhetsfilter. Rapportera missbruk @@ -494,7 +437,6 @@ Välj schemalagd tid Schemalägg för… Publiceras om %1$s - Skulle ha publicerats för %1$s sedan Tid Schemalägg inlägg Avbryt schemaläggning @@ -569,7 +511,6 @@ Författare Förfrågningar Godkännanden - Inga gemenskaper matchar detta filter. Verifierbara regler (valfritt) Publicerar ett maskinläsbart regeldokument (NIP-9B) tillsammans med gemenskapen. Klienter som stödjer det blockerar inlägg som inte matchar innan de skickas. Tillåtna händelsetyper @@ -598,26 +539,15 @@ Lägg till WoT-grind Global max händelsestorlek (valfritt) Byte — lämna tomt för ingen global gräns. - Mottagna - Mina - Tilldelade - Upptäck Nytt märke - Redigera märke Tilldela märke Acceptera Avvisa Ta bort från profil - Märkes-ID (d-tag) - mod, bidragsgivare-2025… Namn Läsbart namn på märket Beskrivning Varför delas detta märke ut? - Bild-URL (1024×1024) - https://exempel.com/badge.png - Miniatyr-URL (valfritt) - https://exempel.com/badge-thumb.png Ladda upp en bild Välj en fyrkantig bild som ska vara ansiktet på ditt märke. Laddar märke… @@ -626,7 +556,6 @@ Ta bort Märke utan namn Tilldelat %1$d - Du fick ett märke Profilmärken Märken · %1$d Välj vilka av märkena du fått som ska visas på din profil. @@ -672,10 +601,6 @@ Dela dina träningspass Låt Amethyst läsa avslutade träningspass från Health Connect (Samsung Health, Google Fit, Fitbit, Garmin…) och föreslå ett inlägg. Anslut - Nytt träningspass upptäckt - Dela - Avvisa - %1$s slag/min Från Health Connect Löpning Promenad @@ -689,7 +614,6 @@ Kost Fasta Appar - Appar Källa: %1$s v%1$s Ladda ner @@ -698,12 +622,10 @@ Ämnen Länkar Senaste utgåvan - Kommentarer Bli först med att kommentera. av Visa äldre utgåvor Dölj äldre utgåvor - Kalendrar Kortfilmer Offentliga chattar Följpaket @@ -713,18 +635,14 @@ ett Nest Scen Väntar på talare… - Publik Räck upp handen Sänk handen Anslut ljud - Koppla från Tysta Slå på ljud - Ansluter… Hittar rummet Öppnar transport Förhandlar ljud - Ljud anslutet Återansluter… Lyssna på inspelningen Kunde inte skicka meddelandet @@ -732,9 +650,7 @@ Stänga det här rummet? Alla deltagare kommer att kopplas från. Rummet visas som STÄNGT i flödet. Stäng rum - Välj en framtida starttid. Ljudet misslyckades: %1$s - Ljud är inte tillgängligt för det här rummet Tala Lämna scenen Stäng av mikrofon @@ -742,7 +658,6 @@ Går live… Sändning misslyckades: %1$s Tystning misslyckades: %1$s - Mikrofonåtkomst krävs för att tala i det här rummet. Öppna inställningar Ljudrum Håller ljudet igång medan rummet är öppet. @@ -753,7 +668,6 @@ Gå med i nest Värd Öppna - Senaste chatt Ingen är i rummet just nu. %1$d lyssnar Värd @@ -781,8 +695,6 @@ Publik Händer Ingen i publiken än. - Skicka - Säg något… Inga meddelanden än. Var först att chatta. Reagera Redigera rum @@ -816,7 +728,6 @@ Åtgärden misslyckades Åtgärden kunde inte förberedas. Dela rum - Minimera Minimera för att fortsätta lyssna Ljudet bröts Läser in rum… @@ -849,7 +760,6 @@ Välj vilka MoQ-värdservrar Amethyst publicerar dina nests till. Den första posten används som standard när du startar ett nytt utrymme. Dina servrar Sparas som en utbytbar händelse av typ kind-10112 så andra klienter kan läsa dina inställningar. - Lägg till en nest-server Relä-URL (WebTransport) Auth-URL (JWT mint) Lägg till @@ -862,13 +772,11 @@ Ta bort server Inga nest-servrar än. Lägg till en nedan eller välj en rekommenderad server. Videor - Artiklar Musik Spellistor Avsnitt Poddar Visa avsnitt - Avsnitt Inga avsnitt hittades än %1$d avsnitt @@ -880,9 +788,6 @@ Spårtitel Artist Artistens namn - Ljud-URL - https://… .mp3 - URL till omslagsbild (valfritt) Album (valfritt) Längd i sekunder (valfritt) Sångtext eller medverkande (valfritt) @@ -892,7 +797,6 @@ Lägg till i spellista Du äger inga spellistor än. Använd fältet ovan för att skapa en. Hantera alla spellistor - Ny spellista Spellistans namn Skapa (namnlös spellista) @@ -928,9 +832,6 @@ Ta bort bokmärkeslista Visa inlägg Visa artiklar - Visa länkar - Visa hashtags - Du har inga bokmärkeslistor ännu. Tryck på knappen nedan för att skapa en. Intresseuppsättningar Du har inga intresseuppsättningar ännu. Tryck på knappen nedan för att skapa en. Ny intresseuppsättning @@ -949,7 +850,6 @@ Privata inlägg(%1$s) Offentliga inlägg Offentliga inlägg(%1$s) - Privata artiklar Privata artiklar(%1$s) Offentliga artiklar Offentliga artiklar(%1$s) @@ -976,16 +876,6 @@ Metadata för bokmärkeslistor kan ses av alla på Nostr. Endast dina privata medlemmar är krypterade. Flytta till offentligt Flytta till privat - Wallet Connect Tjänst - Tillåter en Nostr Secret att betala zaps utan att lämna appen. Håll hemligheten säker och använd ett privat relä om möjligt - Plånbok Anslut Pubkey - Wallet Connect relä - Wallet Connect hemlighet - Visa secret key - nsec / hex privat nyckel - Ansluten - Inte ansluten - Avancerat: ange anslutningsinformation manuellt Snabba Zap-belopp Visas när du trycker på Zap-knappen. Tryck på ett belopp för att ta bort det. Om du lämnar det tomt öppnas en dialog för att ange ett belopp varje gång. Skicka on-chain istället @@ -1017,14 +907,8 @@ Anslut plånbok Visa relä-flöde Pantbelopp i Sats - Dela Poll - Obligatoriska fält: - Zap mottagare - Beskrivning av primär omröstning… - Alternativ Alternativ %s Beskrivning av omröstningsalternativ - Valfria fält: Minsta Zap Maximal Zap Konsensus @@ -1033,11 +917,8 @@ Flerval Stängningsdatum och tid Omröstningen stänger om %1$s - Avsluta efter - dagar Kunde inte rösta Omröstningen är stängd för nya röster - Zap belopp Endast en röst per användare tillåts i denna typ av omröstning "Letar efter Event %1$s" Skicka Zap @@ -1073,11 +954,8 @@ Ingen Zap Inga spår i Nostr, bara i Lightning Anonym - Publicera som en ny engångsidentitet. Ditt konto kommer inte att kopplas till detta svar. - Detta svar kommer att publiceras från en ny anonym identitet Fil Server Välj en server att ladda upp denna fil till - LnAdress eller @Användare Mediaservrar Ställ in dina önskade mediauppladdningsservrar. Använd lokal Blossom-cache @@ -1086,10 +964,8 @@ Ingen lokal cache hittad på port 24242. Cacha endast profilbilder Begränsa den lokala cachen till profilbilder. Bilder och videor i flödet hämtas direkt från originalservrarna. - Du har inga NIP-96 servrar. Du kan använda Amethyst\'s lista, eller lägga till en nedan ↓ Du har inga Blossom servrar satta. Du kan använda Amethyst\'s lista, eller lägga till en nedan ↓ Rekommenderade Mediaservrar - Inbyggda mediaservrar Amethysts standardlista. Du kan lägga till dem individuellt eller lägga till listan. Använd standardlistan Lägg till mediaserver @@ -1112,36 +988,21 @@ Hashning Klart Fel - Dina Reläer (NIP-95) - Filer är värd för dina reläer. Nytt NIP: kontrollera om de stöder Sekretess Alternativ - Tor/Orbot Inställningar - Anslut via dina Orbot-inställiningar Justera Tor Inställningar - Koppla från Orbot/Tor? - Dina data kommer omedelbart att överföras till det vanliga nätverket Ja Nej - Följ lista Alla följare Alla Användare Följare Standard Följ-Lista - Följer via proxy Runt mig Global Kurerad - Schack Mina Tyst listan Följelistor Detta är följlistor avsedda för ditt eget bruk. Du kan följa användare privat eller offentligt. - Märkta bokmärken - Allmänna bokmärken - Offentlig - Privat - Blandad - Det verkar som att du inte har några följ-set ännu.\nTryck nedan för att uppdatera eller använd plusknappen för att skapa ett nytt. Ny Lägg till författare i följelista Lägg till eller ta bort användare från listor, eller skapa en ny lista med denna användare. @@ -1150,23 +1011,9 @@ %1$s är en privat medlem Lägg till som offentlig medlem Lägg till som privat medlem - Offentliga medlemmar - Privata medlemmar - Offentliga profiler - Privata profiler - medlem - medlemmar - Inga medlemmar Tom - %1$s finns inte i denna lista %1$s är inte medlem Dina listor och %1$s - Dina listor - Inga följelistor hittades, eller så har du inga. Tryck nedan för att uppdatera eller använd menyn för att skapa en ny. - Ett problem uppstod vid hämtning: %1$s - Skapa ny lista - Skapa ny %1$s-lista med användare - Skapar ett %1$s-följ-set och lägger till %2$s i det. Ny följelista Nytt rekommendationspaket Kopiera/Klona följelista @@ -1186,13 +1033,6 @@ Du byter namn från till.. Standardporten är 9050 - ## Anslut genom Tor med Orbot - \n\n1. Installera [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Starta Orbot - \n3. Kontrollera Socks-porten i Orbot. Standarden använder 9050 - \n4. Ändra vid behov porten i Orbot - \n5. Konfigurera Socks-porten på den här skärmen - \n6. Tryck på knappen Aktivera för att använda Orbot som proxy Orbot Socks Port Aktiv Tor Engine Använd den interna versionen eller Orbot @@ -1234,8 +1074,6 @@ Dölj din IP i alla anslutningar Skapa din egen Ogiltigt portnummer - Använd Orbot - Koppla ifrån Tor/Orbot Privata Meddelade Meddelar dig när ett privat meddelande kommer Zaps Mottaget @@ -1292,12 +1130,8 @@ Bluetooth Röstsamtal Videosamtal - Väntar på att andra ska ansluta\u2026 Lägg till deltagare Sök användare\u2026 - Kunde inte starta samtal - Kunde inte ta emot samtal - Kunde inte skapa samtalssession Behörighet krävs Amethyst behöver åtkomst till mikrofonen för att starta ett röstsamtal. Aktivera den i appens inställningar. Amethyst behöver åtkomst till kameran och mikrofonen för att starta ett videosamtal. Aktivera dem i appens inställningar. @@ -1331,24 +1165,13 @@ Android kan begränsa reläanslutningar i bakgrunden. Inaktivera batterioptimering för Amethyst för att säkerställa tillförlitliga notifieringar. Åtgärda nu Meddela: - Gå med i konversation - Användare eller grupp ID - npub, nevent eller hex - Skapa - Gå med Idag Varning för innehåll Varning: %1$s Det här inlägget innehåller känsligt innehåll som vissa människor kan tycka är stötande eller störande - Dölj alltid känsligt innehåll - Visa alltid känsligt innehåll - Visa alltid innehållsvarningar Dölj Visa Varna - Rekommenderas: - Filtrera skräppost från främlingar - Varna när inlägg har rapporter från dina följare Filtrera spam Döljer inlägg från främlingar som var exakt samma för 5 eller fler gånger Lägg till klient-tagg i mina händelser @@ -1380,22 +1203,17 @@ Mängden data i byte som skickades till detta relä, inklusive filter och händelser Mängden data i byte som mottogs från detta relä, inklusive filter och händelser Lagrade händelser - Ett fel inträffade vid försök att hämta information från Relay %1$s Ägare Används av Service-nyckel - Kör %1$s - Kör %1$s (%2$s) Version Programvara Kontakt Stödda NIPs Stödda GRASPs - Entréavgifter Inträde Prenumeration Publicering - Betalningar %1$s Betalnings-URL Målgrupp Policyer & länkar @@ -1403,7 +1221,6 @@ Begränsningar Länder Språk - Taggar Ämnen Alla länder Alla språk @@ -1418,64 +1235,48 @@ Öppna Läs Skriv - RTT Nätverk Typ NIP som stöds Krav - Senaste kontroll %1$d ms Accepterade typer Plats Aktiva prenumerationer - Väntande utgående händelser REQ-prenumerationer (%1$d) COUNT-prenumerationer (%1$d) Utgående händelser (%1$d) - Inga aktiva prenumerationer för detta relä %1$d författare %1$d ID:n sedan %1$s till %1$s gräns %1$d - Meddelandelängd - Prenumerationer - Filter - Längd på prenumerations-ID Min. prefix Max. eventtaggar - Innehållslängd Max. innehållslängd Kastar bort äldre än Accepterar upp till %1$s i framtiden för %1$s sedan - %1$s nollor %1$s bitar Lagringstid för händelser Innehållsstorlek Anslutning Åtkomstkontroll Min. PoW-svårighet - Autentisering Autentisering krävs - Betalning Betalning krävs Max. meddelandelängd Max. prenumerationer Max. filter per prenumeration Maxgräns (returnerade händelser) - Standardgräns (returnerade händelser) Max. SubID-längd Cashu Token Mint: %1$s Inlösen - Skicka till Zap Plånbok - Öppna i Cashu Plånbok Kopiera Token Öppna i annan app Ingen Lightning-adress angiven - Kopierade token till urklipp LIVE OFFLINE SLUTADE @@ -1526,7 +1327,6 @@ Marmot-tillstånd återställt. Kunde inte återställa Marmot-tillstånd: %1$s Alltid - Endast Wi-Fi Obegränsad WiFi Aldrig Slutförd @@ -1551,7 +1351,6 @@ Välj stilen för inlägg Profilgalleri stil Välj galleriets stil - Ladda bild Spammare Ljud avstängt. Klicka för att ta bort ljudlöst Ljud på. Klicka för att stänga av ljudet @@ -1563,18 +1362,13 @@ Nostr-adress verifierad Verifikation av Nostr-adress misslyckades Kontrollerar Nostr-adress - Välj/Avmarkera alla Standard Återställ till standardinställningar - Välj ett relä för att fortsätta - Vidarebefordra Zaps till: - Stödjande klienter kommer att vidarebefordra Zaps till LNAddress eller användarprofilen nedan istället för din egen Exponera plats som Lägger till en Geohash av din plats i inlägget. Allmänheten kommer att veta att du befinner dig inom 5 km från nuvarande plats Plats-exklusivt inlägg Endast anhängare av platsen kommer att se den. Dina allmänna anhängare kommer inte att se den. Hashtag-exklusivt inlägg - Endast anhängare av hashtaggen kommer att se den. Dina generella följare kommer inte att se den. Kommentera en webbplats Kommentera en extern resurs %1$d min läsning @@ -1595,20 +1389,14 @@ Ladda upp en ljudfil Välj en MP3, WAV eller FLAC. Den laddas upp till din mediaserver när du sparar. Ljudfil redo att laddas upp - Laddar upp… Laddar upp omslag och ljud och publicerar. Detta fortsätter även om du lämnar skärmen. - Uppladdning misslyckades: %1$s Laddar position Inga platsbehörigheter Lägger till en varning för känsligt innehåll innan ditt innehåll visas. Detta är idealiskt för NSFW-innehåll (inte säkert för arbete) eller innehåll som vissa personer kan uppleva som stötande eller störande Anledning (valfritt) - Ny Funktion - För att aktivera denna funktion kräver det att Amethyst skickar ett NIP-17 meddelande (GiftWrapped, Förseglade Direkta och Gruppmeddelanden). NIP-17 är nytt och de flesta klienter har ännu inte implementerat det. Se till att mottagaren använder en kompatibel klient. - Aktivera Publik Grupp Ny offentlig eller privat grupp - Relä Privat Till Ämne @@ -1620,9 +1408,6 @@ Förklaring till medlemmar Ändra namnet för de nya målen. Klistra in från urklipp - Ogiltig NIP-47 URI - URI %1$s är inte en giltig NIP-47 inloggnings-URI. - Anslut till ny NWC-plånbok Plånbok hittades inte Amethyst kunde inte hitta några plånboksappar som stöder Nostr Wallet Connect (NWC). \n\nVad du kan göra: @@ -1638,7 +1423,6 @@ Spela upp videor och GIFs automatiskt Spela upp videor automatiskt när de syns på skärmen Visa förhandsgranskning av URL - När bilder ska laddas Kopiera stacken Kopiera till Urklipp Kopierat till urklipp @@ -1654,43 +1438,21 @@ Media tillagd Media har lagts till i ditt profilgalleri Skapad den - Regler - Om oss Riktlinjer Moderatorer Logga in med Amber Uppdatera din status - Fel vid tolkning av felmeddelande Röster viktas av zap-beloppet. Du kan ställa in en minsta mängd för att undvika spammare och en maximal mängd för att undvika att en stor zapper tar över omröstningen. Använd samma belopp i båda fälten för att se till att varje röst värderas till samma belopp. Lämna tomt för att acceptera valfritt belopp. Kunde inte skicka zap Meddela användaren Meddelande %1$s Ok - Misslyckades att nå %1$s: %2$s - Det gick inte att montera NIP-11 url för %1$s: %2$s - Det gick inte att nå %1$s: %2$s - Det gick inte att tolka svaret från %1$s: %2$s - Relä avböjde förfrågan %1$s: %2$s - Misslyckades att nå %1$s: %2$s - Misslyckades att parsa resultatet från %1$s: %2$s - %1$s misslyckades med kod %2$s - Aktiv för: - Hem - Meddelanden - Chattar - Globalt - Sök Dela och vidarebefordra Zaps Stödjande klienter kommer att dela och vidarebefordra zaps till användarna som har lagts till här istället för dig Sök och lägg till användare Användarnamn eller visningsnamn Saknad lightning-konfiguration Användaren %1$s har inte ställt in en blixtfakturaadress för att ta emot satoshis - Procent - 25 - Delar zaps med - Vidarebefordrar zaps till - Blixtpengar hittades inte Betald Plånbok %1$s Fel vid öppning av signeringsapp @@ -1699,7 +1461,6 @@ Codec eller format stöds inte på den här enheten (%1$s). Försök öppna den i din webbläsare. Öppna i webbläsare Signeringsförfrågan avvisad - Underteckningsbegäran avvisad Kontrollera att signeringsprogrammet har godkänt denna transaktion Inga plånböcker hittades för att betala en blixtfaktura (Fel: %1$s). Installera en blixtpengaplånbok för att använda zaps Inga plånböcker hittades för att betala en blixtfaktura. Installera en blixtpengaplånbok för att använda zaps @@ -1715,40 +1476,23 @@ Välj ett alternativ Kunde inte betala fakturan Kunde inte ta ut - Kunde inte konfigurera Wallet Connect - Fel vid tolkning av NIP-47-anslutningssträngen. Kontrollera om den är korrekt med din plånboksleverantör: %1$s. Fel: %2$s - Fel vid tolkning av NIP-47-anslutningssträngen. Kontrollera om den är korrekt med din plånboksleverantör: %1$s. Kunde inte lösa in Cashu Mint gav följande felmeddelande: %1$s - Cashu-token har redan spenderats. Cashu mottagen %1$s sats skickades till din plånbok. (Avgifter: %2$s sats) Ingen kompatibel Cashu-plånbok hittades på systemet Kunde inte hämta fakturan från mottagarens servrar Din Wallet Connect-leverantör returnerade följande fel: %1$s - Kunde inte ansluta till Tor Tor ansluter inte Amethyst kunde inte slutföra uppstart av Tor. Vill du använda en vanlig (icke-Tor) anslutning så att flödet kan laddas? Vi kommer ihåg ditt val under nästa timme och försöker sedan Tor igen. Använd vanlig anslutning Fortsätt vänta - Kunde inte ladda ner relädokument Kunde inte montera LNUrl från Lightning Address \"%1$s\". Kontrollera användarens konfiguration - Mottagarens Lightning-tjänst på %1$s är inte tillgänglig. Den beräknades från Lightning Address \"%2$s\". Fel: %3$s. Kontrollera om servern är uppe och om Lightning Addressen är korrekt - Kunde inte lösa %1$s. Kontrollera om du är ansluten, om servern är uppe och om Lightning Addressen %2$s är korrekt - Kunde inte lösa %1$s. Kontrollera om du är ansluten, om servern är uppe och om Lightning Addressen %2$s är korrekt.\n\nUndantag var: %3$s - Kunde inte hämta fakturan från %1$s Kunde inte hämta faktura från %1$s: %2$s - Fel vid tolkning av JSON från Lightning Address. Kontrollera användarens Lightning-konfiguration Fel vid tolkning av JSON från %1$s. Kontrollera användarens blixtkonfiguration - Återuppringnings-URL hittades inte i användarens konfiguration för Lightning Address-servern Callback URL hittades inte från %1$s\'s svar - Fel vid tolkning av JSON från Lightning Address fakturahämtning. Kontrollera användarens Lightning-konfiguration - Fel vid tolkning av JSON från %1$ss fakturahämtning. Kontrollera användarens blixtkonfiguration Felaktig fakturabelopp (%1$s sats) från %2$s. Det borde ha varit %3$s Kunde inte skapa en Lightning-faktura innan Zap skickades. Mottagarens Lightning-plånbok skickade följande fel: %1$s - Det gick inte att skapa en blixt faktura. Meddelande från %1$s: %2$s - Kunde inte skapa en Lightning-faktura innan Zap skickades. Elementet pr hittades inte i den resulterande JSON. - Det gick inte att skapa en blixtfaktura från %1$s: Elementet pr hittades inte i den resulterande JSON. Skrivskyddad användare Inga reaktioner konfigurerade Aviseringar @@ -1774,13 +1518,11 @@ Skicka ett meddelande till säljaren Hej %1$s, är detta fortfarande tillgängligt? Hallå där, är detta fortfarande tillgängligt? - Sälj en artikel Titel iPhone 13 Skick Kategori Pris (i Sats) - 1000 Plats Stad, Region, Land Ny @@ -1809,20 +1551,13 @@ Annat Det gick inte att ladda upp media Kunde inte öppna den komprimerade filen - Fel vid komprimering av media: %1$s Fel vid uppladdning: %1$s Servern gav inte en URL efter uppladdning Kunde inte ladda ner uppladdade medier från servern Kunde inte kontrollera nedladdad fil efter uppladdning: %1$s - Kunde inte förbereda lokal fil att ladda upp: %1$s Det gick inte att nå %1$s: %2$s - Uppladdning misslyckades: %1$s Radering misslyckades: %1$s Media är för stort för NIP-95 - Kunde inte ladda miniatyrbild - Kunde inte förbereda header information: %1$s - Komprimering avbruten - Komprimering misslyckades att returnera en fil Kryptera filer Kryptera filer innan uppladdning för integritet. Vissa servrar kanske inte accepterar krypterade filer på gratiskonton. Krypterad uppladdning misslyckades @@ -1849,27 +1584,18 @@ Kan inte ta bort metadata från AVIF: %1$s Redigera utkast Logga in med QR-kod - Rutt Hem - Sök Upptäck Meddelanden Aviseringar - Globalt Kortfilmer - Bilder - Träningspass Kalendrar Kalenderlistor Schack Plånbok - Saldo Skicka Ta emot Transaktioner - Ingen plånbok ansluten - Konfigurera en Nostr Wallet Connect (NWC)-anslutning i dina zap-inställningar för att använda plånboken. - Konfigurera plånbok sats Klistra in en BOLT-11-faktura Betala @@ -1897,8 +1623,6 @@ Detta tar bort plånboksanslutningen. Du kan alltid lägga till den igen senare. Plånboksnamn Min plånbok - Dina plånböcker - Hantera plånböcker Inga plånböcker anslutna Anslut en eller flera NWC-plånböcker för att skicka och ta emot betalningar. Lägg till NWC-anslutning @@ -1917,12 +1641,9 @@ Mint-URL Ta bort mint Historik - Redigera plånbok Nutzap-nyckel (avancerat) En separat privat nyckel som endast används för att ta emot NIP-61-nutzaps. Inte din Nostr-identitetsnyckel. Generera en ny nyckel - Ogiltigförklarar alla väntande nutzaps som är låsta till den nuvarande nyckeln. - Behåll nuvarande nyckel Privat P2PK-nyckel (hex) Redigera Cashu-plånbok Spara ändringar @@ -1938,7 +1659,6 @@ Populära mints Matchande mints - Rekommendera den här mint Ta emot Skicka LN Skicka token @@ -1998,10 +1718,6 @@ Spara Byt namn Byt namn på plånbok - Redigera - Ogiltig URI för NWC-anslutning - Flytta upp - Flytta ner On-chain-transaktioner Ingen on-chain-adress tillgänglig för detta konto. Ingen on-chain-backend är konfigurerad. @@ -2076,17 +1792,13 @@ Betalning skickad (%1$d av %2$d kvitto publicerat), men nästa kvitto kunde inte publiceras Betalning skickad (%1$d av %2$d kvitton publicerade), men nästa kvitto kunde inte publiceras - Säkerhetsfilter Importera följare Nytt inlägg Nya kort: bilder eller videor Nytt Community-meddelande Ny produkt - Nytt Geo-Exklusivt inlägg Ny artikel Ny omröstning - Ny zap-omröstning - Ny vanlig omröstning Ny bild Ny kalenderhändelse Redigera kalenderhändelse @@ -2101,8 +1813,6 @@ Dag Kommande Tidigare - Inga kommande eller tidigare kalenderhändelser från ditt valda flöde än. - Inga kalenderlistor än. Din kalender är tom Händelser delade av personer du följer dyker upp här. Tryck på +-knappen för att skapa egna. Inga listor än @@ -2129,8 +1839,6 @@ Nästa vecka Föregående dag Nästa dag - Inga händelser denna dag - Inga händelser Fortsätter Dag %1$d av %2$d Lägg till i telefonens kalender @@ -2190,7 +1898,6 @@ Den valda bilden kunde inte laddas upp. Försök igen eller klistra in en URL. Deltagare (%1$d) Sök namn, npub eller nip-05 - Ange en giltig npub… eller 64-teckens hex pubkey. Ta bort deltagare Kalenderpåminnelser Skicka påminnelser @@ -2211,10 +1918,7 @@ Händelsedetaljer Ny kort video Ny lång video - Titel Sammanfattning (valfritt) - URL för omslagsbild (valfritt) - Skriv din artikel i markdown… Förhandsgranskning Redigera Lägg till en rubrikbild @@ -2298,18 +2002,14 @@ Relä %1$s Expandera relälistan Notalternativ - Relälistväljare Omröstning Inaktivera omröstning Bitcoin-faktura Avbryt Bitcoin-faktura - Avbryt Sälja en artikel Zappraiser Avbryt Zappraiser Plats Ta bort plats - Zap-split - Avbryt Zap-split Lägg till varning för innehåll Ta bort varning för innehåll Lägg till utgångsdatum @@ -2324,11 +2024,8 @@ Ogiltig adress Amethyst fick en URI att öppna men den URI var ogiltig: %1$s DM Inkorg Reläer - Reläer: %1$s - Använder vanliga reläer Ställ in dina privata inkorgsreläer Denna inställning låter alla veta vilka reläer som ska användas när de skickar meddelanden till dig. Utan dem kan du missa vissa meddelanden. - Bra alternativ är:\n - inbox.nostr.wine (betald)\n - you.nostr1.com (personliga reläer - betald) Bra alternativ är:\n - auth.nostr1.com (gratis)\n - inbox.nostr.wine (betalad)\n - relay.0xchat.com (gratis) Sätt in mellan 1–3 reläer för att fungera som din privata inkorg. DM Inkorg reläer bör acceptera alla meddelanden från vem som helst, men endast tillåta dig att ladda ner dem. Ställ in nu @@ -2348,7 +2045,6 @@ Att skapa en relälista specifikt för att ta emot aviseringar är avgörande för din Nostr-upplevelse. Lägg till mellan 1–3 reläer som tar emot aviseringar åt dig. Se till att de inte kräver betalning eller web of trust från avsändaren, annars får du bara aviseringar från betalande eller långsiktiga användare. Bra alternativ är:\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social - DM uppladdning Relä inställningar Ordna om relä Offentliga hemreläer @@ -2365,12 +2061,8 @@ Relays där dina MLS KeyPackages publiceras (MIP-00). Andra användare hämtar dessa KeyPackages för att bjuda in dig till Marmot-gruppchatter. Lägg till mellan 1–3 relays som accepterar KeyPackage-händelser från dig och tillåter offentlig läsning. Privata reläer Infoga mellan 1–3 reläer för att lagra händelser som ingen annan kan se, som dina Utkast och/eller appinställningar. Helst är dessa reläer antingen lokala eller kräver autentisering innan du laddar ner varje användares innehåll. - Allmänna reläer - Amethyst använder dessa reläer för att ladda ner inlägg åt dig. Anslutna reläer Aktuell lista över reläer som används - Rekommenderade reläer - Lägg till följande reläer till din Allmänna relälista för att ta emot inlägg från de listade användarna. Sökreläer Lista över reläer som används för sökning och taggning av användare. Taggning och sökning kommer inte att fungera om inga alternativ är tillgängliga. Lokala reläer @@ -2405,11 +2097,8 @@ Denna version tillhandahölls av: Version %1$s Tack! - Maximal gräns Begränsade skrivningar Forkad från - FORK - Git Repository: %1$s Webbplats: Klona: Öppen @@ -2434,20 +2123,13 @@ Redigera artikel Redigera inlägg Förslag till att förbättra ditt inlägg - Sammanfattning av ändringar - Snabba fixar… Acceptera förslaget Starta video i ett popup-fönster Ladda ner - Undertexter på - Undertexter av - Förseglat meddelande av. Klicka för att slå på förseglat meddelande - Förseglat meddelande på. Klicka för att stänga av förseglat meddelande Skicka Spela upp användarnamn som ljud Häftstift Skanna QR-kod - Navigera till tredjeparts plånboksleverantören Alby Välj datum Det går inte att svara på ett utkast Det går inte att citera ett utkast @@ -2489,23 +2171,18 @@ Otillräckligt lagringsutrymme - Servern har inte tillräckligt med lagringsutrymme för att bearbeta begäran framgångsrikt Loop upptäckt - Servern upptäcker en oändlig loop medan den bearbetar begäran Nätverksautentisering krävs - Klienten måste autentiseras för att få tillgång till nätverket - NIP-96 Servar - Lägg till så många servrar som du vill. Du kan välja vilken som ska användas senare när du laddar upp din bild Blossom Servrar Lägg till så många servrar som du vill. Du kan välja vilken som ska användas senare när du laddar upp din bild Lägg till en NIP-96 Server Lägg till en Blossom Server Radera alla Är du säker på att du vill ta bort alla utkast? - Stack: Torrent fil Ladda ner Det gick inte att öppna filen Inga torrent-appar installerade för att öppna och ladda ner filen. Händelsen har inte tillräcklig information för att skapa en magnetlänk - Mina listor/set Mina listor - Användare Välj en lista för att filtrera flödet Flöden Hashtaggar @@ -2536,7 +2213,6 @@ Privat meddelande Offentligt meddelande Chatt Relä - Reläet som alla användare av den här chatten ansluter till Dela bild… Kunde inte dela bilden, försök igen senare… Dela video… @@ -2583,7 +2259,6 @@ Vill du skicka den senaste kraschrapporten till Amethyst i ett DM? Ingen personlig information kommer att delas Skicka Detta meddelande försvinner om %1$s - Detta meddelande försvinner om %1$d dagar Välj signatör Redan i listan Privata medlemmar @@ -2605,7 +2280,6 @@ Paketnamn Nytt paketnamn Paketbeskrivning - Ny paketbeskrivning Sänd lista Sänd rekommendationspaket Ta bort lista @@ -2619,13 +2293,9 @@ Fäll ihop Fäll ut Försök igen misslyckade (%1$d) - +%1$d fler sändningar - " (%1$d pågår)" - %1$d/%2$d reläer Tidsgräns överskriden Försöker igen… Försök igen - Visa Avfärda %1$d/%2$d Sänder @@ -2651,7 +2321,6 @@ Starta om Acceptera Avböj - Nytt parti Nytt schackparti Laddar parti… Parti hittades inte @@ -2806,23 +2475,13 @@ Profil att importera från namnsökning, npub1…, alice@example.com Stöder npub, NIP-05, hex och Namecoin (.bit / d/ / id/) - Slå upp följarlista Tips %1$d konton hittades %1$d valda - Löst via Namecoin - Följer nu %1$d konton - Ditt flöde är klart. - Hoppa över - Sök en till Följ %1$d konton - Importera fler - Fortsätt Hoppa över för nu - Löser upp %1$s… Hämtar följarlista… Inga följare hittades - Följer %1$d konton… "Ange profilen för en vän eller gemenskapsledare. Du kan använda deras npub, NIP-05-adress eller ett Namecoin-namn som alice@example.bit eller id/alice för blockchain-verifierade identiteter." Välj alla %1$d%% drifttid @@ -2830,7 +2489,6 @@ Testa anslutning Testar servrar… Ansluten - Misslyckades Testresultat Diagnostik Senaste test @@ -2843,9 +2501,6 @@ Lita på Avvisa Relä-synkronisering - Relä-synkronisering - Publicera om dina händelser på alla kända reläer för att hålla dina utkorgs-, inkorgs- och DM-reläer uppdaterade. Kräver Wi-Fi — detta kan använda mycket data. - Öppna relä-synkronisering… Vad detta gör Det här verktyget söker igenom alla reläer som din app har sett och omfördelar dina händelser till rätt destinationer: Ladda ner alla händelser du skapat och skicka dem till dina utkorgsreläer. @@ -2855,14 +2510,9 @@ Använda mobildata? Starta synkronisering Starta ändå (mobildata) - Pausa - Återuppta - Börja om Avbryt Reläer: %1$d / %2$d Omfördelade händelser: %1$d nya av %2$d skickade och %3$d mottagna - Synkronisering pausad - %1$d av %2$d reläer klara — %3$d händelser omfördelade hittills. Tryck på Återuppta för att fortsätta. Synkronisering klar Vidarebefordrade %1$d händelser till destinationsreläer av %2$d mottagna. %1$d händelser accepterade som nya av destinationsreläer. @@ -2877,16 +2527,13 @@ skick. %1$s mott. %1$s nya %1$s - inga händelser Bitcoin Explorer (OTS) - händelser händelser från dig händelser till dig sökbara händelser DMs profiler utgående listor - relä inställningar Senast sedd för %1$s sedan Senast sedd %1$s (för %2$s sedan) Senast sedd just nu @@ -2944,7 +2591,6 @@ Söker efter enheter på ditt Wi-Fi… HLS-uppladdning - Publicera HLS i flera upplösningar till din mediaserver Välj en video Din video transkodas till flera upplösningar så att tittare får mjuk uppspelning på alla anslutningar. Ändra @@ -2959,10 +2605,6 @@ H.265 inte tillgängligt på den här enheten — växlar till H.264. Versioner Källupplösning: %1$d×%2$d - Kommer att skapa: %1$s - (%1$s hoppas över — över källan) - %1$d kbps - över källa — kommer att hoppas över Publicera HD-video Publicerar ”%1$s”… Transkodar %1$s @@ -2974,7 +2616,6 @@ Video publicerad Din HD-video är live på Nostr. Något gick fel - Visa anteckning Klar Försök igen Paketåtgärder @@ -2989,30 +2630,21 @@ Attestering Giltig Ogiltig - Accepterad - Avvisad Verifierar - Verifierad Återkallad Giltig från %1$s Giltig till %1$s Attesteringsförfrågan - Begär attestering för en händelse Attestantens rekommendation Rekommenderad för typer: Attestantens kompetens - Kompetent att verifiera typer: %1$s - Intygar Begär attestering till Datumintervall Från Till Nu All tid - Senaste synkronisering: %1$s - Sedan senaste synkronisering Webbbokmärken - Inga webbbokmärken ännu. Tryck på + för att lägga till. Lägg till webbbokmärke Redigera webbbokmärke URL @@ -3051,13 +2683,10 @@ https://example.com/image.jpg Webbplats-URL (valfritt) https://exempel.se - Tidsfrist (valfritt) Sätt en tidsfrist Nytt mål - Skapa mål Begäran om försvinnande Begär att reläer permanent raderar all din data fram till det valda datumet. Denna åtgärd bygger på NIP-62 och är juridiskt bindande i vissa jurisdiktioner. - Välj ett relä Målreläer ALLA RELÄER Detta kommer att begära att ALLA reläer raderar allt kopplat till din nyckel fram till det valda datumet. Denna händelse kommer att sändas så brett som möjligt. Denna åtgärd kan inte ångras. @@ -3073,7 +2702,6 @@ Välj datum Välj tid Försvinnande historik - Uppdatera Dessa är dina tidigare Begäran om försvinnande-händelser som hittats på anslutna reläer. Reläer som är taggade i dessa händelser bör inte ha kvar någon av din data från före händelsedatumet. Inga försvinnandebegäranden hittades Du har inte skickat några Begäran om försvinnande-händelser ännu. @@ -3116,7 +2744,6 @@ Bannlys händelse Tillåt typ Blockera IP - Publik nyckel (hex) Händelse-ID (hex) Typnummer IP-adress @@ -3127,7 +2754,6 @@ Relänamn Relä beskrivning URL för reläikon - Hantera relä Hantera Medlemmar Medlemmar i %1$s @@ -3198,7 +2824,6 @@ Åtgärder för emoji-paket Mina emoji-paket Emojis - Bläddra bland emoji-uppsättningar Privat Privat emoji Offentliga emojis är synliga för alla och visas i din reaktionsmeny och i \":\"-autokompletteringen när detta paket finns i din emoji-lista. @@ -3223,4 +2848,10 @@ Nowhere Drop Nowhere Konst Nowhere Forum + + Mottagarens Lightning-tjänst på %1$s är inte tillgänglig. Den beräknades från Lightning Address \"%2$s\". Fel: %3$s. Kontrollera om servern är uppe och om Lightning Addressen är korrekt + Kunde inte lösa %1$s. Kontrollera om du är ansluten, om servern är uppe och om Lightning Addressen %2$s är korrekt.\n\nUndantag var: %3$s + Fel vid tolkning av JSON från %1$ss fakturahämtning. Kontrollera användarens blixtkonfiguration + Det gick inte att skapa en blixt faktura. Meddelande från %1$s: %2$s + Det gick inte att skapa en blixtfaktura från %1$s: Elementet pr hittades inte i den resulterande JSON. diff --git a/amethyst/src/main/res/values-sw/strings.xml b/amethyst/src/main/res/values-sw/strings.xml index fa2ca8e9dd..e460c8c816 100644 --- a/amethyst/src/main/res/values-sw/strings.xml +++ b/amethyst/src/main/res/values-sw/strings.xml @@ -32,8 +32,6 @@ Zingine Usumbufu Ukatili - Haijulikani - Aikoni ya Relay Mwandishi asiyejulikana Nakili Maandishi Nakili Kitambulisho cha Mwandishi @@ -48,12 +46,9 @@ Ripoti Barua Taka / Ulaghai Ripoti Uigaji - Ripoti Maudhui Dhahiri Ripoti Tabia Haramu Ripoti Programu Hasidi - Ripoti Msimamizi Programu hasidi - Msimamizi Ingia kwa kutumia Ufunguo wa Faragha ili uweze kujibu Ingia kwa kutumia ufunguo wa Faragha ili uweze kuboresha machapisho Ingia kwa kutumia ufunguo wa Faragha ili kupenda Machapisho @@ -67,15 +62,12 @@ Ingia kwa kutumia Ufunguo wa Faragha ili uweze Kuacha Kufuata Unatumia maneno ya umma na funguo za umma ni za kusoma tu. Ingia kwa kutumia ua Faragha ili kuweza kuficha neno au sentensi Unatumia maneno ya umma na maneno ya umma ni ya kusoma tu. Ingia kwa kutumia maneno ya Faragha ili kuweza kuonyesha neno au sentensi - Unatumia maneno ya umma na maneno ya umma ni ya kusoma tu. Ingia kwa kutumia maneno ya Faragha ili kuweza kubadilisha mipangilio Unatumia maneno ya umma na maneno ya umma ni ya kusoma tu. Ingia kwa kutumia maneno ya Faragha ili kuweza kupakia Unatumia maneno ya umma na maneno ya umma ni ya kusoma tu. Ingia kwa kutumia maneno ya Faragha ili kuweza kujisajili kwa matukio Usimbuaji Uisoidhinishwa Mtuaji sahihi hakuidhinisha usimbuaji unaohitajika ili kutekeleza operesheni hii. Washa usimbuaji NIP-44 kwenye programu yako ya utiaji sahihi kisha ujaribu tena Mtuaji sahihi hajaonekana Je, programu ya Utiaji sahihi iliondolewa? Angalia ikiwa programu ya utiaji sahihi imesakinishwa na ina akaunti hii. Ondoka kisha Uingie tena ikiwa programu ya utiaji sahihi imebadilika. - Programu ya utiaji sahihi imepata hitilafu - Idadi ya maoni Kuongeza imeimarishwa Nukuu @@ -83,9 +75,7 @@ Ongeza "kujibu " " na " - "katika chaneli " Bango la Wasifu - Malipo Yamefaulu Hitilafu katika kuchanganua ujumbe wa hitilafu " Kufuatia" " Wafuasi" @@ -101,9 +91,7 @@ Kiasi katika Sats Tuma Sats 😎 - "Hitilafu katika kuchanganua onyesho la kukagua %1$s : %2$s" "Hakiki Picha ya Kadi ya %1$s" - Kituo Kipya Kituo Kipya Kundi Langu la Ajabu Url ya picha @@ -114,35 +102,20 @@ Hifadhi Unda Ghairi - Kushindwa kupakia picha - Anwani ya Relay - Machapisho - Bayti Makosa - Malisho ya Nyumbani - Malisho ya Ujumbe Binafsi - Malisho ya Mazungumzo ya Umma - Malisho ya Kimataifa - Malisho ya Utafutaji Ongeza Relay Jina la Kuonyesha Jina langu la kuonyesha Jina la mtumiaji - Jina langu la mtumiaji Kuhusu mimi URL ya Picha ya Profaili URL ya Bango URL ya Tovuti - Anwani ya LN - URL ya LN (imepitwa na wakati) Picha imesave kwenye galeria Kushindwa kuhifadhi picha Pakia Picha - Inapakia… Mtumiaji hana anwani ya umeme iliyoandaliwa kupokea sati "jibu hapa.. " - Hunakili Kitambulisho cha Dokezo kwenye ubao wa kunakili ili kushiriki katika Nostr - Nakili Kitambulisho cha Kituo (Kumbuka) kwenye Ubao wa kunakili Huhariri Metadata ya Kituo Jiunge Inajulikana @@ -152,14 +125,10 @@ Mazungumzo Vidokezo Majibu - "Anafuata" Chaguo Zaidi Tovuti Anwani ya Umeme Hunakili Kitambulisho cha Nsec (nywila yako) kwenye ubao wa kunakili kwa ajili ya nakala rudufu - Nakili Ufunguo wa Siri kwenye Ubao wa Kunakili - Hunakili ufunguo wa umma kwenye ubao wa kunakili kwa ajili ya kushiriki - Nakili Ufunguo wa Umma (NPub) kwenye Ubao wa Kunakili Tuma Ujumbe wa Moja kwa Moja Huhariri Metadata ya Mtumiaji Fuata @@ -179,7 +148,6 @@ Kukubaliana na masharti ni lazima Ufunguo unahitajika Ingia - Tengeneza Ufunguo Mpya Inapakia malisho @@ -187,12 +155,6 @@ Jaribu tena Malisho ni tupu. Sasisha - imeundwa - na maelezo ya - na picha - ilisitisha jina la mazungumzo hadi - maelezo ya - na picha ya Ondoka Acha kufuata Kituo kimeundwa @@ -212,7 +174,6 @@ Lugha chafu / Maneno yenye chuki Ripoti Lugha yenye chuki Ripoti Uchi / Pornografia - wengine Funga kama Zimejulikana Funga kama Mpya Funga kama Zimejulikana @@ -220,23 +181,18 @@ Ufunguo wa siri (nsec) umeinakiliwa kwenye ubao wa kunakili Nakili Ufunguo Wangu wa Siri Uthibitishaji umeshindwa - Kosa - "Imeundwa na %1$s" "Picha ya tuzo ya alama kwa %1$s" Umepokea Tuzo Mpya ya Alama Tuzo ya alama imetolewa kwa Maudhui ya dokezo yamenakiliwa kwenye ubao wa kunakili Imesakinishwa @npub ya mwandishi kwa ubao wa kunakili Imesakinishwa ID ya andiko (@note1) kwa ubao wa kunakili - Chagua Matini "<Haiwezi kuifanyia utawala ujumbe binafsi uliofichwa>\n\nUlinukuliwa katika mazungumzo ya faragha/yaliyofichwa kati ya %1$s na %2$s." Ongeza Akaunti Mpya Akaunti Chagua Akaunti Ongeza Akaunti Mpya Akaunti Iliyo Hai - Ina ufunguo wa faragha - Soma tu, hakuna ufunguo wa faragha Rudi Chagua Shiriki Kiungo cha Kivinjari @@ -253,7 +209,6 @@ Futa Zuia Ripoti - Futa Usionyeshe Tena Barua Taka au Udanganyifu Lugha chafu au tabia yenye chuki @@ -278,27 +233,12 @@ Ongeza kwenye Vialamisho vya Umma Ondoa kutoka kwenye Vialamisho Binafsi Ondoa kutoka kwenye Vialamisho vya Umma - Huduma ya Kuchanganya Pochi - Inaidhinisha Nostr Secret kulipa zaps bila kuacha programu. Weka siri salama na tumia relay ya faragha ikiwezekana - Ufunguo wa Umma wa Kuchanganya Pochi - Kuchanganya Relay - Siri ya Kuchanganya Pochi - Onyesha ufunguo wa siri - nsec / ufunguo wa siri wa hex Kiasi cha Ahadi katika Sats - Chapisha Kura - Sehemu zinazohitajika: - Wapokeaji wa Zaps - Maelezo ya msingi ya kura… Chaguo %s Maelezo ya chaguo cha kura - Sehemu za hiari: Kima cha Chini cha Zaps Kima cha Juu cha Zaps Uamuzi - Funga baada ya - siku - Kiasi cha Zaps Kura moja tu kwa mtumiaji inaruhusiwa kwenye aina hii ya kura "Inatafuta Tukio %1$s" Ongeza ujumbe wa umma @@ -326,29 +266,12 @@ Bila Zap Hakuna alama katika Nostr, tu katika Lightning Seva ya Faili - LnAddress au @Mtumiaji - Relays Zako (NIP-95) - Faili zinahifadhiwa na relays zako. NIP mpya: hakikisha zinazisaidia - Usanidi wa Tor/Orbot - Unaweza kuunganisha kupitia usanidi wako wa Orbot - Kujitenga na Orbot/Tor yako? - Data yako itahamishwa mara moja kwenye mtandao wa kawaida Ndio Hapana - Orodha ya Kufuatilia Yafuatayo Yote Kote - ## Kuungana kupitia Tor na Orbot -\n\n1. Sakinisha [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) -\n2. Anza Orbot -\n3. Katika Orbot, angalia bandari ya Socks. Chaguo-msingi hutumia 9050 -\n4. Ikiwa ni lazima, badilisha bandari katika Orbot -\n5. Sanidi bandari ya Socks kwenye skrini hii -\n6. Bonyeza kitufe cha Kuamilisha kutumia Orbot kama mbadala Bandari ya Socks ya Orbot Nambari ya bandari sio sahihi - Tumia Orbot - Jitenge na Tor/Orbot yako Ujumbe Binafsi Inakuarifu wakati ujumbe binafsi unapowasili Zaps Zilizopokelewa @@ -357,20 +280,9 @@ kwa %1$s Taarifa: - jiunge kwenye mazungumzo - Kitambulisho cha Mtumiaji au Kikundi - npub, nevent au hex - Unda - jiunge Leo Onyo la Yaliyomo Chapisho hili lina yaliyomo nyeti ambayo baadhi ya watu wanaweza kuona kama ya kuchukiza au kusumbua - Daima ficha yaliyomo nyeti - Daima onyesha yaliyomo nyeti - Daima onyesha onyo za yaliyomo - Inapendekeza: - Chuja barua taka kutoka kwa wageni - Onya wakati machapisho yana ripoti kutoka kwa wafuatavyo wako Alama Mpya ya Majibu Hakuna aina za majibu zilizochaguliwa. Bonyeza kwa muda mrefu kubadilisha Mzushi wa Zaps @@ -379,32 +291,21 @@ Mzushi wa Zaps kwa %1$s. Sats %2$s hadi kufikia lengo Soma kutoka kwa Relay Andika kwa Relay - Kuna kosa lililotokea jaribu kupata habari za Relay kutoka kwa %1$s Mmiliki Toleo Programu Wasiliana NIPs Zinazoungwa mkono - Ada za Kuingia URL ya Malipo Vikwazo Nchi Lugha - Alama Sera ya Kutuma - Urefu wa Ujumbe - Michango - Vichujio - Urefu wa Kitambulisho cha Michango Awamu ya Chini Vichwa vya Tukio vya Juu - Urefu wa Yaliyomo PoW ya Chini - Uthibitishaji - Malipo Kukomboa Hakuna Anwani ya Lightning Imewekwa - Kitufe kimekopwa kwenye ubao wa kunakili Moja kwa Moja Nje ya Mtandao Imemalizika @@ -426,7 +327,6 @@ (translated) row titles. Marked translatable="false" so protocol terms (blossom, nsec, negentropy, …) stay searchable in every locale and aren't sent to translators. --> Daima - Wi-Fi tu Kamwe Mfumo Mwanga @@ -437,7 +337,6 @@ Onesha Picha Cheza Video Onesha Hakikisho za URL - Soma Picha Wahasibu Walemavu. Bonyeza kuwasha sauti Sauti imewashwa. Bonyeza kulegeza @@ -445,17 +344,10 @@ Anwani ya Nostr ilithibitishwa Anwani ya Nostr ilishindwa kuthibitishwa Kuthibitisha Anwani ya Nostr - Chagua/Chagua Vingine Vyote Chaguo-msingi - Chagua kiotomatiki kuendelea - Tuma Zaps kwa: - Wateja wanaosaidia watatuma Zaps kwa LNAddress au Wasifu wa Mtumiaji hapa chini badala ya yako Tumia Mahali kama Inaongeza Geohash ya eneo lako kwenye chapisho. Umma utajua kuwa uko ndani ya kilometa 5 (maili 3) ya eneo la sasa Inaongeza onyo la yaliyomo nyeti kabla ya kuonyesha yaliyomo yako. Hii ni nzuri kwa yaliyomo yoyote ya NSFW au yaliyomo ambayo baadhi ya watu wanaweza kuona kama ya kuchukiza au kusumbua - Kipengee Kipya - Kuwezesha hali hii kunahitaji Amethyst kutuma ujumbe wa NIP-17 (Ufungaji wa Zawadi, Ujumbe wa Moja kwa Moja Uliosajiliwa, na Ujumbe wa Kikundi). NIP-17 ni mpya na wateja wengi bado hawajaijumuisha. Hakikisha mpokeaji anatumia mteja unaokubaliana. - Tumia Umma Binafsi Kwa @@ -470,26 +362,14 @@ Lisha picha na GIFs kiotomatiki Cheza video na GIFs kiotomatiki Onyesha hakikisho za URL kiotomatiki - Lini kusoma picha Nakili URL kwa ubao wa kunakili Nakili Kitambulisho cha Andiko kwa ubao wa kunakili Imetengenezwa saa - Miongozo Sasisha hali yako - Kosa katika uchambuzi wa ujumbe wa kosa Kura zina uzito kulingana na kiasi cha zap. Unaweza kuweka kiasi cha chini ili kuepuka wahasibu na kiasi cha juu ili kuepuka wahasibu wakubwa kuchukua kura ya maoni. Tumia kiasi sawa katika sehemu zote mbili ili kuhakikisha kila kura inathaminiwa kwa kiasi sawa. Acha tupu ili kukubali kiasi chochote. Haiwezekani kutuma zap Tuma ujumbe kwa mtumiaji Sawa - Imeshindwa kufikia %1$s: %2$s - Imeshindwa kufikia %1$s: %2$s - Imeshindwa kuchanganua matokeo kutoka %1$s: %2$s - %1$s imeshindwa kwa kutumia msimbo %2$s - Inatumika kwa: - Nyumbani - Soga - Ulimwenguni - Tafuta @@ -502,4 +382,5 @@ + diff --git a/amethyst/src/main/res/values-ta-rIN/strings.xml b/amethyst/src/main/res/values-ta-rIN/strings.xml index 3858017cc3..66391eddf2 100644 --- a/amethyst/src/main/res/values-ta-rIN/strings.xml +++ b/amethyst/src/main/res/values-ta-rIN/strings.xml @@ -14,8 +14,6 @@ எரிதம் (தேவையற்றவை) ஆள்மாறாட்டம் சட்டவிரோத நடத்தை - தெரியாதவை - ரிலே ஐகான் எழுதியவர் தெரியவில்லை உரையை நகலெடுக்கவும் எழுதியவர் IDஐ நகலெடுக்கவும் @@ -25,7 +23,6 @@ எரிதம் / மோசடி என்று புகாரளிக்கவும் ஆள்மாறாட்டத்தைப் புகாரளிக்கவும் - வெளிப்படையான உள்ளடக்கத்தைப் புகாரளிக்கவும் சட்டப்புறம்பான நடத்தையைப் புகாரளிக்கவும் பதிலளிக்க ஒரு தனிப்பட்ட சாவியுடன் உள்நுழைக குறிப்புகளை உயர்த்த ஒரு தனிப்பட்ட சாவியுடன் உள்நுழைக @@ -33,7 +30,6 @@ ஜாப் தொகை அமைப்பு இல்லை. மாற்ற நீண்ட நேரம் அழுத்தவும் ஜாப்களை அனுப்ப ஒரு தனிப்பட்ட சாவியுடன் உள்நுழைக ஜாப்கள் - பார்வை எண்ணிக்கை உயர்த்து உயர்த்தப்பட்டது மேற்கோள் காட்டு @@ -41,7 +37,6 @@ சேர் "பதில் பெறுநர் " "மற்றும்" - "அலை வரிசையில் " தன்விவர பேனர் " பின்பற்றப்படுவோர்" " பின்பற்றுவோர்" @@ -56,9 +51,7 @@ மிக்க நன்றி! தொகை (ஸாட்களில்) ஸாட்கள் அனுப்பவும் - "%1$s க்கான முன்னோட்டத்தை புரிந்து கொள்வதில் பிழை: %2$s" " %1$s க்கான முன்னோட்ட அட்டைப் படம்" - புதிய அலைவரிசை அலைவரிசைப் பெயர் எனது அருமையான குழு படச்சுட்டி @@ -69,35 +62,20 @@ சேமி உருவாக்கு ரத்து - படத்தை பதிவேற்ற இயலவில்லை - ரிலே முகவரி - குறிப்புகள் - துணுக்குகள் பிழைகள் - முகப்பு ஊட்டம் - தனிசெய்தி ஊட்டம் - பொது செய்தி ஊட்டம் - முழுதளாவிய ஊட்டம் - தேடுதல் ஊட்டம் ஒரு ரிலேவை சேர் காட்சிப் பெயர் எனது காட்சிப் பெயர் பயனர் பெயர் - எனது பயனர் பெயர் என்னைப் பற்றி தன்விவரப் படச் சுட்டி பேனர் சுட்டி வலைதள முகவரி - LN முகவரி - LN URL (காலாவதியானது) படம் காட்சியகத்தில் சேமிக்கப்பட்டது படத்தைச் சேமிக்க இயலவில்லை படத்தைப் பதிவேற்று - பதிவேற்றுகிறது…. பயனர் ஸாட்கள் பெறுவதற்கு லைட்னிங் முகவரி அமைக்கவில்லை "இங்கு பதிலளிக்கவும்.. " - குறிப்பு ID ஐ கிளிப்போர்டில் பிரதி எடுக்கும் - அலைவரிசை ID ஐ கிளிப்போர்டில் பிரதி எடு அலைவரிசை பற்றிய தகவல்களை மாற்றும் சேர் தெரிந்த @@ -107,16 +85,12 @@ உரையாடல்கள் குறிப்புகள் பதில்கள் - "பின்தொடரப்படுவோர்" "புகார்கள்" மேலும் " ரிலேகள்" இணையதளம் லைட்னிங் முகவரி Nsec IDயை (உங்கள் கடவுச்சொல்) காப்புப்பிரதிக்காக கிளிப்போர்டுக்கு நகலெடுக்கிறது - கிளிப்போர்டுக்கு ரகசிய சாவியை நகலெடுக்கவும் - பகிர்வுக்காக கிளிப்போர்டுக்கு பொதுசாவியை நகலெடுக்கிறது - கிளிப்போர்டுக்கு பொதுசாவியை (NPUB) நகலெடுக்கவும் நேரடிச் செய்தியை அனுப்பு பயனரின் தகவலை திருத்துகிறது பின்தொடர் @@ -136,7 +110,6 @@ விதிமுறைகளை ஏற்பது கட்டாயம் சாவி தேவை உள்நுழைக - புதிய சாவியை உருவாக்குக ஊட்டம் ஏற்றப்படுகிறது @@ -144,12 +117,6 @@ மறுமுயற்சி செய் ஊட்டம் காலியாக உள்ளது. புதுப்பி - உருவாக்கப்பட்டது - விளக்கம்: - மற்றும் படம் - மாற்றப்பட்ட அரட்டை பெயர் - விளக்கம் - மற்றும் படம் வெளியேறு பின்தொடர்வதை நிறுத்து அலைவரிசை உருவாக்கப்பட்டது @@ -168,7 +135,6 @@ அவதூறு / வெறுப்புப் பேச்சு வெறுப்புப் பேச்சைப் புகாரளிக்கவும் பிறந்தமேனி / ஆபாசத்தைப் புகாரளிக்கவும் - பிற தெரிந்தவற்றைப் படித்ததாகக் குறி புதியனவற்றைப் படித்ததாகக் குறி அனைத்தையும் படித்ததாகக் குறி @@ -176,23 +142,18 @@ ரகசிய சாவி (nsec) கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது எனது ரகசிய சாவியை நகலெடுக்கவும் அங்கீகரிப்பு தோல்வியுற்றது - பிழை - " %1$s ஆல் உருவாக்கப்பட்டது" " %1$s க்கான பேட்ஜ் விருது படம்" நீங்கள் ஒரு புதிய பேட்ஜ் விருதைப் பெற்றீர்கள் பேட்ஜ் விருது வழங்கப்பட்டது. பெறுநர்: குறிப்பு கிளிப்போர்டுக்கு நகலெடுக்கப் பட்டது கிளிப்போர்டுக்கு எழுத்தாளரின் @npub நகலெடுக்கப் பட்டது கிளிப்போர்டுக்கு குறிப்பு ஐடி (@note1) நகலெடுக்கப் பட்டது - உரையைத் தேர்ந்தெடுக்கவும் "தனிப்பட்ட செய்தியை மறைக்குறியாக்க இயலவில்லை \n \n %1$s மற்றும் %2$s க்கு இடையே தனிப்பட்ட/ குறியாக்கப்பட்ட உரையாடலில் நீங்கள் மேற்கோள் காட்டப்பட்டீர்கள்." புதிய கணக்கைச் சேர்க்கவும் கணக்குகள் கணக்கைத் தேர்ந்தெடுக்கவும் புதிய கணக்கைச் சேர்க்கவும் செயலில் உள்ள கணக்கு - தனிப்பட்ட சாவி உள்ளது - படிக்க மட்டும், தனிப்பட்ட சாவி இல்லை பின் தேர்ந்தெடுக்கவும் உலாவி இணைப்பைப் பகிரவும் @@ -209,7 +170,6 @@ அழி தடைசெய் புகார் - அழி மீண்டும் காட்டாதே எரிதம் அல்லது மோசடிகள் அவதூறு அல்லது வெறுக்கத்தக்க நடத்தை @@ -234,26 +194,12 @@ பொது புக்மார்க்குகளில் சேர்க்கவும் தனிப்பட்ட புக்மார்க்குகளிலிருந்து அகற்று பொது புக்மார்க்குகளிலிருந்து அகற்று - பணப்பை இணைப்பு சேவை - பயன்பாட்டை விட்டு வெளியேறாமல் ஜாப்களை செலுத்த ஒரு நாஸ்டர் ரகசியத்தை அங்கீகரிக்கிறது. ரகசியத்தை பாதுகாப்பாக வைத்து, முடிந்தால் தனியார் ரிலேவைப் பயன்படுத்துங்கள் - பணப்பை இணைப்பு பொது சாவி - பணப்பை இணைப்பு ரிலே - பணப்பை இணைப்பு ரகசியம் - மறைமுகச் சாவியைக் காட்டு - nsec / hex தனிப்பட்ட சாவி உறுதிமொழி தொகை (ஸாட்களில்) - தேவையான புலங்கள்: - ஜாப் பெறுநர்கள் - முதன்மை வாக்கெடுப்பு விளக்கம்… விருப்பம் %s (வாக்குத்) தெரிவின் விளக்கம் - விருப்ப புலங்கள்: குறைந்தளவு ஜாப் அதிகளவு ஜாப் ஒருமித்த கருத்து - நிறைவுறும் நேரம் - நாட்களில் - ஜாப் தொகை இந்த வகை வாக்கெடுப்பில் ஒரு பயனருக்கு ஒரு வாக்கு மட்டுமே அனுமதிக்கப்படுகிறது "நிகழ்வு %1$s ஐத் தேடி" ஒரு பொது செய்தியைச் சேர்க்கவும் @@ -281,29 +227,12 @@ அல்லாத-ஜாப் நாஸ்டரில் எந்த சுவடும் இன்றி, லைட்நிங்கில் மட்டும் உள்ளது கோப்புச் சேவையகம் - LN முகவரி அல்லது @பயனர் - உங்கள் ரிலே (NIP-95) - ஃபைல்ஸ் உங்கள் ரிலேக்களில் ஹோஸ்ட் செய்யப்படும். புதிய NIP: ரிலேயில் இச்சேவை உள்ளதா என சரிபார்க்கவும் - Tor/Orbot இணைப்பு - Orbot அமைப்பு மூலம் இணைக்கவும் - Tor/Orbot இணைப்பை துண்டிக்கவா? - உங்கள் டேட்டா உடனே வழக்கமான நெட்வொர்க்கிற்கு மாற்றப்படும் ஆம் இல்லை - பின்பற்றப்படுவோர் பட்டியல் எல்லா பின்பற்றப் படுவோர் முழுதளாவிய - ## Tor மூலம் Orbot உடன் இணைக்க - \n\n1. [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) இன்ஸ்டால் செய்க - \n2. Orbot-ஐ தொடங்குங்கள் - \n3. Orbot-இல் Socks போர்ட்டை செக் செய்க. இயல்புநிலையில் அது 9050 - \n4. வேண்டுமானால் Orbot-இல் போர்ட்டை மாற்றுங்கள் - \n5. இந்த திரையில் Socks போர்டை கட்டமைக்க - \n6. ஆக்டிவேட் பொத்தானை அழுத்தி Orbot-ஐ proxy-ஆக பயன்படுத்துங்கள் Orbot Socks போர்ட் செல்லாத போர்ட் நம்பர் - Orbot-ஐ பயன்படுத்துங்கள் - Orbot இணைப்பது துண்டிக்க தனிப்பட்ட செய்திகள் தனிப்பட்ட செய்தி வருகையில் தெரிவிக்கவும் ஜாப் பெறப்பட்டது @@ -313,20 +242,9 @@ %1$s -க்கு தெரிவிக்க - உரையாடலில் இணைக - பயனர் அல்லது குழுவின் ID - npub, nevent அல்லது hex - உருவாக்குக - இணைக இன்று உள்ளடக்க எச்சரிக்கை இந்த குறிப்பின் உள்ளடக்கம் சிலருக்கு அவமதிப்பாகவோ அருவெறுப்பாகவோ இருக்கலாம் - எப்போதும் உணர்ச்சிபூர்வமான உள்ளடக்கத்தை மறைக்க - எப்போதும் உணர்ச்சிபூர்வமான உள்ளடக்கத்தை காண்பிக்க - எப்போதும் உள்ளடக்க எச்சரிக்கையை காண்பிக்க - பரிந்துரைகள் - தெரியாதவர்களிடமிருந்து ஸ்பேம்-மை வடிகட்டுக - குறிப்புகளில் நீங்கள் பின்பற்றுபவரின் புகார் இருந்தால் எச்சரிக்க புதிய ரியாக்ஷன் குறி எந்த ரியாக்ஷனும் தேர்ந்தெடுக்கவில்லை. மாற்ற நீண்ட நேரம் அழுத்தவும் ஜாப்-திரட்டுதல் @@ -340,23 +258,14 @@ மென்பொருள் தொடர்புக்கு ஆதரிக்கப்படும் NIPகள் - நுழைவுக் கட்டணம் கட்டண URL வரம்புகள் நாடுகள் மொழிகள் - சிட்டைகள் பதிவுக் கொள்கை - குறிப்பு நீளம் - சப்ஸ்க்ரிப்ஷன்கள் - வடிப்பான்கள் - சப்ஸ்க்ரிப்ஷன் ID நீளம் குறைந்தளவு முன்னீடு அதிகளவு நிகழ்வு சிட்டைகள் - உள்ளடக்க நீளம் குறைந்தளவு PoW - சான்றளிப்பு - கட்டணம் Cashu வில்லை மீட்க நேரலை @@ -388,4 +297,5 @@ + diff --git a/amethyst/src/main/res/values-ta/strings.xml b/amethyst/src/main/res/values-ta/strings.xml index 5471010d5e..aed360a666 100644 --- a/amethyst/src/main/res/values-ta/strings.xml +++ b/amethyst/src/main/res/values-ta/strings.xml @@ -14,8 +14,6 @@ எரிதம் (தேவையற்றவை) ஆள்மாறாட்டம் சட்டவிரோத நடத்தை - தெரியாதவை - ரிலே ஐகான் எழுதியவர் தெரியவில்லை உரையை நகலெடுக்கவும் எழுதியவர் IDஐ நகலெடுக்கவும் @@ -25,7 +23,6 @@ எரிதம் / மோசடி என்று புகாரளிக்கவும் ஆள்மாறாட்டத்தைப் புகாரளிக்கவும் - வெளிப்படையான உள்ளடக்கத்தைப் புகாரளிக்கவும் சட்டப்புறம்பான நடத்தையைப் புகாரளிக்கவும் பதிலளிக்க ஒரு தனிப்பட்ட சாவியுடன் உள்நுழைக குறிப்புகளை உயர்த்த ஒரு தனிப்பட்ட சாவியுடன் உள்நுழைக @@ -33,7 +30,6 @@ ஜாப் தொகை அமைப்பு இல்லை. மாற்ற நீண்ட நேரம் அழுத்தவும் ஜாப்களை அனுப்ப ஒரு தனிப்பட்ட சாவியுடன் உள்நுழைக ஜாப்கள் - பார்வை எண்ணிக்கை உயர்த்து உயர்த்தப்பட்டது மேற்கோள் காட்டு @@ -41,7 +37,6 @@ சேர் "பதில் பெறுநர் " "மற்றும்" - "அலை வரிசையில் " தன்விவர பேனர் " பின்பற்றப்படுவோர்" " பின்பற்றுவோர்" @@ -56,9 +51,7 @@ மிக்க நன்றி! தொகை (ஸாட்களில்) ஸாட்கள் அனுப்பவும் - "%1$s க்கான முன்னோட்டத்தை புரிந்து கொள்வதில் பிழை: %2$s" " %1$s க்கான முன்னோட்ட அட்டைப் படம்" - புதிய அலைவரிசை அலைவரிசைப் பெயர் எனது அருமையான குழு படச்சுட்டி @@ -69,35 +62,20 @@ சேமி உருவாக்கு ரத்து - படத்தை பதிவேற்ற இயலவில்லை - ரிலே முகவரி - குறிப்புகள் - துணுக்குகள் பிழைகள் - முகப்பு ஊட்டம் - தனிசெய்தி ஊட்டம் - பொது செய்தி ஊட்டம் - முழுதளாவிய ஊட்டம் - தேடுதல் ஊட்டம் ஒரு ரிலேவை சேர் காட்சிப் பெயர் எனது காட்சிப் பெயர் பயனர் பெயர் - எனது பயனர் பெயர் என்னைப் பற்றி தன்விவரப் படச் சுட்டி பேனர் சுட்டி வலைதள முகவரி - LN முகவரி - LN URL (காலாவதியானது) படம் காட்சியகத்தில் சேமிக்கப்பட்டது படத்தைச் சேமிக்க இயலவில்லை படத்தைப் பதிவேற்று - பதிவேற்றுகிறது…. பயனர் ஸாட்கள் பெறுவதற்கு லைட்னிங் முகவரி அமைக்கவில்லை "இங்கு பதிலளிக்கவும்.. " - குறிப்பு ID ஐ கிளிப்போர்டில் பிரதி எடுக்கும் - அலைவரிசை ID ஐ கிளிப்போர்டில் பிரதி எடு அலைவரிசை பற்றிய தகவல்களை மாற்றும் சேர் தெரிந்த @@ -107,16 +85,12 @@ உரையாடல்கள் குறிப்புகள் பதில்கள் - "பின்தொடரப்படுவோர்" "புகார்கள்" மேலும் " ரிலேகள்" இணையதளம் லைட்னிங் முகவரி Nsec IDயை (உங்கள் கடவுச்சொல்) காப்புப்பிரதிக்காக கிளிப்போர்டுக்கு நகலெடுக்கிறது - கிளிப்போர்டுக்கு ரகசிய சாவியை நகலெடுக்கவும் - பகிர்வுக்காக கிளிப்போர்டுக்கு பொதுசாவியை நகலெடுக்கிறது - கிளிப்போர்டுக்கு பொதுசாவியை (NPUB) நகலெடுக்கவும் நேரடிச் செய்தியை அனுப்பு பயனரின் தகவலை திருத்துகிறது பின்தொடர் @@ -136,18 +110,11 @@ விதிமுறைகளை ஏற்பது கட்டாயம் சாவி தேவை உள்நுழைக - புதிய சாவியை உருவாக்குக ஊட்டம் ஏற்றப்படுகிறது "பதில்களை ஏற்றுவதில் பிழை: " மறுமுயற்சி செய் ஊட்டம் காலியாக உள்ளது. புதுப்பி - உருவாக்கப்பட்டது - விளக்கம்: - மற்றும் படம் - மாற்றப்பட்ட அரட்டை பெயர் - விளக்கம் - மற்றும் படம் வெளியேறு பின்தொடர்வதை நிறுத்து அலைவரிசை உருவாக்கப்பட்டது @@ -166,7 +133,6 @@ அவதூறு / வெறுப்புப் பேச்சு வெறுப்புப் பேச்சைப் புகாரளிக்கவும் பிறந்தமேனி / ஆபாசத்தைப் புகாரளிக்கவும் - பிற தெரிந்தவற்றைப் படித்ததாகக் குறி புதியனவற்றைப் படித்ததாகக் குறி அனைத்தையும் படித்ததாகக் குறி @@ -174,23 +140,18 @@ ரகசிய சாவி (nsec) கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது எனது ரகசிய சாவியை நகலெடுக்கவும் அங்கீகரிப்பு தோல்வியுற்றது - பிழை - " %1$s ஆல் உருவாக்கப்பட்டது" " %1$s க்கான பேட்ஜ் விருது படம்" நீங்கள் ஒரு புதிய பேட்ஜ் விருதைப் பெற்றீர்கள் பேட்ஜ் விருது வழங்கப்பட்டது. பெறுநர்: குறிப்பு கிளிப்போர்டுக்கு நகலெடுக்கப் பட்டது கிளிப்போர்டுக்கு எழுத்தாளரின் @npub நகலெடுக்கப் பட்டது கிளிப்போர்டுக்கு குறிப்பு ஐடி (@note1) நகலெடுக்கப் பட்டது - உரையைத் தேர்ந்தெடுக்கவும் "தனிப்பட்ட செய்தியை மறைக்குறியாக்க இயலவில்லை \n \n %1$s மற்றும் %2$s க்கு இடையே தனிப்பட்ட/ குறியாக்கப்பட்ட உரையாடலில் நீங்கள் மேற்கோள் காட்டப்பட்டீர்கள்." புதிய கணக்கைச் சேர்க்கவும் கணக்குகள் கணக்கைத் தேர்ந்தெடுக்கவும் புதிய கணக்கைச் சேர்க்கவும் செயலில் உள்ள கணக்கு - தனிப்பட்ட சாவி உள்ளது - படிக்க மட்டும், தனிப்பட்ட சாவி இல்லை பின் தேர்ந்தெடுக்கவும் உலாவி இணைப்பைப் பகிரவும் @@ -207,7 +168,6 @@ அழி தடைசெய் புகார் - அழி மீண்டும் காட்டாதே எரிதம் அல்லது மோசடிகள் அவதூறு அல்லது வெறுக்கத்தக்க நடத்தை @@ -232,26 +192,12 @@ பொது புக்மார்க்குகளில் சேர்க்கவும் தனிப்பட்ட புக்மார்க்குகளிலிருந்து அகற்று பொது புக்மார்க்குகளிலிருந்து அகற்று - பணப்பை இணைப்பு சேவை - பயன்பாட்டை விட்டு வெளியேறாமல் ஜாப்களை செலுத்த ஒரு நாஸ்டர் ரகசியத்தை அங்கீகரிக்கிறது. ரகசியத்தை பாதுகாப்பாக வைத்து, முடிந்தால் தனியார் ரிலேவைப் பயன்படுத்துங்கள் - பணப்பை இணைப்பு பொது சாவி - பணப்பை இணைப்பு ரிலே - பணப்பை இணைப்பு ரகசியம் - மறைமுகச் சாவியைக் காட்டு - nsec / hex தனிப்பட்ட சாவி உறுதிமொழி தொகை (ஸாட்களில்) - தேவையான புலங்கள்: - ஜாப் பெறுநர்கள் - முதன்மை வாக்கெடுப்பு விளக்கம்… விருப்பம் %s (வாக்குத்) தெரிவின் விளக்கம் - விருப்ப புலங்கள்: குறைந்தளவு ஜாப் அதிகளவு ஜாப் ஒருமித்த கருத்து - நிறைவுறும் நேரம் - நாட்களில் - ஜாப் தொகை இந்த வகை வாக்கெடுப்பில் ஒரு பயனருக்கு ஒரு வாக்கு மட்டுமே அனுமதிக்கப்படுகிறது "நிகழ்வு %1$s ஐத் தேடி" ஒரு பொது செய்தியைச் சேர்க்கவும் @@ -279,29 +225,12 @@ அல்லாத-ஜாப் நாஸ்டரில் எந்த சுவடும் இன்றி, லைட்நிங்கில் மட்டும் உள்ளது கோப்புச் சேவையகம் - LN முகவரி அல்லது @பயனர் - உங்கள் ரிலே (NIP-95) - ஃபைல்ஸ் உங்கள் ரிலேக்களில் ஹோஸ்ட் செய்யப்படும். புதிய NIP: ரிலேயில் இச்சேவை உள்ளதா என சரிபார்க்கவும் - Tor/Orbot இணைப்பு - Orbot அமைப்பு மூலம் இணைக்கவும் - Tor/Orbot இணைப்பை துண்டிக்கவா? - உங்கள் டேட்டா உடனே வழக்கமான நெட்வொர்க்கிற்கு மாற்றப்படும் ஆம் இல்லை - பின்பற்றப்படுவோர் பட்டியல் எல்லா பின்பற்றப் படுவோர் முழுதளாவிய - ## Tor மூலம் Orbot உடன் இணைக்க - \n\n1. [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) இன்ஸ்டால் செய்க - \n2. Orbot-ஐ தொடங்குங்கள் - \n3. Orbot-இல் Socks போர்ட்டை செக் செய்க. இயல்புநிலையில் அது 9050 - \n4. வேண்டுமானால் Orbot-இல் போர்ட்டை மாற்றுங்கள் - \n5. இந்த திரையில் Socks போர்டை கட்டமைக்க - \n6. ஆக்டிவேட் பொத்தானை அழுத்தி Orbot-ஐ proxy-ஆக பயன்படுத்துங்கள் Orbot Socks போர்ட் செல்லாத போர்ட் நம்பர் - Orbot-ஐ பயன்படுத்துங்கள் - Orbot இணைப்பது துண்டிக்க தனிப்பட்ட செய்திகள் தனிப்பட்ட செய்தி வருகையில் தெரிவிக்கவும் ஜாப் பெறப்பட்டது @@ -310,20 +239,9 @@ %1$s -இடமிருந்து %1$s -க்கு தெரிவிக்க - உரையாடலில் இணைக - பயனர் அல்லது குழுவின் ID - npub, nevent அல்லது hex - உருவாக்குக - இணைக இன்று உள்ளடக்க எச்சரிக்கை இந்த குறிப்பின் உள்ளடக்கம் சிலருக்கு அவமதிப்பாகவோ அருவெறுப்பாகவோ இருக்கலாம் - எப்போதும் உணர்ச்சிபூர்வமான உள்ளடக்கத்தை மறைக்க - எப்போதும் உணர்ச்சிபூர்வமான உள்ளடக்கத்தை காண்பிக்க - எப்போதும் உள்ளடக்க எச்சரிக்கையை காண்பிக்க - பரிந்துரைகள் - தெரியாதவர்களிடமிருந்து ஸ்பேம்-மை வடிகட்டுக - குறிப்புகளில் நீங்கள் பின்பற்றுபவரின் புகார் இருந்தால் எச்சரிக்க புதிய ரியாக்ஷன் குறி எந்த ரியாக்ஷனும் தேர்ந்தெடுக்கவில்லை. மாற்ற நீண்ட நேரம் அழுத்தவும் ஜாப்-திரட்டுதல் @@ -337,23 +255,14 @@ மென்பொருள் தொடர்புக்கு ஆதரிக்கப்படும் NIPகள் - நுழைவுக் கட்டணம் கட்டண URL வரம்புகள் நாடுகள் மொழிகள் - சிட்டைகள் பதிவுக் கொள்கை - குறிப்பு நீளம் - சப்ஸ்க்ரிப்ஷன்கள் - வடிப்பான்கள் - சப்ஸ்க்ரிப்ஷன் ID நீளம் குறைந்தளவு முன்னீடு அதிகளவு நிகழ்வு சிட்டைகள் - உள்ளடக்க நீளம் குறைந்தளவு PoW - சான்றளிப்பு - கட்டணம் Cashu வில்லை மீட்க நேரலை diff --git a/amethyst/src/main/res/values-th-rTH/strings.xml b/amethyst/src/main/res/values-th-rTH/strings.xml index 72d67481c0..f2d05a022f 100644 --- a/amethyst/src/main/res/values-th-rTH/strings.xml +++ b/amethyst/src/main/res/values-th-rTH/strings.xml @@ -20,8 +20,6 @@ เลียนแบบ พฤติกรรมที่ผิดกฎหมาย อื่นๆ - ไม่ทราบ - รีเลย์ไอคอน ไม่ทราบผู้เขียน คัดลอกข้อความ คัดลอก ID ผู้เขียน @@ -35,7 +33,6 @@ รายงาน: สแปม / หลอกลวง รายงาน: การเลียนแบบ - รายงาน: เนื้อหารุนแรง รายงาน: พฤติกรรมที่ผิดกฎหมาย รายงานมัลแวร์ มัลแวร์ @@ -49,7 +46,6 @@ เข้าสู่ระบบด้วย private key เพื่อเพิ่มการซ่อนข้อความ เข้าสู่ระบบด้วย private key เพื่อแก้ไขการซ่อนข้อความ Zaps - ยอดเข้าชม แชร์ แชร์ แก้ไขแล้ว @@ -62,9 +58,7 @@ เพิ่ม "ตอบกลับถึง " " และ " - " ในช่อง " หน้าปกโปรไฟล์ - การชำรพเงินเสร็จสมบูรณ์ เกิดข้อผิดพลาดในการวิเคราะห์ข้อความแสดงข้อผิดพลาด " กำลังติดตาม" " ผู้ติดตาม" @@ -79,9 +73,7 @@ ขอบคุณมาก! จำนวนในหน่วย sat ส่ง Sats - "ข้อผิดพลาดในการวิเคราะห์ตัวอย่างสําหรับ %1$s : %2$s" "รูปตัวอย่างสำหรับ %1$s" - Channel ใหม่ ชื่อ Channel กลุ่มที่ยอดเยี่ยมของฉัน! ที่อยู่ URL รูปภาพ @@ -92,39 +84,22 @@ บันทึก สร้าง ยกเลิก - ไม่สามารถโหลดรูปภาพได้ - ที่อยู่รีเลย์ - โพสต์ - ไบต์ ข้อผิดพลาด - เกิดข้อผิดพลาดในการเชื่อมต่อ - ฟีดเริ่มต้น - ฟีดข้อความส่วนตัว - ฟีดข้อความ - ฟีดโลก - ฟีดค้นหา เพิ่มรีเลย์ ชื่อที่แสดง ชื่อที่แสดงของฉัน ปลาอานนท์ สุดหล่อ ยินดีต้อนรับนะอานนท์! ชื่อผู้ใช้ - ชื่อผู้ใช้ของฉัน เกี่ยวกับฉัน ที่อยู่ URL รูปโปรไฟล์ ที่อยู่ URL รูปหน้าปก ที่อยู่ URL เว็บไซต์ - Lightning Address - LN URL (หมดอายุ) - บันทึกรูปภาพ บันทึกรูปภาพลงแกลเลอรี เกิดข้อผิดพลาดในการบันทึกรูปภาพ อัพโหลดรูปภาพ - กำลังอัพโหลด ผู้ใช้นี้ไม่ได้ตั้งค่า lightning address เพื่อรับ sats "ตอบกลับที่นี่.. " - คัดลอกโน้ต ID ลงคลิปบอร์ดเพื่อแชร์ไปยัง Nostr - คัดลอก Channel ID (โน้ต) ลงคลิปบอร์ด แก้ไข Channel Metadata เข้าร่วม รู้ @@ -135,16 +110,12 @@ โน้ต ตอบกลับ คลังภาพ - "ติดตาม" "รายงาน" ตัวเลือกเพิ่มเติม " รีเลย์" เว็บไซต์ ไม่ได้ตั้งค่า Lightning Address คัดลอก Nsec ID (รหัสผ่านของคุณ) ลงคลิปบอร์ดเพื่อสำรองข้อมูล - คัดลอก Secret Key ลงคลิปบอร์ด - คัดลอก public key ลงคลิปบอร์ดเพื่อแชร์ - คัดลอก Public Key (NPub) ลงคลิปบอร์ด ส่งข้อความส่วนตัว แก้ไข the User\'s Metadata ติดตาม @@ -173,8 +144,6 @@ ใช้ชื่อเล่นว่าอะไรดีเอ่ย? ยังไม่มีบัญชี Nostr หรือ? มีบัญชี Nostr อยู่แล้ว? - สร้างบัญชีผู้ใช้ใหม่ - สร้าง key ใหม่ กำลังดาวน์โหลดฟีด กำลังโหลดข้อมูลบัญชี @@ -183,12 +152,6 @@ ลองอีกครั้ง ฟีดนี้ว่างเปล่า รีเฟรช - สร้าง - พร้อมคําอธิบายของ - และ รูปภาพ - เปลี่ยนชื่อ chat เป็น - คําอธิบายของ - และ รูปภาพของ ออก เลิกติดตาม สร้าง Channel @@ -212,7 +175,6 @@ คําหยาบคาย / คําพูดที่แสดงความเกลียดชัง รายงาน: คําพูดที่แสดงความเกลียดชัง รายงาน: ภาพเปลือย/สื่อลามก - อื่น ๆ ทำเครื่องหมายอ่านแล้วในแชทที่รู้จักทั้งหมด ทำเครื่องหมายว่าอ่านแล้วทั้งหมดสำหรับข้อความใหม่ ทพเครื่องหมายว่าอ่านแล้วทั้งหมด @@ -232,23 +194,18 @@ เกิดข้อผิดพลาดในการตรวจสอบ เกิดข้อผิดพลาดจากการยืนยันตนด้วยชีวภาพ เกิดข้อผิดพลาดจากการยืนยันตนด้วยชีวภาพ: Error: %1$s - ข้อผิดพลาด - "สร้างโดย %1$s" "ภาพเหรียญตราสําหรับ %1$s" คุณได้รับเหรียญตราใหม่ เหรียญตราถูกมอบให้กับ คัดลอกข่้อความในโน้ตลงคลิปบอร์ด คัดลอก @npub ของผู้เขียนลงคลิปบอร์ด คัดลอกโน้ต ID (@note1)ลงคลิปบอร์ด - เลือกข้อความ "<ไม่สามารถถอดรหัสข้อความส่วนตัวได้>\n\nคุณถูกอ้างถึงในการสนทนาส่วนตัว/เข้ารหัสระหว่าง %1$s และ %2$s." เพิ่มบัญชีใหม่ บัญชี เลือกบัญชี เพิ่มบัญชีใหม่ บัญชีที่ใช้งานอยู่ - มี private key - อ่านเท่านั้น, ไม่มี private key ย้อนกลับ เลือก แชร์ Browser Link @@ -266,14 +223,12 @@ ลบ บล๊อก รายงาน - ลบ ไม่แสดงข้อความนี้อีก สแปม หรือ หลอกลวง คําหยาบคายหรือการแสดงความเกลียดชัง การแอบอ้างบุคคลอื่นที่เป็นอันตราย เนื้อหาภาพเปลือย พฤติกรรมที่ผิดกฎหมาย - มัลแวร์ การบล็อกผู้ใช้จะซ่อนเนื้อหาของพวกเขาในแอปของคุณ โน้ตของคุณยังคงดูได้แบบสาธารณะรวมถึงคนที่คุณบล็อกด้วย ผู้ใช้ที่ถูกบล็อกจะแสดงรายการบนหน้าจอตัวกรองความปลอดภัย รายงานการล่วงละเมิด @@ -293,30 +248,15 @@ เพิ่มไปยังบุ๊คมาร์คสาธรณะ ลบออกจากบุ๊คมาร์คส่วนตัว ลบออกจากบุ๊คมาร์คสาธรณะ - บริการเชื่อมต่อ wallet - อนุญาตให้ Nostr Secret จ่าย zaps โดยไม่ต้องออกจากแอป เพื่อรักษาความลับให้ปลอดภัยและใช้รีเลย์ส่วนตัวหากเป็นไปได้ - Wallet Connect Pubkey - บริการเชื่อมต่อ wallet - Wallet Connect Secret - แสดง secret key - nsec/ private key ในฐาน16 จำนวนเงินที่นำเข้าในหน่วย sat - สร้างโพลล์ - ส่วนที่จำเป็น: - ผู้รับ Zap - คำอธิบายโพลล์… ตัวเลือก %s คำอธิบายตัวเลือกในโพลล์ - ตำอธิบายเพิ่มเติม: Zap ขั้นต่ำ Zap สูงสุด ฉันทามติ (0–100)% - ปิดหลังจาก - วัน ไม่สามารถโหวต โพลปิดรับการลงคะแนนเพิ่มเติม - จำนวน Zap อนุญาตให้โหวตได้เพียงครั้งเดียวต่อผู้ใช้หนึ่งคนสำหรับการสำรวจประเภทนี้ "กำลังมองหา Event %1$s" เพิ่มในข้อความสาธรณะ @@ -345,35 +285,18 @@ แอบแซ่บ ไม่มีการบันทึกบน Nostr, มีแค่ในระบบ Lightning เซิร์ฟเวอร์เก็บข้อมูล - LnAddress หรือ @ชื่อผู้ใช้ Media Servers ตั้งค่า media server ที่คุณต้องการ - Built-in Media Servers รายการค่าเริ่มต้นของ Amethyst คุณสามารถเพิ่มทีละรายการหรือเพิ่มทั้งรายการก็ได้ ใช้รายการค่าเริ่มต้น เพิ่ม media server ลบ media server - รีเลย์ของคุณ (NIP-95) - ไฟล์อยู่บนรีเลย์ของคุณ New NIP: โปรดตรวจสอบว่ามีการรองรับหรือไม่ - ตั้งค่า Tor/Orbot - การตั้งค่าการเชื่อมต่อ Orbot ของคุณ - ตัดการเชื่อมต่อจาก Orbot/Tor ของคุณ? - ข้อมูลของคุณจะถูกถ่ายโอนในเครือข่ายปกติทันที ใช่ ไม่ - รายการผู้ติดตาม ติดตามทั้งหมด ทั่วโลก รายการผู้ถูกปิดกั้น Port เริ่มต้นคือ 9050 - ## เชื่อมต่อกัย Tor ด้วย Orbot - \n\n1. ติดตั้ง [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. เริ่มต้นใช้งาน Orbot - \n3. ใน Orbot, ตรวจสอบe Socks port. ค่าเริ่มต้นเป็น 9050 - \n4. หากจําเป็นให้เปลี่ยนพอร์ตใน Orbot - \n5. กําหนดค่า Socks port บนหน้าจอนี้ - \n6. กดปุ่มเปิดใช้งานเพื่อใช้ Orbot เป็น proxy - พอร์ต Orbot Socks รีเลย์สำหรีบข้อความส่วนตัว ปิด @@ -382,8 +305,6 @@ ซ่อน IP ของคุณจากทุกอย่าง ยกเว้นรูปภาพและวิดีโอ ซ่อน IP ของคุณจากทุกการเชื่อมต่อ เลข port ไม่ถูกต้องr - ใช้ Orbot - ตัดการเชื่อมต่อจาก Tor/Orbot ข้อความส่วนตัว แจ้งเตือนฉันเมื่อข้อความส่วนตัวมาถึง ได้รับ Zaps @@ -393,20 +314,9 @@ ถึง %1$s การแจ้งเตือน: - เข้าร่วมการสนทนา - ผู้ใช้ หรือ Group\'s ID - npub, nevent หรือ hex - สร้าง - เข้าร่วม วันนี้ คําเตือนเนื้อหา โพสต์นี้มีเนื้อหาที่ละเอียดอ่อนซึ่งบางคนอาจพบว่าไม่เหมาะสมหรือรบกวน - ซ่อนเนื้อหาที่ละเอียดอ่อนเสมอ - แสดงเนื้อหาที่ละเอียดอ่อนเสมอ - แสดงคำเตือนเนื้อหาเสมอ - แนะนำ: - กรองสแปมจากคนแปลกหน้า - เตือนเมื่อมีการรายงานโพสต์จากผู้ติดตามของคุณ สัญลักษณ์ Reaction ใหม่ ไม่มีการเลือกประเภทของ reaction กดค้างเพื่อเปลี่ยน ระดมทุน @@ -417,37 +327,24 @@ เขียนบน Relay จำนวนข้อมูลในหน่วยไบต์ที่ถูกส่งไปยังรีเลย์นี้ รวมถึงฟิลเตอร์และอีเว้นต่างๆ จำนวนข้อมูลในหน่วยไบต์ที่ถูกรับมาจากรีเลย์นี้ รวมถึงฟิลเตอร์และอีเว้นต่างๆ - เกิดข้อผิดพลาดในการรับข้อมูลจาก %1$s เจ้าของ เวอร์ชัน ซอฟต์แวร์ ติดต่อ รับรอง NIPs - ค่าใช้จ่ายสำหรับการใช้งาน url การชำระเงิน ข้อจำกัด ประเทศ ภาษา - แท็ก นโยบายการโพสต์ ประกาศจากทางรีเลย์ - ความยาวข้อความ - การสมัครสมาชิก - ฟิลเตอร์ - ความยาวของรหัสการสมัครสมาชิก คำนำหน้าขั้นต่ำ event tags สูงสุด - ความยาวของเนื้อหา PoW ขั้นต่ำ - ยืนยัน - การชำระเงิน โทเคน Cashu แลกคืน - ส่งไปยังกระเป๋า Lightning - เปิดด้วยกระเป๋า Cashu คัดลอก ไม่ได้ตั้งค่า Lightning Address - คัดลอกโทเคนลงคลิปบอร์ด ถ่ายทอดสด ออฟไลน์ สิ้นสุดแล้ว @@ -470,7 +367,6 @@ (translated) row titles. Marked translatable="false" so protocol terms (blossom, nsec, negentropy, …) stay searchable in every locale and aren't sent to translators. --> ตลอดเวลา - Wifi เท่านั้น Unmetered WiFi ไม่ต้องแสดง เสร็จสมบูรณ์ @@ -489,7 +385,6 @@ ซ่อนแถบเมนูขณะเลื่อนฟีด UI Mode เลือกรูปแบบการโพสต์ - โหลดรูปภาพ แสปม ปิดการมองเห็น คลิกเพื่อปลดออก เปิดการมองเห็นอยู่ คลิกเพื่อปิด @@ -497,17 +392,10 @@ Nostr address ได้รับการยืนยัน ไม่สามารถยืนยัน Nostr address ได้ ตรวจสอบ Nostr address - เลือก/ไม่เลือก ทั้งหมด ค่าเริ่มต้น - เลือกรีเลย์เพื่อดำเนินการต่อ - ส่งต่อ Zaps ถึง: - ไคลเอนต์ที่สนับสนุนจะส่งต่อ zaps ไปยัง LNAddress หรือโปรไฟล์ผู้ใช้ด้านล่างแทนที่จะเป็นของคุณ เปิดเผยตําแหน่งที่ตั้ง เพิ่ม Geohash ของตําแหน่งของคุณลงในโพสต์ สาธารณชนจะรู้ว่าคุณอยู่ภายใน 5 กม. (3 ไมล์) จากตําแหน่งปัจจุบัน เพิ่มคําเตือนเนื้อหาที่ละเอียดอ่อนก่อนแสดงเนื้อหาของคุณ สิ่งนี้เหมาะสําหรับเนื้อหา NSFW หรือเนื้อหาใด ๆ ที่บางคนอาจพบว่าไม่เหมาะสมหรือรบกวน - ฟีเจอร์ใหม่ - การเปิดใช้งานโหมดนี้ต้องใช้ Amethyst เพื่อส่งข้อความ NIP-17 (GiftWrapped, Sealed Direct และ Group Messages) NIP-17 เป็นของใหม่และไคลเอ็นต์ส่วนใหญ่ยังไม่ได้รองรับ ตรวจสอบให้แน่ใจว่าเครื่องรับใช้ไคลเอ็นต์ที่รองรับ - เปิดใช้งาน สาธรณะ สร้างกลุ่มสาธารณะ/ส่วนตัว ส่วนตัว @@ -524,7 +412,6 @@ โหลดรูปภาพและ GIFs โดยอัตโนมัติ เล่นวีดีโอและ GIFs โดยอัตโนมัติ แสดงจัวอย่าง URL - ควรโหลดรูปภาพเมื่อใด คัดลอก คัดลอก npub ไปยังคลิปบอร์ด แชร์ หรือเก็บไว้ @@ -532,44 +419,22 @@ คัดลอก โน้ต ID ลงคลิปบอร์ดd เพิ่มไปยังคลังภาพ สร้างโดย - กฏ เข้าสู่ระบบด้วย Amber คุณกำลังทำอะไรอยู่… - เกิดข้อผิดพลาดในการแสดงข้อความ โหวตถูกให้น้ำหนักโดยจำนวน Zaps. คุณสามารถตั้งจำนวนเงินต่ำสุด และจำนวนครั้งสูงสุดในการโหวตเพื่อหลีกเลี่ยงการแสปมผลโพล. ใช้จำนวนเงินที่เท่ากันในทุกหัวข้อเพื่อให้การโหวตเป็นไปอย่างเท่าเทียม ปล่อยช่องว่าง หากต้องการให้โหวตเท่าใดก็ได้ แย่จัง ส่ง Zaps ไม่ได้ ส่งข้อความ ตกลง - ไม่สามารถเชื่อมถึง %1$s: %2$s - การประกอบ URL NIP-11 สำหรับ %1$s ล้มเหลว: %2$s - การเชื่อมต่อกับ %1$s ล้มเหลว: %2$s - การแปลผลตอบกลับจาก %1$s ล้มเหลว: %2$s - รีเลย์ปฏิเสธคำขอ %1$s: %2$s - ไม่สามารถเชื่อมถึง %1$s: %2$s - เกิดข้อผิดพลาด %1$s: %2$s - %1$s เกิดข้อผิดพลาด %2$s - ใช้งานมา: - หน้าแรก - กล่องข้อความ - ช่องสนทนา - ทั่วโลก - ค้นหา แบ่ง และส่งต่อ Zaps แอพที่รองรับจะทำการแบ่ง Zaps ที่ได้ไปยังผู้ใช้ที่เพิ่มมาในรายการนี้ ค้นหา และเพิ่มผู้ใช้ ชื่อผู้ใช้ หรือชื่อที่แสดง ไม่พบการตั้งค่า Lightning ผู้ใช้ %1$s ไม่ได้ตั้งค่า lightning address เพื่อรับ sats - เปอร์เซ็นต์ - 25 - แบ่ง Zaps กับ - ส่งต่อ Zaps ไปยัง - ไม่พบกระเป๋า Lightning ชำระแล้ว กระเป๋า: %1$s เกิดข้อผิดพลาดในการเปิดแอพเข้ารหัส ไม่พบแอพที่สามารถช่วยเข้ารหัส หรือ signer โปรดตรวจดูอีกครั้งว่าได้ติดตั้งแอพแล้ว - Signer ปฏิเสธการเข้ารหัส โปรดตรวจสอบให้แน่ใจว่าแอพเข้ารหัส หรือ Signer ได้อนุญาติทำรายการนี้ ไม่พบกระเป๋า Lightning (Error: %1$s) โปรดติดตั้งแอพกระเป๋า Lightning ก่อน ไม่พบกระเป๋า Lightning โปรดติดตั้งแอพกระเป๋า Lightning ก่อน @@ -580,35 +445,18 @@ จงเลือกตัวเลือก ไม่สามารถชำระได้ ไม่สามารถถอนได้ - ไม่สามารถตั้งค่ากระเป๋าได้ - เกิดข้อผิดพลาดในการอ่านรหัสเชื่อมกระเป๋า NIP-47 . ตรวจสอบรหัสในการเชื่อมต่อกระเป๋าให้ดี: %1$s. Error: %2$s - เกิดข้อผิดพลาดในการอ่านรหัสเชื่อมกระเป๋า NIP-47 . ตรวจสอบรหัสในการเชื่อมต่อกระเป๋าให้ดี: %1$s. ไม่สามารถใช้งาน Cashu ผู้ให้บริการ Mint เกิดข้อผิดพลาด : %1$s - เงิน Cashu ถูกใช้ไปแล้ว ได้รับ Cashu %1$s sats ถูกส่งไปยังกระเป๋าของคุณ. (ค่าธรรมเนียม: %2$s sats) ไม่พบกระเป๋า Cashu ที่รองรับ ไม่สามารถสร้างบิลจากเซอเวอร์ของผู้รับเงินได้ เกิดข้อผิดพลาดจากบริการกระเป๋า Lightning : %1$s - ไม่สามารถเชื่อมต่อกับเครือข่าย Tor - ไม่พบข้อมูลเกี่ยวกับ Relay นี้ ไม่สามารถสร้าง LNUrl จากที่อยู่ Lightning ได้ \"%1$s\" โปรดตรวจสอบการตั้งค่า - บริการ Lightning ของ %1$s แลจะไม่พร้อมใช้งานจาก \"%2$s\". Error: %3$s. โปรดตรวจสอบผู้ให้บริการ หรือที่อยู่ Lightning ให้ถูกตต้อง - เกิดข้อผิดพลาด %1$s. โปรดตรวจสอบเครือข่ายเน็ต และทบทวนว่า %2$s นั้นถูกต้อง - เกิดข้อผิดพลาด %1$s. โปรดตรวจสอบเครือข่ายเน็ต และทบทวนว่า %2$s นั้นถูกต้อง\n\nข้อผิดพลาด : %3$s - ไม่สามารถสร้างบิลจาก %1$s - เกิดข้อผิดพลาดในการอ่าน JSON จากที่อยู่ Lightning โปรดตรวจสอบว่าที่อยู่นั้นถูกต้อง เกิดข้อผิดพลาดในการอ่าน JSON จาก %1$s. โปรดตรวจสอบการตั้งค่า Lightning - ไม่พบ Callback URL จากที่อยู่ Lightning นี้ โปรดตรวจสอบการตั้งค่าระบบ Lightning ของท่าน ไม่พบที่อยู่ URL จาก %1$s - เกิดข้อผิดพลาดในการอ่าน JSON จากบิลที่โหลดจากที่อยู่ Lightning โปรดตรวจสอบว่าที่อยู่นั้นถูกต้อง - เกิดข้อผิดพลาดในการอ่านบิล JSON จาก %1$s โปรดตรวจสอบการตั้งค่า lightning จำนวนที่ต้องชำระไม่ถูกต้อง (%1$s sats) จาก %2$s. มันควรจะเป็น %3$s ไม่สามารถสร้างบิลชำระในการส่ง zap ได้ โดยเกิดข้อผิดพลาด %1$s จากกระเป๋าของผู้รับ - ไม่สามารถสร้าง lightning invoice ข้อความจาก %1$s: %2$s - ไม่สามารถสร้างบิลชำระในการส่ง zap ได้ ไม่พบข้อมูล pr จากข้อมูลที่อยู่ผู้รับ - ไม่สามารถสร้างบิลชำระในการส่ง zap จาก %1$s เนื่องจากไม่พบ PR บน JSON ดูอย่างเดียว ไม่มีรายการ reaction เลือกแอพ UnifiedPush @@ -624,13 +472,11 @@ ส่งข้อความหาผู้ขาย สวัสดี! ยังมี %1$s อยู่ไหม? สวัสดี! สิ่งนี้ยังมีอยู่ไหม? - ขายบางอย่าง ชื่อ iPhone 13 สภาพ หมวดหมู่ ราคา (หน่วย Sats) - 1000 ตำแหน่ง เมือง, รัฐ, ประเทศ ใหม่ @@ -659,12 +505,9 @@ อื่นๆ ไม่สามารถโหลดสื่อได้ ไม่สามารถเปิดดูข้อมูลที่ถูกบีบอัดได้ - เกิดข้อผิดพลาดในการบีบอัดข้อมูล : %1$s เกิดข้อผิดพลาดขณะอัพโหลด: %1$s เซอเวอร์ไม่ตอบสนองหลังจากอัพโหลดแล้ว ไม่สามารถโหลดข้อมูลสื่อได้ - ไม่สามารถเตรียมข้อมูลสำหรับอัพโหลด : %1$s - การอัปโหลดล้มเหลว: %1$s การลบล้มเหลว: %1$s สื่อชิ้นนี้ใหญ่เกินไปสำหรับ NIP-95 ต่ำ @@ -672,16 +515,12 @@ สูง แก้ไขฉบับร่าง เข้าสู่ระบบด้วย qr code - เส้นทาง หน้าแรก - ค้นหา สำรวจ ข้อความ การแจ้งเตือน - ทั่วโลก Shorts - ตัวกรองความปลอดภัย โพสต์ใหม่ สร้าง Shorts: รูปภาพ/วิดีโอ สร้างโน๊ตสำหรับชุมชม @@ -696,29 +535,22 @@ รีเลย์ %1$s แสดงรายการรีเลย์ ตัวเลือกเพิ่มเติม - ตัวเลือกรายการรีเลย์ โพลล์ ยกเลิกโพลล์ Bitcoin Invoice ยกเลิก Bitcoin Invoice - ยกเลิกการขายสิ่งนี้ ระดมทุน ยกเลิกการระดมทุน ตำแหน่ง ลบตำแหน่งออก - แบ่งปัน zap - ยกเลิก Zap split เพิ่มคําเตือนเนื้อหา ลบคําเตือนเนื้อหา แสดง npub เป็น qr code ที่อยู่ไม่ถูกต้อง Amethyst ได้รับ URI แต่ URI นั้นไม่ถูกต้อง: %1$s รีเลย์ขาเข้าของ DM - รีเลย์: %1$s - ใช้รีเลย์ทั่วไป ตั้งค่ารีเลย์ส่วนตัวสำหรับรับข้อมูล การตั้งค่านี้จะแจ้งให้ทุกคนทราบว่าควรใช้รีเลย์ใดในการส่งข้อความถึงคุณ หากไม่มีการตั้งค่านี้ คุณอาจพลาดข้อความบางส่วนได้ - ตัวเลือกที่ดี ได้แก่:\n- inbox.nostr.wine (เสียค่าบริการ)\n- you.nostr1.com (รีเลย์ส่วนตัว - เสียค่าบริการ) ใส่รีเลย์ 1–3 ตัวเพื่อทำหน้าที่เป็นกล่องขาเข้าส่วนตัวของคุณ รีเลย์กล่องขาเข้า DM ควรยอมรับข้อความจากทุกคน แต่อนุญาตให้คุณดาวน์โหลดได้เท่านั้น ตั้งค่าตอนนี้เลย ค้นหารีเลย์ @@ -735,10 +567,6 @@ ใส่รีเลย์ 1–3 ตัวเพื่อทำหน้าที่เป็นกล่องขาเข้าส่วนตัวของคุณ คนอื่นจะใช้รีเลย์เหล่านี้ในการส่งข้อความ DM ถึงคุณ รีเลย์กล่องขาเข้า DM ควรยอมรับข้อความจากทุกคน แต่อนุญาตให้คุณดาวน์โหลดได้เท่านั้น ตัวเลือกที่ดี ได้แก่:\n - inbox.nostr.wine (เสียค่าบริการ)\n - you.nostr1.com (รีเลย์ส่วนตัว - เสียค่าบริการ) รีเลย์ส่วนตัว ใส่รีเลย์ 1–3 ตัวเพื่อเก็บเหตุการณ์ที่ไม่มีใครสามารถเห็นได้ เช่น ร่างโพสต์ และการตั้งค่าแอปของคุณ รีเลย์เหล่านี้ควรเป็นรีเลย์ภายในเครื่องหรือรีเลย์ที่ต้องมีการยืนยันตัวตนก่อนที่จะดาวน์โหลดเนื้อหาของผู้ใช้แต่ละคน - รีเลย์ทั่วไป - Amethyst ใช้รีเลย์เหล่านี้เพื่อดาวน์โหลดโพสต์สำหรับคุณ - รีเลย์ที่แนะนำ - เพิ่มรีเลย์เข้ารายการรีเลย์ทั่วไปเพื่อให้เห็นโพสต์จากผู้ใช้อื่น ๆ มากขึ้น ค้นหารีเลย์ รายการรีเลย์ที่จะใช้เมื่อค้นหาข้อมูลหรือผู้ใช้ การแท็กและการค้นหาจะไม่ทำงานหากไม่มีตัวเลือก ตรวจสอบให้แน่ใจว่ารีเลย์เหล่านี้รองรับ NIP-50 รีเลย์ในพื้นที่ของคุณ @@ -750,11 +578,8 @@ เวอร์ชันนี้นำเสนอโดย: เวอร์ชัน %1$s ขอบคุณ! - Max Limit การเขียนที่ถูกจำกัด คัดลอกมาจาก - คัดลอก - Git Repository: %1$s เว็บไซน์ สำเนา: OTS: %1$s @@ -762,18 +587,11 @@ มีหลักฐานว่าโพสต์นี้มีการลงนามก่อน %1$s หลักฐานถูกประทับตราใน Bitcoin blockchain ณ วันและเวลาดังกล่าว แก้ไขโพสต์ เสนอให้ปรับปรุงการโพสต์ - สรุปการเปลี่ยนแปลง - แก้ไขด่วน ยอมรับการแนะนำนี้ ดาวน์โหลด - เปิด Lyrics - ปิด Lyrics - ปิดผนึกข้อความแล้ว คลิกเพื่อเปิดข้อความ - เปิดผนึกข้อความไว้ คลิกเพื่อปิด ส่ง อ่านชื่อผู้ใช้เป็นเสียง สแกนคิวอาร์โค้ด - นำทางไปยังผู้ให้บริการกระเป๋าเงินบุคคลที่สาม Alby ไม่สามารถตอบกลับโน้ตฉบับร่างได้ ไม่สามารถโควทโน้ตฉบับร่างได้ ไม่สามารถกดรีแอคโน้ตฉบับร่างได้ @@ -833,4 +651,10 @@ + + บริการ Lightning ของ %1$s แลจะไม่พร้อมใช้งานจาก \"%2$s\". Error: %3$s. โปรดตรวจสอบผู้ให้บริการ หรือที่อยู่ Lightning ให้ถูกตต้อง + เกิดข้อผิดพลาด %1$s. โปรดตรวจสอบเครือข่ายเน็ต และทบทวนว่า %2$s นั้นถูกต้อง\n\nข้อผิดพลาด : %3$s + เกิดข้อผิดพลาดในการอ่านบิล JSON จาก %1$s โปรดตรวจสอบการตั้งค่า lightning + ไม่สามารถสร้าง lightning invoice ข้อความจาก %1$s: %2$s + ไม่สามารถสร้างบิลชำระในการส่ง zap จาก %1$s เนื่องจากไม่พบ PR บน JSON diff --git a/amethyst/src/main/res/values-th/strings.xml b/amethyst/src/main/res/values-th/strings.xml index e03e052818..52e6dbf049 100644 --- a/amethyst/src/main/res/values-th/strings.xml +++ b/amethyst/src/main/res/values-th/strings.xml @@ -20,8 +20,6 @@ เลียนแบบ พฤติกรรมที่ผิดกฎหมาย อื่นๆ - ไม่ทราบ - รีเลย์ไอคอน ไม่ทราบผู้เขียน คัดลอกข้อความ คัดลอก ID ผู้เขียน @@ -35,7 +33,6 @@ รายงาน: สแปม / หลอกลวง รายงาน: การเลียนแบบ - รายงาน: เนื้อหารุนแรง รายงาน: พฤติกรรมที่ผิดกฎหมาย รายงานมัลแวร์ มัลแวร์ @@ -49,7 +46,6 @@ เข้าสู่ระบบด้วย private key เพื่อเพิ่มการซ่อนข้อความ เข้าสู่ระบบด้วย private key เพื่อแก้ไขการซ่อนข้อความ Zaps - ยอดเข้าชม แชร์ แชร์ แก้ไขแล้ว @@ -62,9 +58,7 @@ เพิ่ม "ตอบกลับถึง " " และ " - " ในช่อง " หน้าปกโปรไฟล์ - การชำรพเงินเสร็จสมบูรณ์ เกิดข้อผิดพลาดในการวิเคราะห์ข้อความแสดงข้อผิดพลาด " กำลังติดตาม" " ผู้ติดตาม" @@ -79,9 +73,7 @@ ขอบคุณมาก! จำนวนในหน่วย sat ส่ง Sats - "ข้อผิดพลาดในการวิเคราะห์ตัวอย่างสําหรับ %1$s : %2$s" "รูปตัวอย่างสำหรับ %1$s" - Channel ใหม่ ชื่อ Channel กลุ่มที่ยอดเยี่ยมของฉัน! ที่อยู่ URL รูปภาพ @@ -92,39 +84,22 @@ บันทึก สร้าง ยกเลิก - ไม่สามารถโหลดรูปภาพได้ - ที่อยู่รีเลย์ - โพสต์ - ไบต์ ข้อผิดพลาด - เกิดข้อผิดพลาดในการเชื่อมต่อ - ฟีดเริ่มต้น - ฟีดข้อความส่วนตัว - ฟีดข้อความ - ฟีดโลก - ฟีดค้นหา เพิ่มรีเลย์ ชื่อที่แสดง ชื่อที่แสดงของฉัน ปลาอานนท์ สุดหล่อ ยินดีต้อนรับนะอานนท์! ชื่อผู้ใช้ - ชื่อผู้ใช้ของฉัน เกี่ยวกับฉัน ที่อยู่ URL รูปโปรไฟล์ ที่อยู่ URL รูปหน้าปก ที่อยู่ URL เว็บไซต์ - Lightning Address - LN URL (หมดอายุ) - บันทึกรูปภาพ บันทึกรูปภาพลงแกลเลอรี เกิดข้อผิดพลาดในการบันทึกรูปภาพ อัพโหลดรูปภาพ - กำลังอัพโหลด ผู้ใช้นี้ไม่ได้ตั้งค่า lightning address เพื่อรับ sats "ตอบกลับที่นี่.. " - คัดลอกโน้ต ID ลงคลิปบอร์ดเพื่อแชร์ไปยัง Nostr - คัดลอก Channel ID (โน้ต) ลงคลิปบอร์ด แก้ไข Channel Metadata เข้าร่วม รู้ @@ -135,16 +110,12 @@ โน้ต ตอบกลับ คลังภาพ - "ติดตาม" "รายงาน" ตัวเลือกเพิ่มเติม " รีเลย์" เว็บไซต์ ไม่ได้ตั้งค่า Lightning Address คัดลอก Nsec ID (รหัสผ่านของคุณ) ลงคลิปบอร์ดเพื่อสำรองข้อมูล - คัดลอก Secret Key ลงคลิปบอร์ด - คัดลอก public key ลงคลิปบอร์ดเพื่อแชร์ - คัดลอก Public Key (NPub) ลงคลิปบอร์ด ส่งข้อความส่วนตัว แก้ไข the User\'s Metadata ติดตาม @@ -173,20 +144,12 @@ ใช้ชื่อเล่นว่าอะไรดีเอ่ย? ยังไม่มีบัญชี Nostr หรือ? มีบัญชี Nostr อยู่แล้ว? - สร้างบัญชีผู้ใช้ใหม่ - สร้าง key ใหม่ กำลังดาวน์โหลดฟีด กำลังโหลดข้อมูลบัญชี "ไม่สามารถโหลดการตอบกลับ: " ลองอีกครั้ง ฟีดนี้ว่างเปล่า รีเฟรช - สร้าง - พร้อมคําอธิบายของ - และ รูปภาพ - เปลี่ยนชื่อ chat เป็น - คําอธิบายของ - และ รูปภาพของ ออก เลิกติดตาม สร้าง Channel @@ -210,7 +173,6 @@ คําหยาบคาย / คําพูดที่แสดงความเกลียดชัง รายงาน: คําพูดที่แสดงความเกลียดชัง รายงาน: ภาพเปลือย/สื่อลามก - อื่น ๆ ทำเครื่องหมายอ่านแล้วในแชทที่รู้จักทั้งหมด ทำเครื่องหมายว่าอ่านแล้วทั้งหมดสำหรับข้อความใหม่ ทพเครื่องหมายว่าอ่านแล้วทั้งหมด @@ -230,23 +192,18 @@ เกิดข้อผิดพลาดในการตรวจสอบ เกิดข้อผิดพลาดจากการยืนยันตนด้วยชีวภาพ เกิดข้อผิดพลาดจากการยืนยันตนด้วยชีวภาพ: Error: %1$s - ข้อผิดพลาด - "สร้างโดย %1$s" "ภาพเหรียญตราสําหรับ %1$s" คุณได้รับเหรียญตราใหม่ เหรียญตราถูกมอบให้กับ คัดลอกข่้อความในโน้ตลงคลิปบอร์ด คัดลอก @npub ของผู้เขียนลงคลิปบอร์ด คัดลอกโน้ต ID (@note1)ลงคลิปบอร์ด - เลือกข้อความ "<ไม่สามารถถอดรหัสข้อความส่วนตัวได้>\n\nคุณถูกอ้างถึงในการสนทนาส่วนตัว/เข้ารหัสระหว่าง %1$s และ %2$s." เพิ่มบัญชีใหม่ บัญชี เลือกบัญชี เพิ่มบัญชีใหม่ บัญชีที่ใช้งานอยู่ - มี private key - อ่านเท่านั้น, ไม่มี private key ย้อนกลับ เลือก แชร์ Browser Link @@ -264,14 +221,12 @@ ลบ บล๊อก รายงาน - ลบ ไม่แสดงข้อความนี้อีก สแปม หรือ หลอกลวง คําหยาบคายหรือการแสดงความเกลียดชัง การแอบอ้างบุคคลอื่นที่เป็นอันตราย เนื้อหาภาพเปลือย พฤติกรรมที่ผิดกฎหมาย - มัลแวร์ การบล็อกผู้ใช้จะซ่อนเนื้อหาของพวกเขาในแอปของคุณ โน้ตของคุณยังคงดูได้แบบสาธารณะรวมถึงคนที่คุณบล็อกด้วย ผู้ใช้ที่ถูกบล็อกจะแสดงรายการบนหน้าจอตัวกรองความปลอดภัย รายงานการล่วงละเมิด @@ -291,30 +246,15 @@ เพิ่มไปยังบุ๊คมาร์คสาธรณะ ลบออกจากบุ๊คมาร์คส่วนตัว ลบออกจากบุ๊คมาร์คสาธรณะ - บริการเชื่อมต่อ wallet - อนุญาตให้ Nostr Secret จ่าย zaps โดยไม่ต้องออกจากแอป เพื่อรักษาความลับให้ปลอดภัยและใช้รีเลย์ส่วนตัวหากเป็นไปได้ - Wallet Connect Pubkey - บริการเชื่อมต่อ wallet - Wallet Connect Secret - แสดง secret key - nsec/ private key ในฐาน16 จำนวนเงินที่นำเข้าในหน่วย sat - สร้างโพลล์ - ส่วนที่จำเป็น: - ผู้รับ Zap - คำอธิบายโพลล์… ตัวเลือก %s คำอธิบายตัวเลือกในโพลล์ - ตำอธิบายเพิ่มเติม: Zap ขั้นต่ำ Zap สูงสุด ฉันทามติ (0–100)% - ปิดหลังจาก - วัน ไม่สามารถโหวต โพลปิดรับการลงคะแนนเพิ่มเติม - จำนวน Zap อนุญาตให้โหวตได้เพียงครั้งเดียวต่อผู้ใช้หนึ่งคนสำหรับการสำรวจประเภทนี้ "กำลังมองหา Event %1$s" เพิ่มในข้อความสาธรณะ @@ -343,35 +283,18 @@ แอบแซ่บ ไม่มีการบันทึกบน Nostr, มีแค่ในระบบ Lightning เซิร์ฟเวอร์เก็บข้อมูล - LnAddress หรือ @ชื่อผู้ใช้ Media Servers ตั้งค่า media server ที่คุณต้องการ - Built-in Media Servers รายการค่าเริ่มต้นของ Amethyst คุณสามารถเพิ่มทีละรายการหรือเพิ่มทั้งรายการก็ได้ ใช้รายการค่าเริ่มต้น เพิ่ม media server ลบ media server - รีเลย์ของคุณ (NIP-95) - ไฟล์อยู่บนรีเลย์ของคุณ New NIP: โปรดตรวจสอบว่ามีการรองรับหรือไม่ - ตั้งค่า Tor/Orbot - การตั้งค่าการเชื่อมต่อ Orbot ของคุณ - ตัดการเชื่อมต่อจาก Orbot/Tor ของคุณ? - ข้อมูลของคุณจะถูกถ่ายโอนในเครือข่ายปกติทันที ใช่ ไม่ - รายการผู้ติดตาม ติดตามทั้งหมด ทั่วโลก รายการผู้ถูกปิดกั้น Port เริ่มต้นคือ 9050 - ## เชื่อมต่อกัย Tor ด้วย Orbot - \n\n1. ติดตั้ง [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. เริ่มต้นใช้งาน Orbot - \n3. ใน Orbot, ตรวจสอบe Socks port. ค่าเริ่มต้นเป็น 9050 - \n4. หากจําเป็นให้เปลี่ยนพอร์ตใน Orbot - \n5. กําหนดค่า Socks port บนหน้าจอนี้ - \n6. กดปุ่มเปิดใช้งานเพื่อใช้ Orbot เป็น proxy - พอร์ต Orbot Socks รีเลย์สำหรีบข้อความส่วนตัว ปิด @@ -380,8 +303,6 @@ ซ่อน IP ของคุณจากทุกอย่าง ยกเว้นรูปภาพและวิดีโอ ซ่อน IP ของคุณจากทุกการเชื่อมต่อ เลข port ไม่ถูกต้องr - ใช้ Orbot - ตัดการเชื่อมต่อจาก Tor/Orbot ข้อความส่วนตัว แจ้งเตือนฉันเมื่อข้อความส่วนตัวมาถึง ได้รับ Zaps @@ -390,20 +311,9 @@ จาก %1$s ถึง %1$s การแจ้งเตือน: - เข้าร่วมการสนทนา - ผู้ใช้ หรือ Group\'s ID - npub, nevent หรือ hex - สร้าง - เข้าร่วม วันนี้ คําเตือนเนื้อหา โพสต์นี้มีเนื้อหาที่ละเอียดอ่อนซึ่งบางคนอาจพบว่าไม่เหมาะสมหรือรบกวน - ซ่อนเนื้อหาที่ละเอียดอ่อนเสมอ - แสดงเนื้อหาที่ละเอียดอ่อนเสมอ - แสดงคำเตือนเนื้อหาเสมอ - แนะนำ: - กรองสแปมจากคนแปลกหน้า - เตือนเมื่อมีการรายงานโพสต์จากผู้ติดตามของคุณ สัญลักษณ์ Reaction ใหม่ ไม่มีการเลือกประเภทของ reaction กดค้างเพื่อเปลี่ยน ระดมทุน @@ -414,37 +324,24 @@ เขียนบน Relay จำนวนข้อมูลในหน่วยไบต์ที่ถูกส่งไปยังรีเลย์นี้ รวมถึงฟิลเตอร์และอีเว้นต่างๆ จำนวนข้อมูลในหน่วยไบต์ที่ถูกรับมาจากรีเลย์นี้ รวมถึงฟิลเตอร์และอีเว้นต่างๆ - เกิดข้อผิดพลาดในการรับข้อมูลจาก %1$s เจ้าของ เวอร์ชัน ซอฟต์แวร์ ติดต่อ รับรอง NIPs - ค่าใช้จ่ายสำหรับการใช้งาน url การชำระเงิน ข้อจำกัด ประเทศ ภาษา - แท็ก นโยบายการโพสต์ ประกาศจากทางรีเลย์ - ความยาวข้อความ - การสมัครสมาชิก - ฟิลเตอร์ - ความยาวของรหัสการสมัครสมาชิก คำนำหน้าขั้นต่ำ event tags สูงสุด - ความยาวของเนื้อหา PoW ขั้นต่ำ - ยืนยัน - การชำระเงิน โทเคน Cashu แลกคืน - ส่งไปยังกระเป๋า Lightning - เปิดด้วยกระเป๋า Cashu คัดลอก ไม่ได้ตั้งค่า Lightning Address - คัดลอกโทเคนลงคลิปบอร์ด ถ่ายทอดสด ออฟไลน์ สิ้นสุดแล้ว @@ -463,7 +360,6 @@ เพิ่มการแจ้งเตือนเนื้อหาที่ละเอียดอ่อนก่อนโชว์เนื้อหานี้ การตั้งค่า ตลอดเวลา - Wifi เท่านั้น Unmetered WiFi ไม่ต้องแสดง เสร็จสมบูรณ์ @@ -482,7 +378,6 @@ ซ่อนแถบเมนูขณะเลื่อนฟีด UI Mode เลือกรูปแบบการโพสต์ - โหลดรูปภาพ แสปม ปิดการมองเห็น คลิกเพื่อปลดออก เปิดการมองเห็นอยู่ คลิกเพื่อปิด @@ -490,17 +385,10 @@ Nostr address ได้รับการยืนยัน ไม่สามารถยืนยัน Nostr address ได้ ตรวจสอบ Nostr address - เลือก/ไม่เลือก ทั้งหมด ค่าเริ่มต้น - เลือกรีเลย์เพื่อดำเนินการต่อ - ส่งต่อ Zaps ถึง: - ไคลเอนต์ที่สนับสนุนจะส่งต่อ zaps ไปยัง LNAddress หรือโปรไฟล์ผู้ใช้ด้านล่างแทนที่จะเป็นของคุณ เปิดเผยตําแหน่งที่ตั้ง เพิ่ม Geohash ของตําแหน่งของคุณลงในโพสต์ สาธารณชนจะรู้ว่าคุณอยู่ภายใน 5 กม. (3 ไมล์) จากตําแหน่งปัจจุบัน เพิ่มคําเตือนเนื้อหาที่ละเอียดอ่อนก่อนแสดงเนื้อหาของคุณ สิ่งนี้เหมาะสําหรับเนื้อหา NSFW หรือเนื้อหาใด ๆ ที่บางคนอาจพบว่าไม่เหมาะสมหรือรบกวน - ฟีเจอร์ใหม่ - การเปิดใช้งานโหมดนี้ต้องใช้ Amethyst เพื่อส่งข้อความ NIP-17 (GiftWrapped, Sealed Direct และ Group Messages) NIP-17 เป็นของใหม่และไคลเอ็นต์ส่วนใหญ่ยังไม่ได้รองรับ ตรวจสอบให้แน่ใจว่าเครื่องรับใช้ไคลเอ็นต์ที่รองรับ - เปิดใช้งาน สาธรณะ สร้างกลุ่มสาธารณะ/ส่วนตัว ส่วนตัว @@ -517,7 +405,6 @@ โหลดรูปภาพและ GIFs โดยอัตโนมัติ เล่นวีดีโอและ GIFs โดยอัตโนมัติ แสดงจัวอย่าง URL - ควรโหลดรูปภาพเมื่อใด คัดลอก คัดลอก npub ไปยังคลิปบอร์ด แชร์ หรือเก็บไว้ @@ -525,44 +412,22 @@ คัดลอก โน้ต ID ลงคลิปบอร์ดd เพิ่มไปยังคลังภาพ สร้างโดย - กฏ เข้าสู่ระบบด้วย Amber คุณกำลังทำอะไรอยู่… - เกิดข้อผิดพลาดในการแสดงข้อความ โหวตถูกให้น้ำหนักโดยจำนวน Zaps. คุณสามารถตั้งจำนวนเงินต่ำสุด และจำนวนครั้งสูงสุดในการโหวตเพื่อหลีกเลี่ยงการแสปมผลโพล. ใช้จำนวนเงินที่เท่ากันในทุกหัวข้อเพื่อให้การโหวตเป็นไปอย่างเท่าเทียม ปล่อยช่องว่าง หากต้องการให้โหวตเท่าใดก็ได้ แย่จัง ส่ง Zaps ไม่ได้ ส่งข้อความ ตกลง - ไม่สามารถเชื่อมถึง %1$s: %2$s - การประกอบ URL NIP-11 สำหรับ %1$s ล้มเหลว: %2$s - การเชื่อมต่อกับ %1$s ล้มเหลว: %2$s - การแปลผลตอบกลับจาก %1$s ล้มเหลว: %2$s - รีเลย์ปฏิเสธคำขอ %1$s: %2$s - ไม่สามารถเชื่อมถึง %1$s: %2$s - เกิดข้อผิดพลาด %1$s: %2$s - %1$s เกิดข้อผิดพลาด %2$s - ใช้งานมา: - หน้าแรก - กล่องข้อความ - ช่องสนทนา - ทั่วโลก - ค้นหา แบ่ง และส่งต่อ Zaps แอพที่รองรับจะทำการแบ่ง Zaps ที่ได้ไปยังผู้ใช้ที่เพิ่มมาในรายการนี้ ค้นหา และเพิ่มผู้ใช้ ชื่อผู้ใช้ หรือชื่อที่แสดง ไม่พบการตั้งค่า Lightning ผู้ใช้ %1$s ไม่ได้ตั้งค่า lightning address เพื่อรับ sats - เปอร์เซ็นต์ - 25 - แบ่ง Zaps กับ - ส่งต่อ Zaps ไปยัง - ไม่พบกระเป๋า Lightning ชำระแล้ว กระเป๋า: %1$s เกิดข้อผิดพลาดในการเปิดแอพเข้ารหัส ไม่พบแอพที่สามารถช่วยเข้ารหัส หรือ signer โปรดตรวจดูอีกครั้งว่าได้ติดตั้งแอพแล้ว - Signer ปฏิเสธการเข้ารหัส โปรดตรวจสอบให้แน่ใจว่าแอพเข้ารหัส หรือ Signer ได้อนุญาติทำรายการนี้ ไม่พบกระเป๋า Lightning (Error: %1$s) โปรดติดตั้งแอพกระเป๋า Lightning ก่อน ไม่พบกระเป๋า Lightning โปรดติดตั้งแอพกระเป๋า Lightning ก่อน @@ -573,35 +438,18 @@ จงเลือกตัวเลือก ไม่สามารถชำระได้ ไม่สามารถถอนได้ - ไม่สามารถตั้งค่ากระเป๋าได้ - เกิดข้อผิดพลาดในการอ่านรหัสเชื่อมกระเป๋า NIP-47 . ตรวจสอบรหัสในการเชื่อมต่อกระเป๋าให้ดี: %1$s. Error: %2$s - เกิดข้อผิดพลาดในการอ่านรหัสเชื่อมกระเป๋า NIP-47 . ตรวจสอบรหัสในการเชื่อมต่อกระเป๋าให้ดี: %1$s. ไม่สามารถใช้งาน Cashu ผู้ให้บริการ Mint เกิดข้อผิดพลาด : %1$s - เงิน Cashu ถูกใช้ไปแล้ว ได้รับ Cashu %1$s sats ถูกส่งไปยังกระเป๋าของคุณ. (ค่าธรรมเนียม: %2$s sats) ไม่พบกระเป๋า Cashu ที่รองรับ ไม่สามารถสร้างบิลจากเซอเวอร์ของผู้รับเงินได้ เกิดข้อผิดพลาดจากบริการกระเป๋า Lightning : %1$s - ไม่สามารถเชื่อมต่อกับเครือข่าย Tor - ไม่พบข้อมูลเกี่ยวกับ Relay นี้ ไม่สามารถสร้าง LNUrl จากที่อยู่ Lightning ได้ \"%1$s\" โปรดตรวจสอบการตั้งค่า - บริการ Lightning ของ %1$s แลจะไม่พร้อมใช้งานจาก \"%2$s\". Error: %3$s. โปรดตรวจสอบผู้ให้บริการ หรือที่อยู่ Lightning ให้ถูกตต้อง - เกิดข้อผิดพลาด %1$s. โปรดตรวจสอบเครือข่ายเน็ต และทบทวนว่า %2$s นั้นถูกต้อง - เกิดข้อผิดพลาด %1$s. โปรดตรวจสอบเครือข่ายเน็ต และทบทวนว่า %2$s นั้นถูกต้อง\n\nข้อผิดพลาด : %3$s - ไม่สามารถสร้างบิลจาก %1$s - เกิดข้อผิดพลาดในการอ่าน JSON จากที่อยู่ Lightning โปรดตรวจสอบว่าที่อยู่นั้นถูกต้อง เกิดข้อผิดพลาดในการอ่าน JSON จาก %1$s. โปรดตรวจสอบการตั้งค่า Lightning - ไม่พบ Callback URL จากที่อยู่ Lightning นี้ โปรดตรวจสอบการตั้งค่าระบบ Lightning ของท่าน ไม่พบที่อยู่ URL จาก %1$s - เกิดข้อผิดพลาดในการอ่าน JSON จากบิลที่โหลดจากที่อยู่ Lightning โปรดตรวจสอบว่าที่อยู่นั้นถูกต้อง - เกิดข้อผิดพลาดในการอ่านบิล JSON จาก %1$s โปรดตรวจสอบการตั้งค่า lightning จำนวนที่ต้องชำระไม่ถูกต้อง (%1$s sats) จาก %2$s. มันควรจะเป็น %3$s ไม่สามารถสร้างบิลชำระในการส่ง zap ได้ โดยเกิดข้อผิดพลาด %1$s จากกระเป๋าของผู้รับ - ไม่สามารถสร้าง lightning invoice ข้อความจาก %1$s: %2$s - ไม่สามารถสร้างบิลชำระในการส่ง zap ได้ ไม่พบข้อมูล pr จากข้อมูลที่อยู่ผู้รับ - ไม่สามารถสร้างบิลชำระในการส่ง zap จาก %1$s เนื่องจากไม่พบ PR บน JSON ดูอย่างเดียว ไม่มีรายการ reaction เลือกแอพ UnifiedPush @@ -617,13 +465,11 @@ ส่งข้อความหาผู้ขาย สวัสดี! ยังมี %1$s อยู่ไหม? สวัสดี! สิ่งนี้ยังมีอยู่ไหม? - ขายบางอย่าง ชื่อ iPhone 13 สภาพ หมวดหมู่ ราคา (หน่วย Sats) - 1000 ตำแหน่ง เมือง, รัฐ, ประเทศ ใหม่ @@ -652,12 +498,9 @@ อื่นๆ ไม่สามารถโหลดสื่อได้ ไม่สามารถเปิดดูข้อมูลที่ถูกบีบอัดได้ - เกิดข้อผิดพลาดในการบีบอัดข้อมูล : %1$s เกิดข้อผิดพลาดขณะอัพโหลด: %1$s เซอเวอร์ไม่ตอบสนองหลังจากอัพโหลดแล้ว ไม่สามารถโหลดข้อมูลสื่อได้ - ไม่สามารถเตรียมข้อมูลสำหรับอัพโหลด : %1$s - การอัปโหลดล้มเหลว: %1$s การลบล้มเหลว: %1$s สื่อชิ้นนี้ใหญ่เกินไปสำหรับ NIP-95 ต่ำ @@ -665,15 +508,11 @@ สูง แก้ไขฉบับร่าง เข้าสู่ระบบด้วย qr code - เส้นทาง หน้าแรก - ค้นหา สำรวจ ข้อความ การแจ้งเตือน - ทั่วโลก Shorts - ตัวกรองความปลอดภัย โพสต์ใหม่ สร้าง Shorts: รูปภาพ/วิดีโอ สร้างโน๊ตสำหรับชุมชม @@ -688,29 +527,22 @@ รีเลย์ %1$s แสดงรายการรีเลย์ ตัวเลือกเพิ่มเติม - ตัวเลือกรายการรีเลย์ โพลล์ ยกเลิกโพลล์ Bitcoin Invoice ยกเลิก Bitcoin Invoice - ยกเลิกการขายสิ่งนี้ ระดมทุน ยกเลิกการระดมทุน ตำแหน่ง ลบตำแหน่งออก - แบ่งปัน zap - ยกเลิก Zap split เพิ่มคําเตือนเนื้อหา ลบคําเตือนเนื้อหา แสดง npub เป็น qr code ที่อยู่ไม่ถูกต้อง Amethyst ได้รับ URI แต่ URI นั้นไม่ถูกต้อง: %1$s รีเลย์ขาเข้าของ DM - รีเลย์: %1$s - ใช้รีเลย์ทั่วไป ตั้งค่ารีเลย์ส่วนตัวสำหรับรับข้อมูล การตั้งค่านี้จะแจ้งให้ทุกคนทราบว่าควรใช้รีเลย์ใดในการส่งข้อความถึงคุณ หากไม่มีการตั้งค่านี้ คุณอาจพลาดข้อความบางส่วนได้ - ตัวเลือกที่ดี ได้แก่:\n- inbox.nostr.wine (เสียค่าบริการ)\n- you.nostr1.com (รีเลย์ส่วนตัว - เสียค่าบริการ) ใส่รีเลย์ 1–3 ตัวเพื่อทำหน้าที่เป็นกล่องขาเข้าส่วนตัวของคุณ รีเลย์กล่องขาเข้า DM ควรยอมรับข้อความจากทุกคน แต่อนุญาตให้คุณดาวน์โหลดได้เท่านั้น ตั้งค่าตอนนี้เลย ค้นหารีเลย์ @@ -727,10 +559,6 @@ ใส่รีเลย์ 1–3 ตัวเพื่อทำหน้าที่เป็นกล่องขาเข้าส่วนตัวของคุณ คนอื่นจะใช้รีเลย์เหล่านี้ในการส่งข้อความ DM ถึงคุณ รีเลย์กล่องขาเข้า DM ควรยอมรับข้อความจากทุกคน แต่อนุญาตให้คุณดาวน์โหลดได้เท่านั้น ตัวเลือกที่ดี ได้แก่:\n - inbox.nostr.wine (เสียค่าบริการ)\n - you.nostr1.com (รีเลย์ส่วนตัว - เสียค่าบริการ) รีเลย์ส่วนตัว ใส่รีเลย์ 1–3 ตัวเพื่อเก็บเหตุการณ์ที่ไม่มีใครสามารถเห็นได้ เช่น ร่างโพสต์ และการตั้งค่าแอปของคุณ รีเลย์เหล่านี้ควรเป็นรีเลย์ภายในเครื่องหรือรีเลย์ที่ต้องมีการยืนยันตัวตนก่อนที่จะดาวน์โหลดเนื้อหาของผู้ใช้แต่ละคน - รีเลย์ทั่วไป - Amethyst ใช้รีเลย์เหล่านี้เพื่อดาวน์โหลดโพสต์สำหรับคุณ - รีเลย์ที่แนะนำ - เพิ่มรีเลย์เข้ารายการรีเลย์ทั่วไปเพื่อให้เห็นโพสต์จากผู้ใช้อื่น ๆ มากขึ้น ค้นหารีเลย์ รายการรีเลย์ที่จะใช้เมื่อค้นหาข้อมูลหรือผู้ใช้ การแท็กและการค้นหาจะไม่ทำงานหากไม่มีตัวเลือก ตรวจสอบให้แน่ใจว่ารีเลย์เหล่านี้รองรับ NIP-50 รีเลย์ในพื้นที่ของคุณ @@ -742,11 +570,8 @@ เวอร์ชันนี้นำเสนอโดย: เวอร์ชัน %1$s ขอบคุณ! - Max Limit การเขียนที่ถูกจำกัด คัดลอกมาจาก - คัดลอก - Git Repository: %1$s เว็บไซน์ สำเนา: OTS: %1$s @@ -754,18 +579,11 @@ มีหลักฐานว่าโพสต์นี้มีการลงนามก่อน %1$s หลักฐานถูกประทับตราใน Bitcoin blockchain ณ วันและเวลาดังกล่าว แก้ไขโพสต์ เสนอให้ปรับปรุงการโพสต์ - สรุปการเปลี่ยนแปลง - แก้ไขด่วน ยอมรับการแนะนำนี้ ดาวน์โหลด - เปิด Lyrics - ปิด Lyrics - ปิดผนึกข้อความแล้ว คลิกเพื่อเปิดข้อความ - เปิดผนึกข้อความไว้ คลิกเพื่อปิด ส่ง อ่านชื่อผู้ใช้เป็นเสียง สแกนคิวอาร์โค้ด - นำทางไปยังผู้ให้บริการกระเป๋าเงินบุคคลที่สาม Alby ไม่สามารถตอบกลับโน้ตฉบับร่างได้ ไม่สามารถโควทโน้ตฉบับร่างได้ ไม่สามารถกดรีแอคโน้ตฉบับร่างได้ @@ -814,4 +632,9 @@ ไม่สามารถเปิดไฟล์ได้ แลือกลิสต์เพื่อโชว์ ออกจากระบบ + บริการ Lightning ของ %1$s แลจะไม่พร้อมใช้งานจาก \"%2$s\". Error: %3$s. โปรดตรวจสอบผู้ให้บริการ หรือที่อยู่ Lightning ให้ถูกตต้อง + เกิดข้อผิดพลาด %1$s. โปรดตรวจสอบเครือข่ายเน็ต และทบทวนว่า %2$s นั้นถูกต้อง\n\nข้อผิดพลาด : %3$s + เกิดข้อผิดพลาดในการอ่านบิล JSON จาก %1$s โปรดตรวจสอบการตั้งค่า lightning + ไม่สามารถสร้าง lightning invoice ข้อความจาก %1$s: %2$s + ไม่สามารถสร้างบิลชำระในการส่ง zap จาก %1$s เนื่องจากไม่พบ PR บน JSON diff --git a/amethyst/src/main/res/values-tr-rTR/strings.xml b/amethyst/src/main/res/values-tr-rTR/strings.xml index 75945f8d35..e0114ca5fc 100644 --- a/amethyst/src/main/res/values-tr-rTR/strings.xml +++ b/amethyst/src/main/res/values-tr-rTR/strings.xml @@ -15,8 +15,6 @@ İstenmeyen Taklit Etme İllegal Davranış - Bilinmeyen - Relay İkonu Bilinmeyen Yazar Yazıyı Kopyala Kullanıcı PubKey\'ini Kopyala @@ -25,7 +23,6 @@ İstenmeyen Raporla Taklit Etme Raporla - Müstehcen İçerik Raporla İllegal Davranış Raporla Yanıtlamak için bir Gizli Anahtarla giriş yap Gönderileri desteklemek için bir Gizli Anahtarla giriş yap @@ -33,7 +30,6 @@ Zap miktarı belirlenmedi. Değiştirmek için uzun basılı tutun Zap göndermek için bir Gizli Anahtarla giriş yap Zapler - Görüntülenme sayısı Destekle desteklendi Alıntı @@ -41,7 +37,6 @@ Ekle "yanıtlanıyor" "ve" - "kanalda" Profil Bayrağı "Takip edilenler" "Takipçiler" @@ -56,7 +51,6 @@ Çok teşekkürler! Satlarda Miktar Satlar Gönder - Yeni Kanal Kanal Adı Benim Harika Grubum Resim URL\'si @@ -67,34 +61,20 @@ Kaydet Oluştur Vazgeç - Resim yüklenemedi - Relay Adresi - Gönderiler Hatalar - Ana Akış - Gizli Mesaj Akışı - Açık Mesaj Akışı - Küresel Akış - Akış Ara Relay Ekle Görüntü Adı Benim görüntü adım Kullanıcı Adı - Benim kullanıcı adım Hakkımda Avatar URL\'i Bayrakk URL\'i Website URL\'si - LN Adresi - LN URL\'si (tarihi geçmiş) Resim galeriye kaydedildi Resim galeriye kaydedilemedi Resim Yükle - Yükleniyor… Kullanıcının sats alabileceği bir lightning adresi kurulu değil "buraya yanıtlayın…" - Paylaşmak için Not ID\'sini panoya kopyalar - Kanal ID\'sini (Not) panoya kopyala Kanal Üstveri\'sini Editle Katıl Bilinen @@ -104,15 +84,11 @@ Diyaloglar Notlar Yanıtlar - "Takipler" "Raporlar" Daha Fazla Seçenek "Relaylar" Lİghtning Adresi Yedekleme için Nsec ID\'yi (sizin şifreniz) panoya kopyalar - Gizli Anahtarı Panoya Kopyala - Paylaşmak için açık anahtarı panoya kopyalar - Açık Anahtarı (NPub) Panoya Kopyala Direkt Mesaj Gönder Kullanıcının Üstverisini Düzenler Takip Et @@ -131,7 +107,6 @@ Kullanım şartlarını kabul etmeniz gerekiyor Anahtar gerekiyor Giriş Yap - Yeni anahtar oluştur Akış yükleniyor @@ -139,12 +114,6 @@ Tekrar dene Akış boş Yenile - oluşturuldu - şu açıklamayla - ve fotoğrafla - chat ismini şuna değiştirdi - açıklamayı - fotoğrafı Ayrıl Takip Etme Kanal oluşturuldu @@ -164,11 +133,9 @@ Küfür / Nefret dolu konuşma Nefret dolu konuşmayı raporla Çıplaklık / Cinselliği raporla - diğerleri Tüm bilinenleri okundu olarak işaretle Tüm yenileri okundu olarak işaretle Tümünü okundu olarak işaretle - Hata + diff --git a/amethyst/src/main/res/values-tr/strings.xml b/amethyst/src/main/res/values-tr/strings.xml index b404a3f538..078e483daa 100644 --- a/amethyst/src/main/res/values-tr/strings.xml +++ b/amethyst/src/main/res/values-tr/strings.xml @@ -15,8 +15,6 @@ İstenmeyen Taklit Etme İllegal Davranış - Bilinmeyen - Relay İkonu Bilinmeyen Yazar Yazıyı Kopyala Kullanıcı PubKey\'ini Kopyala @@ -25,7 +23,6 @@ İstenmeyen Raporla Taklit Etme Raporla - Müstehcen İçerik Raporla İllegal Davranış Raporla Yanıtlamak için bir Gizli Anahtarla giriş yap Gönderileri desteklemek için bir Gizli Anahtarla giriş yap @@ -33,7 +30,6 @@ Zap miktarı belirlenmedi. Değiştirmek için uzun basılı tutun Zap göndermek için bir Gizli Anahtarla giriş yap Zapler - Görüntülenme sayısı Destekle desteklendi Alıntı @@ -41,7 +37,6 @@ Ekle "yanıtlanıyor" "ve" - "kanalda" Profil Bayrağı "Takip edilenler" "Takipçiler" @@ -56,7 +51,6 @@ Çok teşekkürler! Satlarda Miktar Satlar Gönder - Yeni Kanal Kanal Adı Benim Harika Grubum Resim URL\'si @@ -67,34 +61,20 @@ Kaydet Oluştur Vazgeç - Resim yüklenemedi - Relay Adresi - Gönderiler Hatalar - Ana Akış - Gizli Mesaj Akışı - Açık Mesaj Akışı - Küresel Akış - Akış Ara Relay Ekle Görüntü Adı Benim görüntü adım Kullanıcı Adı - Benim kullanıcı adım Hakkımda Avatar URL\'i Bayrakk URL\'i Website URL\'si - LN Adresi - LN URL\'si (tarihi geçmiş) Resim galeriye kaydedildi Resim galeriye kaydedilemedi Resim Yükle - Yükleniyor… Kullanıcının sats alabileceği bir lightning adresi kurulu değil "buraya yanıtlayın…" - Paylaşmak için Not ID\'sini panoya kopyalar - Kanal ID\'sini (Not) panoya kopyala Kanal Üstveri\'sini Editle Katıl Bilinen @@ -104,15 +84,11 @@ Diyaloglar Notlar Yanıtlar - "Takipler" "Raporlar" Daha Fazla Seçenek "Relaylar" Lİghtning Adresi Yedekleme için Nsec ID\'yi (sizin şifreniz) panoya kopyalar - Gizli Anahtarı Panoya Kopyala - Paylaşmak için açık anahtarı panoya kopyalar - Açık Anahtarı (NPub) Panoya Kopyala Direkt Mesaj Gönder Kullanıcının Üstverisini Düzenler Takip Et @@ -131,18 +107,11 @@ Kullanım şartlarını kabul etmeniz gerekiyor Anahtar gerekiyor Giriş Yap - Yeni anahtar oluştur Akış yükleniyor "Yanıtları yüklemekte hata: " Tekrar dene Akış boş Yenile - oluşturuldu - şu açıklamayla - ve fotoğrafla - chat ismini şuna değiştirdi - açıklamayı - fotoğrafı Ayrıl Takip Etme Kanal oluşturuldu @@ -162,9 +131,7 @@ Küfür / Nefret dolu konuşma Nefret dolu konuşmayı raporla Çıplaklık / Cinselliği raporla - diğerleri Tüm bilinenleri okundu olarak işaretle Tüm yenileri okundu olarak işaretle Tümünü okundu olarak işaretle - Hata diff --git a/amethyst/src/main/res/values-uk-rUA/strings.xml b/amethyst/src/main/res/values-uk-rUA/strings.xml index 0a6cf5e29e..ba25c59c51 100644 --- a/amethyst/src/main/res/values-uk-rUA/strings.xml +++ b/amethyst/src/main/res/values-uk-rUA/strings.xml @@ -15,8 +15,6 @@ Спам Видача себе за іншу особу Незаконні дії - Невідомо - Іконка релею Невідомий автор Скопіювати текст Скопіювати ключ користувача @@ -26,7 +24,6 @@ Повідомити про спам / шахрайство Повідомити про видачу себе за іншу особу - Повідомити про відвертий вміст Повідомити про незаконні дії Увійдіть з приватним ключем щоб відповісти Увійдіть з приватним ключем щоб просувати дописи @@ -38,7 +35,6 @@ Ви використовуєте відкритий ключ, і відкриті ключі доступні лише для читання. Увійдіть за допомогою закритого ключа, щоб мати можливість приховати слово або речення Ви використовуєте відкритий ключ, і відкриті ключі доступні лише для читання. Увійдіть за допомогою закритого ключа, щоб мати можливість показати слово або речення Запи - Перегляди Просувати підсилено Цитувати @@ -46,9 +42,7 @@ Додати "у відповідь " " та " - "в каналі " Банер профілю - Успішно сплачено Помилка при обробці повідомлення про помилку " Підписок" " Підписників" @@ -63,9 +57,7 @@ Дуже дякуємо! Сума в sat Надіслати - "Не вдалося створити перегляд для %1$s : %2$s" "Перегляд для %1$s" - Новий канал Назва каналу Моя нова група URL фотографії @@ -76,35 +68,20 @@ Зберегти Створити Скасувати - Не вдалося завантажити фото - Адреса релея - Дописи - Байт Помилки - Домашня стрічка - Стрічка персональних повідомлень - Стрічка чатів - Глобальна стрічка - Пошук Додати релей Видиме ім\'я Моє видиме ім\'я Нікнейм - Мій нікнейм Про мене URL фотографії URL банеру URL сайту - LN адреса - LN URL (застарівш.) Фото збережено до галереї Не вдалося зберегти фото Завантажити фото - Завантаження… Користувач не встановив Lightning адресу для отримання чайових "відповісти.. " - Копіює ID допису для відправки - Скопіювати ID каналу (допису) Редагує метадані каналу Увійти Відомі @@ -114,16 +91,12 @@ Обговорення Дописи Відповіді - "Підписок" "Скарг" Більше опцій " Релеїв" Сайт Lightning адреса Копіює Nsec ID (ваш пароль) для резервного копіювання - Скопіювати приватний ключ - Копіює публічний ключ для відправки - Скопіювати публічний ключ (NPub) Відправити повідомлення Редагує метадані користувача Підписатися @@ -149,8 +122,6 @@ Як ми можемо до вас звертатися? Не маєте облікового запису Nostr? Вже маєте обліковий запис Nostr? - Створити новий обліковий запис - Згенерувати ключ Завантаження стрічки Завантаження облікового запису @@ -159,12 +130,6 @@ Повторити Стрічка порожня. Оновити - створив(ла) - з описом - та фото - змінив(ла) назву на - опис на - та фото на Вийти Відписатися Канал створено @@ -188,7 +153,6 @@ Лайка / Образи Повідомити про образи Повідомити про наготу / порно - інших Позначити всі відомі прочитаними Позначити всі нові прочитаними Позначити все прочитаним @@ -198,23 +162,18 @@ Помилка входу Не вдалося виконати біометрику для автентифікації власника цього телефону Не вдалося виконати біометрику для автентифікації власника цього телефону. Помилка: %1$s - Помилка - "Створено %1$s" "Картинка значка-нагороди %1$s" Ви отримали в нагороду новий значок Значок-нагороду видано Скопіювати текст ID (npub) автора скопійовано ID запису (note1) скопійовано - Виділити текст "<Не вдалося розшифрувати повідомлення>\n\n\пВас згадали в приватному/зашифрованому чаті між %1$s і %2$s." Додати акаунт Акаунти Вибір акаунта Додати акаунт Поточний акаунт - З приватним ключем - Тільки читання, без приватного ключа Назад Виділити Поділитися посиланням @@ -231,7 +190,6 @@ Видалити @string/block_only Поскаржитися - Видалити Більше не показувати @string/spam @string/profanity_hateful_speech @@ -256,29 +214,14 @@ Додати в Публічні закладки Прибрати з Особистих закладок Прибрати з Публічних закладок - Служба Wallet Connect - Дозволяє оплачувати запи за допомогою секрету, не виходячи з програми. Зберігайте секрет у безпеці та за можливості використовуйте приватний релей - Публічний ключ Wallet Connect - Релей Wallet Connect - Секрет Wallet Connect - Показати секрет - nsec / приватний ключ в hex Сума внеску в sat - Відправити опитування - Обов\'язкові поля: - Одержувачі запів - Опис опитування Варіант %s Опис варіанту - Опціональні поля: Мінімальний зап Максимальний зап Консенсус - Закриття після - днів Неможливо проголосувати Опитування закрито для нових голосів - Сума запу У цьому опитуванні можна голосувати тільки один раз "Пошук події %1$s" Додати публічне повідомлення @@ -307,27 +250,11 @@ Не-зап Без сліду в Nostr, звичайний Lightning платіж Сервер для завантаження - LnAddress або @User - Ваші релеї (NIP-95) - Файл зберігається на ваших релеях. Новий NIP: може не працювати в інших клієнтах - Налаштування Tor/Orbot - Підключення через налаштування Orbot - Від\'єднатися від вашого Orbot/Tor? - Ваші дані буде негайно перенесено у звичайну мережу Так Ні - Слідкуйте за списком Всі підписки Глобально - ## Підключіться через Tor з Orbot - \n\n1. Установіть [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Запустіть Orbot - \n3. В Orbot перевірте порт Socks. За умовчанням використовується 9050 - \n4. Якщо необхідно, змініть порт в Orbot - \n5. Налаштуйте порт Socks на цьому екрані - \n6. Натисніть кнопку «Активувати», щоб використовувати Orbot як проксі Невірний номер порту - Відключити Tor/Orbot Особисті повідомлення Сповіщення про вхідні повідомлення Запи @@ -337,19 +264,9 @@ за %1$s Сповіщення: - Долучитися до розмови - ID користувача або групи - Створити - Долучитися Сьогодні Попередження про контент Цей пост містить чутливий контент, який деякі люди можуть знайти образливим - Завжди приховувати чутливий контент - Завжди показувати чутливий контент - Завжди показувати попередження про контент - Рекомендовані: - Фільтрувати спам від незнайомців - Попереджати, коли публікації містять звіти про ваші підписки Новий символ реакції Для цього користувача не вибрано жодного типу реакції. Довге натискання на кнопку серця, щоб змінити Додає цільову суму сат, яку потрібно отримати для цієї посади. Клієнти, які підтримують, можуть відображати це як індикатор прогресу, щоб стимулювати пожертвування @@ -357,24 +274,14 @@ Версія Програмне забезпечення Підтримувані NIP - Плата за вступ Посилання на оплату Обмеження Країни Мови - Теги Політика публікації - Довжина повідомлення - Підписки - Фільтри - Довжина Id підписки Мінімальний префікс Максимальна кількість тегів події - Тривалість контенту Мінімальний PoW - Оплата - Надіслати до Zap Wallet - Токен скопійовано до буферу обміну НАЖИВО ОФЛАЙН ЗАВЕРШЕНО @@ -396,7 +303,6 @@ (translated) row titles. Marked translatable="false" so protocol terms (blossom, nsec, negentropy, …) stay searchable in every locale and aren't sent to translators. --> Завжди - Тільки через Wi-Fi Ніколи Система Світла @@ -409,21 +315,14 @@ Перегляд URL-адреси Розширена прокрутка Приховати Nav панель під час прокручування - Завантажити зображення Спам Звук вимкнено. Натисніть, щоб увімкнути звук Звук увімкнено. Натисніть, щоб вимкнути звук Пошук локальних і віддалених записів Адресу Nostr було верифіковано Перевірка адреси Nostr - Вибрати/Скасувати все За замовчуванням - Виберіть ретранслятор, щоб продовжити - Переслати Zaps до: - Підтримання клієнтів переведе його на LNAddress або профіль користувача нижче замість ваших Надати місцеперебування як - Нова функція - Активувати Тема бесіди "\@User1, @User2, @User3" Учасники цієї групи @@ -435,51 +334,33 @@ Автоматично завантажувати зображення і GIF Автоматично відтворювати відео та GIF-зображення Попередній перегляд URL - Під час завантаження зображень Скопіювати в буфер Скопіювати URL в буфер обміну Копіювати ідентифікатор нотатки в буфер обміну Створено в - Правила Увійти з Amber Оновіть свій статус - Помилка при обробці повідомлення про помилку Не вдалося надіслати файл Zap Написати користувачу ОК - Не вдалося зв’язатися з %1$s: %2$s - Не вдалося зв’язатися з %1$s: %2$s - Не вдалося обробити результат від %1$s: %2$s - %1$s помилка з кодом %2$s - Активно для: - Головна - Чати - Глобально - Пошук Знайти та додати користувача Ім\'я користувача або ім\'я для відображення Сплачено Гаманець: %1$s Помилка при відкритті додатка для входу Додаток для входу не знайдено. Перевірте чи не було видалено додаток - Заявку на вхід відхилено Приховати нове слово або речення Зображення профілю Показувати зображення профілю Вибрати опцію Не вдалося сплатити рахунок Не вдалося зняти - Не вдалося налаштувати Wallet Connect - Помилка аналізу рядка підключення NIP-47. Перевірте, чи це правильно, у вашого постачальника Wallet: %1$s. Помилка: %2$s - Помилка аналізу рядка підключення NIP-47. Перевірте, чи це правильно, у вашого постачальника Wallet: %1$s. Mint надав таке повідомлення про помилку: %1$s - Cashu токени вже витрачені. Отримано Cashu %1$s sats були відправлені в ваш гаманець. (Fees: %2$s sats) У системі не знайдено сумісний гаманець Cashu Не вдалося отримати рахунок з серверів отримувача Постачальник підключення гаманця повернув наступну помилку: %1$s - Не вдалося підключитися до Tor Це абсолютно нова одиниця, в оригінальній коробці Як нове Він використовується, але немає ознак використання @@ -501,11 +382,9 @@ Інше Не вдалося завантажити фото Не вдалося відкрити стиснутий файл - Помилка стискання медіафайлу: %1$s Помилка завантаження: %1$s Сервер не задав URL після завантаження Не вдалося завантажити завантажені медіафайли з сервера - Не вдалося підготувати локальний файл для завантаження: %1$s @@ -518,4 +397,5 @@ + diff --git a/amethyst/src/main/res/values-uk/strings.xml b/amethyst/src/main/res/values-uk/strings.xml index 3c028d4482..207e37ab8c 100644 --- a/amethyst/src/main/res/values-uk/strings.xml +++ b/amethyst/src/main/res/values-uk/strings.xml @@ -15,8 +15,6 @@ Спам Видача себе за іншу особу Незаконні дії - Невідомо - Іконка релею Невідомий автор Скопіювати текст Скопіювати ключ користувача @@ -26,7 +24,6 @@ Повідомити про спам / шахрайство Повідомити про видачу себе за іншу особу - Повідомити про відвертий вміст Повідомити про незаконні дії Увійдіть з приватним ключем щоб відповісти Увійдіть з приватним ключем щоб просувати дописи @@ -38,7 +35,6 @@ Ви використовуєте відкритий ключ, і відкриті ключі доступні лише для читання. Увійдіть за допомогою закритого ключа, щоб мати можливість приховати слово або речення Ви використовуєте відкритий ключ, і відкриті ключі доступні лише для читання. Увійдіть за допомогою закритого ключа, щоб мати можливість показати слово або речення Запи - Перегляди Просувати підсилено Цитувати @@ -46,9 +42,7 @@ Додати "у відповідь " " та " - "в каналі " Банер профілю - Успішно сплачено Помилка при обробці повідомлення про помилку " Підписок" " Підписників" @@ -63,9 +57,7 @@ Дуже дякуємо! Сума в sat Надіслати - "Не вдалося створити перегляд для %1$s : %2$s" "Перегляд для %1$s" - Новий канал Назва каналу Моя нова група URL фотографії @@ -76,35 +68,20 @@ Зберегти Створити Скасувати - Не вдалося завантажити фото - Адреса релея - Дописи - Байт Помилки - Домашня стрічка - Стрічка персональних повідомлень - Стрічка чатів - Глобальна стрічка - Пошук Додати релей Видиме ім\'я Моє видиме ім\'я Нікнейм - Мій нікнейм Про мене URL фотографії URL банеру URL сайту - LN адреса - LN URL (застарівш.) Фото збережено до галереї Не вдалося зберегти фото Завантажити фото - Завантаження… Користувач не встановив Lightning адресу для отримання чайових "відповісти.. " - Копіює ID допису для відправки - Скопіювати ID каналу (допису) Редагує метадані каналу Увійти Відомі @@ -114,16 +91,12 @@ Обговорення Дописи Відповіді - "Підписок" "Скарг" Більше опцій " Релеїв" Сайт Lightning адреса Копіює Nsec ID (ваш пароль) для резервного копіювання - Скопіювати приватний ключ - Копіює публічний ключ для відправки - Скопіювати публічний ключ (NPub) Відправити повідомлення Редагує метадані користувача Підписатися @@ -149,20 +122,12 @@ Як ми можемо до вас звертатися? Не маєте облікового запису Nostr? Вже маєте обліковий запис Nostr? - Створити новий обліковий запис - Згенерувати ключ Завантаження стрічки Завантаження облікового запису "Не вдалося завантажити відповіді: " Повторити Стрічка порожня. Оновити - створив(ла) - з описом - та фото - змінив(ла) назву на - опис на - та фото на Вийти Відписатися Канал створено @@ -186,7 +151,6 @@ Лайка / Образи Повідомити про образи Повідомити про наготу / порно - інших Позначити всі відомі прочитаними Позначити всі нові прочитаними Позначити все прочитаним @@ -196,23 +160,18 @@ Помилка входу Не вдалося виконати біометрику для автентифікації власника цього телефону Не вдалося виконати біометрику для автентифікації власника цього телефону. Помилка: %1$s - Помилка - "Створено %1$s" "Картинка значка-нагороди %1$s" Ви отримали в нагороду новий значок Значок-нагороду видано Скопіювати текст ID (npub) автора скопійовано ID запису (note1) скопійовано - Виділити текст "<Не вдалося розшифрувати повідомлення>\n\n\пВас згадали в приватному/зашифрованому чаті між %1$s і %2$s." Додати акаунт Акаунти Вибір акаунта Додати акаунт Поточний акаунт - З приватним ключем - Тільки читання, без приватного ключа Назад Виділити Поділитися посиланням @@ -229,7 +188,6 @@ Видалити @string/block_only Поскаржитися - Видалити Більше не показувати @string/spam @string/profanity_hateful_speech @@ -254,29 +212,14 @@ Додати в Публічні закладки Прибрати з Особистих закладок Прибрати з Публічних закладок - Служба Wallet Connect - Дозволяє оплачувати запи за допомогою секрету, не виходячи з програми. Зберігайте секрет у безпеці та за можливості використовуйте приватний релей - Публічний ключ Wallet Connect - Релей Wallet Connect - Секрет Wallet Connect - Показати секрет - nsec / приватний ключ в hex Сума внеску в sat - Відправити опитування - Обов\'язкові поля: - Одержувачі запів - Опис опитування Варіант %s Опис варіанту - Опціональні поля: Мінімальний зап Максимальний зап Консенсус - Закриття після - днів Неможливо проголосувати Опитування закрито для нових голосів - Сума запу У цьому опитуванні можна голосувати тільки один раз "Пошук події %1$s" Додати публічне повідомлення @@ -305,27 +248,11 @@ Не-зап Без сліду в Nostr, звичайний Lightning платіж Сервер для завантаження - LnAddress або @User - Ваші релеї (NIP-95) - Файл зберігається на ваших релеях. Новий NIP: може не працювати в інших клієнтах - Налаштування Tor/Orbot - Підключення через налаштування Orbot - Від\'єднатися від вашого Orbot/Tor? - Ваші дані буде негайно перенесено у звичайну мережу Так Ні - Слідкуйте за списком Всі підписки Глобально - ## Підключіться через Tor з Orbot - \n\n1. Установіть [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Запустіть Orbot - \n3. В Orbot перевірте порт Socks. За умовчанням використовується 9050 - \n4. Якщо необхідно, змініть порт в Orbot - \n5. Налаштуйте порт Socks на цьому екрані - \n6. Натисніть кнопку «Активувати», щоб використовувати Orbot як проксі Невірний номер порту - Відключити Tor/Orbot Особисті повідомлення Сповіщення про вхідні повідомлення Запи @@ -334,19 +261,9 @@ Від %1$s за %1$s Сповіщення: - Долучитися до розмови - ID користувача або групи - Створити - Долучитися Сьогодні Попередження про контент Цей пост містить чутливий контент, який деякі люди можуть знайти образливим - Завжди приховувати чутливий контент - Завжди показувати чутливий контент - Завжди показувати попередження про контент - Рекомендовані: - Фільтрувати спам від незнайомців - Попереджати, коли публікації містять звіти про ваші підписки Новий символ реакції Для цього користувача не вибрано жодного типу реакції. Довге натискання на кнопку серця, щоб змінити Додає цільову суму сат, яку потрібно отримати для цієї посади. Клієнти, які підтримують, можуть відображати це як індикатор прогресу, щоб стимулювати пожертвування @@ -354,24 +271,14 @@ Версія Програмне забезпечення Підтримувані NIP - Плата за вступ Посилання на оплату Обмеження Країни Мови - Теги Політика публікації - Довжина повідомлення - Підписки - Фільтри - Довжина Id підписки Мінімальний префікс Максимальна кількість тегів події - Тривалість контенту Мінімальний PoW - Оплата - Надіслати до Zap Wallet - Токен скопійовано до буферу обміну НАЖИВО ОФЛАЙН ЗАВЕРШЕНО @@ -389,7 +296,6 @@ Додає попередження про чутливий контент перед показом цього контенту Налаштування Завжди - Тільки через Wi-Fi Ніколи Система Світла @@ -402,21 +308,14 @@ Перегляд URL-адреси Розширена прокрутка Приховати Nav панель під час прокручування - Завантажити зображення Спам Звук вимкнено. Натисніть, щоб увімкнути звук Звук увімкнено. Натисніть, щоб вимкнути звук Пошук локальних і віддалених записів Адресу Nostr було верифіковано Перевірка адреси Nostr - Вибрати/Скасувати все За замовчуванням - Виберіть ретранслятор, щоб продовжити - Переслати Zaps до: - Підтримання клієнтів переведе його на LNAddress або профіль користувача нижче замість ваших Надати місцеперебування як - Нова функція - Активувати Тема бесіди "\@User1, @User2, @User3" Учасники цієї групи @@ -428,51 +327,33 @@ Автоматично завантажувати зображення і GIF Автоматично відтворювати відео та GIF-зображення Попередній перегляд URL - Під час завантаження зображень Скопіювати в буфер Скопіювати URL в буфер обміну Копіювати ідентифікатор нотатки в буфер обміну Створено в - Правила Увійти з Amber Оновіть свій статус - Помилка при обробці повідомлення про помилку Не вдалося надіслати файл Zap Написати користувачу ОК - Не вдалося зв’язатися з %1$s: %2$s - Не вдалося зв’язатися з %1$s: %2$s - Не вдалося обробити результат від %1$s: %2$s - %1$s помилка з кодом %2$s - Активно для: - Головна - Чати - Глобально - Пошук Знайти та додати користувача Ім\'я користувача або ім\'я для відображення Сплачено Гаманець: %1$s Помилка при відкритті додатка для входу Додаток для входу не знайдено. Перевірте чи не було видалено додаток - Заявку на вхід відхилено Приховати нове слово або речення Зображення профілю Показувати зображення профілю Вибрати опцію Не вдалося сплатити рахунок Не вдалося зняти - Не вдалося налаштувати Wallet Connect - Помилка аналізу рядка підключення NIP-47. Перевірте, чи це правильно, у вашого постачальника Wallet: %1$s. Помилка: %2$s - Помилка аналізу рядка підключення NIP-47. Перевірте, чи це правильно, у вашого постачальника Wallet: %1$s. Mint надав таке повідомлення про помилку: %1$s - Cashu токени вже витрачені. Отримано Cashu %1$s sats були відправлені в ваш гаманець. (Fees: %2$s sats) У системі не знайдено сумісний гаманець Cashu Не вдалося отримати рахунок з серверів отримувача Постачальник підключення гаманця повернув наступну помилку: %1$s - Не вдалося підключитися до Tor Це абсолютно нова одиниця, в оригінальній коробці Як нове Він використовується, але немає ознак використання @@ -494,9 +375,7 @@ Інше Не вдалося завантажити фото Не вдалося відкрити стиснутий файл - Помилка стискання медіафайлу: %1$s Помилка завантаження: %1$s Сервер не задав URL після завантаження Не вдалося завантажити завантажені медіафайли з сервера - Не вдалося підготувати локальний файл для завантаження: %1$s diff --git a/amethyst/src/main/res/values-uz-rUZ/strings.xml b/amethyst/src/main/res/values-uz-rUZ/strings.xml index fa9301804a..71e7c05d2a 100644 --- a/amethyst/src/main/res/values-uz-rUZ/strings.xml +++ b/amethyst/src/main/res/values-uz-rUZ/strings.xml @@ -22,8 +22,6 @@ Boshqa sabab Ta’qib Zo\'ravon - Noma\'lum - Relay belgisi Nomaʼlum muallif Matnni nusxalash Muallif identifikatorini nusxalash @@ -37,12 +35,9 @@ Spam / Firibgarlik deb bildirish Soxta profilni bildirish - Uyatsiz kontentni bildirish Noqonuniy xatti-harakatni bildirish Zararli dasturni bildirish - Moderatorga shikoyat qilish Zararli dastur - Moderator Sizda ommaviy kalit faol. Ommaviy kalitlar orqali faqat o‘qish mumkin. Xabar yozish uchun, maxfiy kalit bilan avtorizatsiyadan o‘ting Sizda ommaviy kalit faol. Ommaviy kalitlar orqali faqat o‘qish mumkin. Postni targ‘ib qilish uchun, maxfiy kalit bilan avtorizatsiyadan o‘ting Sizda ommaviy kalit faol. Ommaviy kalitlar orqali faqat o‘qish mumkin. Postga reaksiya qilish uchun, maxfiy kalit bilan avtorizatsiyadan o‘ting @@ -54,7 +49,6 @@ Imzolovchi ilova topilmadi Imzolovchi ilova oʻchirib tashlandimi? Imzolovchi oʻrnatilganligini va ushbu hisobga ega ekanligini tekshiring. Agar imzolovchi ilova oʻzgargan boʻlsa, tizimdan chiqing va qayta kiring. Zeplar - Koʻrishlar soni Targʻib qilish Targ\'ib qilidi Tahrirlangan @@ -66,7 +60,6 @@ Qo\'shish "Kimga javob yozilmoqda: " " va " - "bu kanalda: " Profil banneri @@ -87,4 +80,5 @@ + diff --git a/amethyst/src/main/res/values-vi-rVN/strings.xml b/amethyst/src/main/res/values-vi-rVN/strings.xml index 95b9b7c2a0..e5e7ebc720 100644 --- a/amethyst/src/main/res/values-vi-rVN/strings.xml +++ b/amethyst/src/main/res/values-vi-rVN/strings.xml @@ -2,12 +2,9 @@ Hình ảnh nhóm Hành vi trái pháp luật - Không xác định Yêu cầu xóa - Lượt xem Thêm " và " - Thanh toán thành công Thanh toán Lưu ý cho người nhận Cảm ơn rất nhiều! @@ -30,4 +27,5 @@ + diff --git a/amethyst/src/main/res/values-zh-rCN/strings.xml b/amethyst/src/main/res/values-zh-rCN/strings.xml index 1594c06156..fe7b28ff70 100644 --- a/amethyst/src/main/res/values-zh-rCN/strings.xml +++ b/amethyst/src/main/res/values-zh-rCN/strings.xml @@ -33,8 +33,6 @@ 其它 骚扰行为 暴力 - 未知 - 中继器图标 未知作者 复制文本 复制作者公钥 ID @@ -49,12 +47,9 @@ 举报垃圾邮件/诈骗 举报冒充 - 举报露骨内容 举报非法行为 举报恶意软件 - 举报 Mod 恶意软件 - Mod 你正在使用公钥,公钥是只读的。使用私钥登录以便回复 你正在使用公钥,公钥是只读的。使用私钥登录以便提升帖子 你正在使用公钥,公钥是只读的。使用私钥登录以点赞帖子 @@ -68,17 +63,14 @@ 你正在使用公钥,公钥是只读的。使用私钥登录以便能够取消关注 你正在使用公钥,公钥是只读的。使用私钥登录以便能够隐藏单词或句子 你正在使用公钥,公钥是只读的。使用私钥登录以便能够显示单词或句子 - 您正在使用公钥以只读方式登录,需要使用私钥登录才能更改设置。 您正在使用公钥以只读方式登录,需要使用私钥登录才能上传。 您正在使用公钥以只读方式登录,需要使用私钥登录才能签署事件。 未授权的解密 签名器没有授权解密操作,请在签名器中授予 NIP-44 解密权限并重试。 未找到签名器 签名器被卸载?请检查是否已经安装了签名器以及其中是否存在该账户。变更签名器需要注销后重新登录。 - 签名器行为异常 外部签名器对该请求返回了不正常的载荷。这可能是 Amethyst 或签名器上的错误。 打闪 - 浏览次数 提升 已提升 已编辑 @@ -91,9 +83,7 @@ 添加 "回复 " " 和 " - "在频道 " 个人档案横幅 - 付款成功 解析错误信息时出错 " 关注" " 粉丝" @@ -166,7 +156,6 @@ 收款人接受的铸币厂中余额不足。请先充值您的 Cashu 钱包。 可为该收款人支付的金额:%1$s sats 网络费用 - 你的钱包应用 交易: %1$s Lightning 小费 给收款方的留言 @@ -180,16 +169,13 @@ 可见前缀 😎 添加到帖子 - "解析 %1$s 预览出错:%2$s" "预览 %1$s 卡片图片" 文章 - 新频道 频道名 我的精彩群聊 图片链接 图片Url(可选) 描述 - 未找到描述 "关于我们.. " 你在想什么? 写一条消息… @@ -199,42 +185,25 @@ 创建 重命名 取消 - 上传图片失败 - 中继器地址 - 帖文 - 字节 错误 错误 中继成功连接的百分比 - 该会话中产生的连接错误数量 - 主页 - 私信 - 公开聊天 - 全球 - 搜索 搜索并添加用户 - 添加用户 添加中继器 - 名称 - 名称 (用于 @ 标记时显示) 我的 @ 名称 显示名称 我的显示名称 Nostr 太酷了 欢迎! 用户名 - 我的用户名 关于我 头像链接 横幅链接 网站链接 称谓代词 - 闪电地址 - LN链接(过期) 源中继可能陈旧 陈旧中继警告 保存到手机 - 保存到相册 图片已保存到相册 视频下载已开始… 媒体下载已开始… @@ -250,16 +219,14 @@ 上传文件 拍照 录制视频 + 此设备上没有找到相机应用 录制消息 - 录制消息 点按以录制消息 重新录制 正在录制 正在录制 %1$s - 上传中… 上传出错 上传语音消息失败 - 未知的上传状态 语音消息尚不支持 NIP-95 语音上传失败:%1$s 无 @@ -271,8 +238,6 @@ 用户尚未设置闪电地址以接收聪 "🔏在此回复… " 在此聊天中 - 复制笔记ID到剪贴板以便于在 Nostr 中分享 - 复制频道ID(笔记)到剪贴板 修改频道元数据 加入 私聊 @@ -286,7 +251,6 @@ 回复 互动 相册 - "关注" "举报" "%1$s 举报" 更多选项 @@ -294,11 +258,8 @@ 网站 闪电地址 复制 Nsec ID(您的私人密钥)到剪贴板以备备份 - 复制私钥到剪贴板 显示私钥二维码 显示加密私钥二维码 - 复制公钥到剪贴板以供共享 - 复制公钥(NPub)到剪贴板 发送直接消息 编辑用户元数据 关注 @@ -327,8 +288,6 @@ 我们应该如何称呼你? 还没有 Nostr 帐户? 已经有 Nostr 帐户? - 创建新帐户 - 生成新密钥 正在加载 正在载入帐户 已加密 @@ -344,13 +303,7 @@ 开放投票 信息流为空。 刷新 - 创建 - 描述为 - 并上传图片 - 将聊天名称修改为 新的聊天资料: - 描述更改为 - 图片更改为 离开 取关 频道已创建 @@ -387,7 +340,6 @@ Nostr 地址 从不 现在 - 秒 时 分 天 @@ -395,7 +347,6 @@ 不文雅的言辞 / 敌意言论 举报敌意言论 举报裸体 / 情色内容 - 其他 将所有已知内容标记为已读 将所有新内容标记为已读 将所有内容标记为已读 @@ -416,8 +367,6 @@ 身份验证失败 生物计未能验证此手机的所有者 生物计未能验证此手机的所有者。错误:%1$s - 错误 - "由 %1$s 创建" "颁发给 %1$s 的徽章图片" \"徽章图片 你收到了新的徽章奖励 @@ -425,7 +374,6 @@ 文本已复制到剪贴板 已复制作者公钥 ID 到剪贴板 已复制笔记ID (@note1) 到剪贴板 - 选择文本 "<无法解密私密消息>\n\n;你被 %1$s 和 %2$s 之间的私人/加密会话引用。" 添加新账户 账户 @@ -437,8 +385,6 @@ 选择账户 添加新账户 活跃账户 - 具有私钥 - 只读,无私钥 返回 选择 分享浏览网址 @@ -463,14 +409,12 @@ 主题帖静音 取消主题帖静音 举报 - 删除 不再次显示 垃圾信息或诈骗 不文明用语或仇恨行为 恶意冒充 暴露裸露或恶心内容 违规行为 - 恶意软件 屏蔽一位用户将会在你的应用中隐藏他的内容。你的笔记仍然是公开可见的,包括对被你屏蔽的用户。屏蔽的用户将会被列在安全过滤器屏幕上。 违规报告 @@ -498,7 +442,6 @@ 选择计划时间 选择计划项目… 在 %1$s 内发布 - %1$s 前到期 时间 定时帖 取消时间安排 @@ -568,7 +511,6 @@ 作者 请求 批准 - 没有社区匹配此过滤器。 可验证规则 (可选) 和社区一起发布机器可读的规则文档 (NIP-9B) 。支持它的客户端在发送之前阻止不匹配的帖子。 允许的事件类型 @@ -597,26 +539,15 @@ 添加信任网络(WoT)网关 全局最大事件大小(可选) 字节 \u2014 留空无全限制。 - 已收到 - 我的 - 授予的 - 发现 新徽章 - 编辑徽章 授予徽章 接受 拒绝 从个人资料中删除 - 徽章 ID (d-tag) - 勇敢,贡献者-2025… 名称 人类可读徽章名称 描述 为什么授予这个徽章? - 图像 URL (1024×1024) - https://example.com/badge.png - 缩略图 URL (可选) - https://example.com/badge-thumb.png 上传图像 选择一个方形图像作为您的徽章的正面。 加载徽章… @@ -625,7 +556,6 @@ 删除 无标题徽章 授予了 %1$d - 您收到了一个徽章 个人资料徽章 徽章 · %1$d 选择要在个人资料中显示的已收到的徽章。 @@ -636,6 +566,9 @@ 推荐的应用 选择您公开推荐的Nostr应用。建议显示在您的个人资料上,并帮助他人发现此客户端无法打开的内容。 尚未找到应用。应用在您的中继上被发现时会出现在这里。 + 按名称搜索应用 + 没有匹配您搜索的应用。 + 没有推荐应用匹配此过滤器。 未命名应用 不宣布它处理的内容 推荐 @@ -664,6 +597,8 @@ 集 重复 体重 + 练习 + 量 备注 小时 分钟 @@ -671,12 +606,7 @@ 分享锻炼 让 Ameyst 从 Health Connect (Samsung Health, Google Fit, Fitbit, Garmin…) 读取完成的锻炼并建议一个帖子。 连接 - 检测到新锻炼 - 分享 - 忽略 %1$s 公里 - %1$s bpm - %1$s 千卡 来自 Health Connect 跑步 步行 @@ -689,8 +619,10 @@ 冥想 饮食 节食 + 循环训练 + EMOM + AMRAP 应用 - 应用 来源: %1$s v%1$s 下载 @@ -699,12 +631,10 @@ 主题 链接 最新发布 - 评论 成为第一个评论者。 方 显示旧版本 隐藏旧版本 - 日历 短视频 公共聊天 关注包 @@ -714,18 +644,14 @@ 一个语音聊天室 阶段 正等待演讲者… - 观众 举手 放下手 连接音频 - 断开连接 静音 取消静音 - 正在连接… 正在解析房间 正在打开传输 正在协商音频 - 音频已连接 重新连接中… 听录音 无法发送信息 @@ -733,9 +659,7 @@ 关闭这个聊天室吗? 所有参与者将被断开连接。该房间会在源中显示为已关闭的。 关闭聊天室 - 选择未来的开始时间。 音频失败: %1$s - 此聊天室没有音频可用 交谈 离开舞台 麦克风静音 @@ -743,7 +667,6 @@ 上线中… 广播失败: %1$s 未能降低音量:%1$s - 在这个房间进行交谈需要麦克风权限。 打开设置 语音聊天房 当聊天室开放时保持音频播放。 @@ -754,7 +677,6 @@ 加入语音聊天室 主持人 打开 - 最近聊天 聊天室里目前没人。 %1$d 人正在听 主持人 @@ -781,8 +703,6 @@ 观众 手 尚无观众。 - 发送 - 说些什么… 还没有消息。成为第一个说话的。 回应 编辑聊天室 @@ -816,7 +736,6 @@ 操作失败 无法准备该操作。 分享聊天室 - 最小化 最小化以继续收听 音频已断开 正在加载聊天室… @@ -849,7 +768,6 @@ 选择 Amethyst 将你的语音聊天室发布到哪些 MoQ 主机服务器。启动新空间时第一个条目将用作默认。 您的服务器 保存为 10112 类型的可替换事件,以便其他客户端可以读取您的首选项。 - 添加语音聊天服务器 中继 (WebTransport) URL 认证(JWT mint) URL 添加 @@ -862,13 +780,11 @@ 移除服务器 暂无语音聊天服务器。在下方添加一个或选择推荐服务器。 视频 - 文章 音乐 播放列表 节目 播客 查看节目 - 节目 尚未发现节目 %1$d 期节目 @@ -879,9 +795,6 @@ 歌曲名 艺人 艺人姓名 - 音频URL - https://… .mp3 - 封面图片URL (可选) 专辑(可选) 持续时间以秒为单位 (可选) 歌词或作词人 (可选) @@ -891,7 +804,6 @@ 添加到播放列表 您尚未有任何播放列表。使用上面的字段创建一个播放列表。 管理所有播放列表 - 新建播放列表 播放列表名称 创建 (无标题播放列表) @@ -926,9 +838,6 @@ 删除书签列表 查看帖子 查看文章 - 查看链接 - 查看话题标签 - 您还没有任何书签列表。轻按下面的新建按钮制作一个。 兴趣集 您还没有任何兴趣集。轻按下面的新建按钮制作一个。 新的兴趣集 @@ -947,7 +856,6 @@ 私密帖子(%1$s) 公开帖子 公开帖子(%1$s) - 私密文章 私密文章(%1$s) 公开文章 公开文章(%1$s) @@ -974,16 +882,6 @@ 书签列表元数据可以被Nostr上的任何人看到。只有您的私密成员是加密的。 移动到公开 移动到私密 - 钱包绑定服务 - 允许在不离开应用的情况下使用 Nostr 私钥支付打闪。请确保私钥安全;如有可能,请使用一个私人中继。 - 钱包绑定公钥 - 钱包绑定中继 - 钱包绑定私钥 - 显示私钥 - nsec / 十六进制私钥 - 已连接 - 未连接 - 高级:手动输入连接详情 快速打闪金额 按下 zap 按钮时显示。 每笔款项都可以通过收款人支持的任何方式支付——闪电、Cashu或链上(链上只用于较大数额)。 点击一个金额来删除它。如果留空,它将每次打开对话框插入一个金额。 在链上发送 @@ -1015,14 +913,8 @@ 连接钱包 查看中继源 承诺聪金额 - 发布投票 - 必填字段: - 打闪接收方 - 投票主要说明… - 选项 选项 %s 投票选项说明 - 可选字段: 打闪最低金额 打闪最高金额 共识 @@ -1031,11 +923,8 @@ 多选 投票结束日期 & 时间 投票结束于 %1$s - 后关闭 - 天 无法投票 该投票已结束 - 打闪金额 这种投票只允许每个用户一票 "正在查找事件 %1$s" 发送打闪 @@ -1071,11 +960,8 @@ 非打闪 Nostr 上没有痕迹,仅在闪电上 匿名 - 使用新的一次性身份发帖。您的帐户将不会被链接到这个回复。 - 此回复将从新的匿名身份发布 文件服务器 选择上传文件时使用的服务器 - 闪电地址或 @User 媒体服务器 设置首选媒体上传服务器。 使用本地Blossom 缓存 @@ -1084,10 +970,8 @@ 端口2442未检测到本地缓存。 仅缓存个人资料图片 限制本地缓存到个人资料图片。源图片和视频将直接从原始服务器获取。 - 尚未设置 NIP-96 服务器。可以使用默认的内置服务器列表或自行添加 ↓ 尚未设置 Blossom 服务器。可以使用默认的内置服务器列表或自行添加 ↓ 推荐的媒体服务器 - 内置媒体服务器 Amethyst 的默认列表。可单独添加或添加整个列表。 使用默认列表 添加媒体服务器 @@ -1110,38 +994,21 @@ 正在计算 Hash 完成 错误 - 你的中继器 (NIP-95) - 文件由你的中继器托管。新的 NIP:检查它们是否支持 隐私选项 - Tor/Orbot 设置 - 通过你的 Orbot 设置连接 调整 Tor 设置 - 断开与你的 Orbot/Tor 连接? - 你的数据将立即在普通网络上传输 是 否 - 关注列表 所有关注 所有用户关注 默认关注列表 - 通过代理关注 周围的人 全球 精选 - 国际象棋 我的 静音列表 关注集 这些是为您自己使用设计的关注列表。您可以私下或公开关注用户 - 有标签的书签 - 常规书签 - 公开 - 私密 - 混合 - 似乎你还没有任何关注集。 - \n轻按下方刷新,或者轻按“+”按钮新建一个。 - 新建 添加作者到关注列表 从列表中添加或删除用户,或用此用户创建一个新列表。 @@ -1150,23 +1017,9 @@ %1$s 是私密成员 添加为公开成员 添加为私密成员 - 公开成员 - 私密成员 - 公开的个人资料 - 私密配置文件 - 成员 - 成员 - 无成员 空 - 此列表中没有 %1$s %1$s 不是成员 您的列表和 %1$s - 您的关注集 - 未找到关注集,或者你还没有任何关注集。轻按下方刷新,或使用按钮新建。 - 获取时出了问题: %1$s - 新建列表 - 创建用户新的 %1$s 列表 - 创建 %1$s 关注集,并添加 %2$s 到其中。 新建关注列表 新的关注包 复制/克隆关注集 @@ -1186,14 +1039,6 @@ 正将集合名称从 改为 默认端口为 9050 - ## 通过 Orbot 连线 Tor - \n\n1. 安装 [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. 开启 Orbot - \n3. 在 Orbot 中检查 Socks 端口。默认使用9050 - \n4. 如果需要,在 Orbot 中更改端口 - \n5. 在此屏幕中配置 Socks 端口 - \n6. 按“启用”按钮以使用 Orbot 作为代理 - Orbot Socks 端口 启动 Tor 使用内置 Tor 或者 Orbot @@ -1235,8 +1080,6 @@ 为所有连接隐藏 IP 让你自己来设置 无效端口 - 使用 Orbot - 断开 Tor/Orbot 连接 私信 收到私信时通知你 收到打闪 @@ -1293,12 +1136,8 @@ 蓝牙 语音通话 视频通话 - 等待其他人加入\u2026 添加参与者 搜索用户\u2026 - 未能开始通话 - 未能接受通话 - 创建通话会话失败 需要权限 Amethyst 需要麦克风权限来开始语音通话。请在应用程序设置中启用它。 Amethyst需要摄像头和麦克风访问权限来开始视频通话。请在应用程序设置中启用它们。 @@ -1332,30 +1171,21 @@ 保持与收件箱中继的持续连接以便即时发送通知。 显示正在进行的通知。使用更多电量,但确保您永远不会错过消息。 根据关注拆分通知 显示两个通知选项卡 — — 关注(你关注的人) 和所有人。未读的指示器只为你关注的人的活动发出微光。 + 显示消息 + 在通知选项卡上包含私信和群消息。如关闭只在消息选项卡中保留消息。 关注 所有人 电池优化已启用 Android 可能会限制后台中继连接。禁用针对Amethyst电池优化以确保可靠的通知。 立即修复 通知: - 加入对话 - 用户或群组 ID - npub、nevent 或 hex - 创建 - 加入 今天 内容警告 警告: %1$s 这个帖子包含敏感内容,一些人可能会觉得有冒犯性或令人不安 - 始终隐藏敏感内容 - 始终显示敏感内容 - 始终显示内容警告 隐藏 显示 警告 - 推荐: - 过滤来自陌生人的垃圾信息 - 当帖子有你的关注的报告时警告 过滤垃圾信息 隐藏陌生人的五次或五次以上完全相同的帖子 将客户端标签添加到我的事件 @@ -1387,22 +1217,17 @@ 向该中继发送事件和过滤请求所使用的数据量 从该中继接收事件和过滤响应所使用的数据量 已保存的事件 - 尝试从 %1$s 获取中继器信息时出错 机主 使用者 服务密钥 - 正在运行 %1$s - 正在运行 %1$s (%2$s) 版本 软件 联络 支持的 NIPs 支持 Grasps - 接纳费 接纳 订阅 发布 - 付款 %1$s 付款网址 目标受众 策略 & 链接 @@ -1410,7 +1235,6 @@ 限制 国家 语言 - 标签 话题 所有国家和地区 所有语言 @@ -1425,64 +1249,48 @@ 打开 读取 写入 - RTT 网络 类型 支持的 NIPs 要求 - 上次检查 %1$d 毫秒 接受的类型 位置信息 活跃订阅 - 待处理发件箱事件 请求订阅(%1$d) 计算订数 (%1$d) 发件箱事件(%1$d) - 此中继没有活动订阅 %1$d 位作者 %1$d 个 id 自 %1$s 直到 %1$s 限制 %1$d - 消息长度 - 订阅 - 筛选器 - 订阅 ID 长度 最少前缀 最多事件标签 - 内容长度 最大内容长度 丢弃旧于 最多接受 未来 %1$s %1$s 之前 - %1$s 整 %1$s 位 事件保留 内容大小 连通性 访问控制 最低工作量证明 - 认证 需要认证 - 支付 需要付费 最大消息长度 最大订阅连接数 最多订阅过滤器 最大数量(返回事件) - 默认限制(返回事件) 最大 SubID 长度 Cashu 代币 铸币厂:%1$s 兑换 - 发送到打闪钱包 - 在 Cashu 钱包中打开 复制令牌 在另一个应用中打开 未设置闪电地址 - 已将代币复制至剪贴板 直播 离线 已结束 @@ -1533,7 +1341,6 @@ Marmot 状态重置。 重置 Marmot 状态失败: %1$s 始终 - 仅限 WiFi 未计量的 WiFi 从不 完整版 @@ -1558,7 +1365,6 @@ 选择帖子样式 资料页图库样式 选择图库样式 - 加载图像 垃圾邮件 静音。点击取消静音 声音开启。点击静音 @@ -1570,18 +1376,13 @@ Nostr 地址已验证 Nostr 地址验证失败 正在检查 Nostr 地址 - 全部选择/取消选择 默认 重设为默认值 - 选择中继器以继续 - 将打闪转发到: - 支持的客户端会将打闪转发到以下的闪电地址或用户个人档案,而不是你的 将位置显示为 将你所在位置的地理位置添加到帖子。公众会知道你在当前位置的5公里之内(3英里) 位置限定帖子 只有处于同一地理位置的关注者才能看到贴帖子。一般关注者无法看到。 话题限定帖 - 只有关注了话题的人才能看到帖子,您的普通关注者无法看到。 评论网站 评论外部资源 需 %1$d 分钟读完 @@ -1600,9 +1401,7 @@ 上传音频文件 选择 MP3, WAV 或 FLAC。保存时它将被上传到媒体服务器。 已准备好上传音频文件 - 上传中… 正砸上传封面 + 音频和发布。即使您离开屏幕,这也会继续进行。 - 上传失败: %1$s 编辑播放列表 编辑播放列表 标题 @@ -1623,13 +1422,9 @@ 没有位置信息权限 在显示你的内容之前添加敏感的内容警告。针对任何 NSFW 内容或一些人可能觉得有冒犯性或令人不安的内容。 原因 (可选) - 新功能 - 启用此模式需要 Amethyst 发送一条 NIP-17 消息(包装的、密封的私信和群聊消息)。因为 NIP-17 是新的,大多数客户端尚未执行。请确保接收方正在使用兼容的客户端。 - 启用 公开 组 新建公开或私人群组 - 中继 私人 至 主题 @@ -1641,9 +1436,6 @@ 对成员的解释 为新目标更改名称。 粘贴自剪贴板 - 无效的 NIP-47 URI - URI %1$s 不是有效的 NIP-47 登录 URI。 - 连接到新的 NWC 钱包 未找到钱包 Amethyst 找不到任何支持 Nostr Wallet Connect (NWC) 的钱包应用. \n\n你可以做的事情: @@ -1660,7 +1452,6 @@ 自动播放视频和 GIF 视频在屏幕上可见时自动播放视频 显示 URL 预览 - 何时加载图像 复制 Stack 复制到剪贴板 已复制到剪贴板 @@ -1676,43 +1467,21 @@ 媒体已添加 媒体已添加到个人资料相册中 创建于 - 规则 - 关于我们 指南 审核者 使用 Amber 登录 更新你的状态 - 错误解析错误消息 投票按照打闪金额进行加权。 你可以设置最小金额以避免垃圾邮件,也可以设置最大金额以避免大型攻击者攻击民意调查。在两个字段中使用相同的金额以确保每张投票的价值相同。 留空即可接受任何金额。 无法发送打闪 向用户发送消息 向 %1$s 发消息 好 - 无法连接 %1$s: %2$s - 组合 %1$s 的 NIP-11 URL 失败: %2$s - 无法连接 %1$s: %2$s - 无法解析来自 %1$s 的响应: %2$s - 中继拒绝请求 %1$s: %2$s - 无法连接 %1$s: %2$s - 无法解析来自 %1$s的结果: %2$s - %1$s 失败,代码 %2$s - 活跃于: - 主页 - 私信 - 聊天 - 全球 - 搜索 拆分及转发打闪 支持的客户端将会把打闪拆分及转发到在这里添加的用户,而不是你的 搜索并添加用户 用户名或显示名 打闪设置缺失 用户 %1$s 尚未设置接收聪的闪电地址 - 百分比 - 25 - 与此用户拆分打闪 - 将打闪转发到 - 找不到闪电钱包 已支付 钱包 %1$s 打开签名应用时出错 @@ -1721,7 +1490,6 @@ 此设备不支持该编解码器或格式(%1$s)。请尝试在您的浏览器中打开它。 在浏览器中打开 签名请求已被拒绝 - 签名请求被拒绝了 请确保签名应用程序已授权此交易 找不到支付闪电发票的钱包(错误:%1$s)。请安装闪电钱包来使用打闪 找不到支付闪电发票的钱包。请安装闪电钱包来使用打闪 @@ -1737,40 +1505,23 @@ 选择一个选项 不能生成支付发票 无法提款 - 无法设置钱包连接 - 解析 NIP-47 连接字符串时出错。请与你的钱包提供商检查这是否正确: %1$s。错误:%2$s - 解析 NIP-47 连接字符串时出错。请与你的钱包提供商检查这是否正确: %1$s。 无法兑换 Cashu 铸币厂提供了以下错误信息: %1$s - Cashu 代币已花费。 已收到 Cashu %1$s 聪已被发送到你的钱包。(费用︰ %2$s 聪) 系统上没有找到兼容的 Cashu 钱包 无法从接收方的服务器获取发票 你的钱包连接提供者返回了以下错误: %1$s - 无法连接到 Tor Tor 未连接 Amethyst 无法完成引导 Tor。 使用常规(非Tor)连接以便加载源吗?我们会记住该选择一个小时,并在这之后重试Tor连接。 使用常规连接 继续等待 - 无法下载中继文件 无法从闪电地址集合LNURL\"%1$s\"。请检查用户设置 - %1$s 的接收者闪电服务不可用。它是根据雷电地址\"%2$s\"计算的。 错误: %3$s。请检查服务器是否已经上线,闪电地址是否正确 - 无法解析 %1$s。请检查你是否已连接,服务器是否启动,以及闪电地址 %2$s 是否正确 - 无法解析 %1$s。请检查你是否已连接,服务器是否启动,以及闪电地址 %2$s 是否正确。\n\n异常为:%3$s - 无法从 %1$s 获取发票 无法从 %1$s 获取发票:%2$s - 从闪电地址解析JSON出错。请检查用户的打闪设置 从 %1$s 解析 JSON 发生错误。请检查用户的闪电设置 - 在用户闪电地址服务器配置中找不到回调URL 从 %1$s 的响应中找不到回调 URL - 从闪电地址的发票获取解析JSON 发生错误。请检查用户的闪电设置 - 从 %1$s 的闪电发票获取解析JSON 发生错误。请检查用户的闪电设置 来自 %2$s 的错误的发票金额(%1$s 聪)。它本应该是 %3$s 无法在发送打闪前创建闪电发票。接收者闪电钱包发送了以下错误: %1$s - 无法创建闪电发票。来自 %1$s 的消息:%2$s - 无法在发送打闪前创建闪电发票。在生成的 JSON 中找不到 Element pr。 - 无法从 %1$s 创建闪电发票:在生成的 JSON 中找不到付款要求元素。 仅读用户 没有设置回应 通知 @@ -1796,13 +1547,11 @@ 向卖方发送消息 嗨,%1$s,这个还能买到吗? 你好,这个还能买到吗? - 出售物品 标题 iPhone 13 条件 分类 价格(聪) - 1000 地点 市,省,国家 全新 @@ -1831,20 +1580,13 @@ 其它 无法上传媒体 无法打开压缩文件 - 压缩媒体时出错:%1$s 上传错误:%1$s 上传后服务器没有提供 URL 无法从服务器下载上传的媒体 无法检查经过上传后再下载的文件:%1$s - 无法准备要上传的本地文件:%1$s 无法上传到%1$s:%2$s - 上传失败:%1$s 删除失败:%1$s 文件过大,无法使用 NIP-95 - 无法加载缩略图 - 无法准备头部信息:%1$s - 压缩已取消 - 压缩返回的文件失败 加密文件 上传前为了隐私加密文件。有些服务器可能不接受免费账户的加密文件。 加密上传失败 @@ -1871,27 +1613,18 @@ 无法从 AVIF 删除元数据: %1$s 编辑草稿 使用二维码登录 - 路径 主页 - 搜索 发现 消息 通知 - 全球 短篇 - 图片 - 锻炼 日历 日历列表 国际象棋 钱包 - 余额 发送 接收 交易 - 未连接钱包 - 在打闪设置中设置Nostr Wallet Connect (NWC) 连接以使用钱包。 - 设置钱包 聪 粘贴 BOLT-11 发票 付款 @@ -1919,8 +1652,6 @@ 这将删除钱包连接。您可以之后添加回来。 钱包名称 我的钱包 - 您的钱包 - 管理钱包 未连接钱包 连接一个或多个NWC钱包来发送和接收付款。 添加 NWC 连接 @@ -1940,12 +1671,9 @@ 移除铸币厂 添加铸币厂 历史记录 - 编辑钱包 Nutzap 密钥(高级) 一枚单独的私钥仅用于接收NIP-61 nutzaps。不是您的 Nostr 身份密钥。 生成新密钥 - 会使得锁定到当前密钥的任何 nutzaps 失效。 - 保留当前密钥 P2PK 私钥(十六进制) 编辑铸币厂 保存更改 @@ -1959,7 +1687,6 @@ 热门铸币厂 匹配的铸币厂 - 推荐这个铸币厂 接收 发送 LN 发送代币 @@ -2040,10 +1767,6 @@ 保存 重命名 重命名钱包 - 编辑 - 无效的 NWC 连接 URI - 上移 - 下移 链上交易 此账户没有链上地址可用。 没有配置链后端。 @@ -2113,17 +1836,13 @@ 付款已发送(已发布 %1$d 份收据,共 %2$d 份),但下一收据无法发布 - 安全滤镜 导入关注 新帖子 新短篇媒体:图像或视频 新社区笔记 新产品 - 新建地理位置限定帖文 新文章 新投票 - 新打闪投票 - 新常规投票 新图片 新建日历活动 编辑日历活动 @@ -2138,8 +1857,6 @@ 日 未开始 已结束 - 您选择的源尚无即将到来或过往的日历事件。 - 暂无日历集合。 您的日历为空 您关注的人分享的活动出现在这里。点击 + 按钮来创建您自己的事件。 尚无集合 @@ -2166,8 +1883,6 @@ 下周 昨天 次日 - 此日无活动 - 无活动 继续 第 %1$d 天,共 %2$d 天 添加到手机日历 @@ -2224,7 +1939,6 @@ 选中的图像无法上传。请重试或粘贴一个URL。 参与者 (%1$d) 搜索名称, npub, 或 nip-05 - 输入有效的 npub… 或 64个字符的十六进制公钥。 移除参与者 日历提醒 发送提醒 @@ -2244,10 +1958,7 @@ 活动详情 新短视频 新长视频 - 标题 摘要(选填) - 封面图片URL (可选) - 用 markdown 格式撰写文章… 预览 编辑 添加标题图片 @@ -2331,18 +2042,14 @@ 中继器 %1$s 展开中继列表 笔记选项 - 中继列表选择器 投票 停用投票 比特币发票 取消比特币发票 - 取消出售物品 打闪筹款方 取消 Zapraiser 地点 移除地点 - 打闪拆分 - 取消打闪拆分 添加内容警告 移除内容警告 添加过期日期 @@ -2357,11 +2064,8 @@ 地址无效 Amethyst 收到了要打开的 URI,但该 uri 无效:%1$s 私信收件箱中继 - 中继:%1$s - 使用常规中继 设置你的私人收件箱中继 该设置可以让所有人知道向您发送消息时应该使用的中继。如果没有的话,您可能会错过一些消息。 - 示例:\n - inbox.nostr.wine (付费)\n - you.nostr1.com (个人专用中继 - 付费) 示例:\n - auth.nostr1.com (免费)\n - inbox.nostr.wine (付费)\n - revisy.0xchat.com (免费) 设置 1 ~ 3 个私人收件箱中继。需要确保这些收件箱中继能够接受来自任何人的任何私信消息,但只允许您读取这些消息。 立即设置 @@ -2381,7 +2085,6 @@ 创建专为接收通知而设计的中继列表对于您的 Nostr 体验至关重要。 插入 1–3 个为你接受通知的中继。确保它们不需要发送者的付款或 web of trust,否则你只能接收付款人或长期用户的通知 好的选项是:\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social - DM 上传 中继设置 调整中继顺序 公共时间线中继 @@ -2398,12 +2101,8 @@ 发布 MLS 密钥包的中继(MIP-00)。其他用户获取这些密钥包来邀请你加入 Marmot 群聊。插入1~3个接受来自你的密钥包事件的中继并允许公开读取。 私人中继 设置 1 ~ 3 个中继用于保存其他人无法看到的事件,例如您的草稿和软件设置。理想情况下,这些应该是本地中继,或者是在获取用户内容时需要经过身份验证的中继。 - 通用中继 - Amethyst 会通过这些中继为您获取帖子。 已连接的中继 当前正在使用的中继列表 - 推荐的中继器 - 在通用中继列表中添加下列中继以接收列表中用户的帖子。 搜索中继 用于关键词和标签检索的中继列表。如果没有可用选项,也就无法使用关键词和标签检索。需要确保它们支持 NIP-50。 本地中继 @@ -2438,11 +2137,8 @@ 此版本赞助商: 版本 %1$s 谢谢! - 最大上限 写入限制 Fork 來源 - 复刻 - Git 仓库: %1$s 网址 克隆: 打开 @@ -2467,20 +2163,13 @@ 编辑文章 编辑帖子 提议改进帖子 - 变动摘要 - 快速修正… 接受建议 在弹出窗口中播放视频 下载 - 开启歌词 - 关闭歌词 - 密封消息关闭。点击打开密封消息 - 密封消息开启。点击关闭密封消息 发送 作为音频播放用户名 图钉 扫描二维码 - 导航到第三方钱包提供商 Alby 选择日期 无法回复笔记草稿 无法引用笔记草稿 @@ -2522,23 +2211,18 @@ Insufficient Storage - 服务器没有足够的存储空间用于处理该请求。 Loop Detected - 服务器处理该请求时检测到死循环。 Network Authentication Required - 客户端必须通过认证才能访问该网络。 - NIP-96 服务器 - 添加上传图片时可以选择的服务器。 Blossom 服务器 添加上传图片时可以选择的服务器。 添加 NIP-96 服务器 添加 Blossom 服务器 删除所有 确定要删除所有草稿吗? - 堆叠: Torrent 文件 下载 打开文件失败 没有用于打开和下载文件的 Torrent 客户端 事件没有足够信息来构建磁力链 - 我的列表/集合 我的列表 - 用户 选择一个用于过滤订阅源的列表 源 话题标签 @@ -2569,7 +2253,6 @@ 私信 公开消息 聊天中继 - 此聊天所有用户都连接到的中继 分享图片… 无法分享图片,请稍后重试… 分享视频… @@ -2616,7 +2299,6 @@ 要用私信将最近的崩溃报告发送给 Amethyst 吗?不会分享个人信息 发送它 此消息将在 %1$s 后消失 - 此消息将在 %1$d 天内消失 选择签名者 已经在列表中 私密成员 @@ -2638,7 +2320,6 @@ 包名 新的包名称 包说明 - 新的包说明 广播列表 广播包 删除列表 @@ -2652,13 +2333,9 @@ 折叠 展开 重试失败(%1$d) - 另外 %1$d 条广播 - " (%1$d 正在进行中)" - %1$d/%2$d 个中继 超时 重试中… 重试 - 查看 取消 %1$d/%2$d 广播中 @@ -2684,7 +2361,6 @@ 重启 接受 拒绝 - 新游戏 新的国际象棋游戏 正在加载游戏\u2026 未找到游戏 @@ -2839,23 +2515,13 @@ 要导入的配置文件 搜索, npub1…, alice@example.com 支持npub, nprofile, NIP-05, hex, and namecoin (.bit, d, id/) - 查找关注列表 提示 找到 %1$d 个账户 选中了 %1$d 项 - 通过 Namecoin 解析 - 正在关注 %1$d 个账户 - 您的源已经就绪。 - 跳过 - 搜索另一个 关注 %1$d 账户 - 导入更多 - 继续 暂时跳过 - 正在解析 %1$s… 正在获取关注列表… 未找到关注项 - 正在关注 %1$d 个账户… "输入好友或社区领袖的配置文件。您可以使用他们的 npub、NIP-05地址或Namecoin 名称,例如alice@example.bit 或区块链验证的地址 id/alice。" 全选 %1$d%% 运行时间 @@ -2863,7 +2529,6 @@ 测试连接 正在测试服务器… 已连接 - 已失败 测试结果 诊断 上次测试 @@ -2876,9 +2541,6 @@ 信任 拒绝 中继同步 - 中继同步 - 在所有已知的中继重新发布您的事件,以保持您的发件箱、收件箱和私信中继是最新的。 需要 Wi-Fi - 这可能使用大量数据。 - 打开中继同步… 这是做什么 此工具扫描您的应用已看到的每一个中继并将您的事件重新分发到正确的目的地: 下载您编写的所有事件并发送到您的发件箱中继中。 @@ -2888,14 +2550,9 @@ 使用移动数据? 开始同步 仍要启动(移动数据) - 暂停 - 恢复 - 重来 取消 中继: %1$d / %2$d 已重新分发事件:%1$d 个新事件,共 %2$d 个已发送事件和 %3$d 个已接收事件 - 同步已暂停 - 完成了 %2$d 个中继中的 %1$d 个中继 — 迄今为止重新分发了 %3$d 个事件。轻按“恢复“继续。 同步完成 转发了 %1$d 个事件到目标中继,共接收到 %2$d 个事件。 %1$d 个事件被目标中继接受为新事件。 @@ -2910,16 +2567,13 @@ 已发送 %1$s 已收到 %1$s 新增 %1$s - 没有事件 比特币资源管理器 (OTS) - 事件 来自您的事件 给您的事件 可搜索的事件 私信 个人资料 发件箱列表 - 中继设置 %1$s 前活跃 上次见于 %1$s (%2$s 之前) 刚见到 @@ -2985,7 +2639,6 @@ 正在搜索Wi-Fi网络上的设备… HLS 上传 - 将多分辨率HLS发布到您的媒体服务器 选择视频 您的视频将被转码为多个分辨率,这样观看者就可以在任何连接上平滑播放。 更改 @@ -3000,10 +2653,6 @@ H.265在此设备上不可用——回退到H.264。 Renditions 源分辨率: %1$d×%2$d - 将产生: %1$s - (%1$s 已跳过 — 以上来源) - %1$d kbps - 以上源 — — 将被跳过 发布HD视频 正在发布\"%1$s\"… 正在转码 %1$s @@ -3015,7 +2664,6 @@ 视频已发布 你的高清视频已发布在Nostr上。 出错了 - 查看笔记 完成 重试 包操作 @@ -3030,30 +2678,21 @@ 证明 有效 无效 - 已接受 - 已拒绝 验证中 - 已验证 已撤销 有效期从 %1$s 有效期到 %1$s 证明请求 - 请求某个事件的证明 证明人建议 推荐的类型: 证明人熟练度 - 熟练验证类型:%1$s - 证明 请求证明 日期范围 自 到 刚刚 全部时间 - 上次同步: %1$s - 自上次同步后 网络书签 - 暂无网络书签。点击 + 添加一个。 添加网络书签 编辑网络书签 URL @@ -3108,13 +2747,10 @@ https://example.com/image.jpg 网站 URL (可选) https://example.com - 截止日期(可选) 设置截止日期 新目标 - 创建目标 请求消失 请求中继永久删除直至所选日期的您的所有数据。此操作基于 NIP-62 在一些司法管辖区具备法律约束力。 - 选择中继 目标中继 所有中继 这会请求所有中继删除直至所选日期的与你的密钥所关联的一切。此事件将在尽可能广的范围内进行广播。此操作无法撤销。 @@ -3130,7 +2766,6 @@ 选择日期 选择时间 消失历史记录 - 刷新 这些是在连接的中继上发现的以往的“消失请求”事件。在这些事件中标记的中继不应持有任何事件日期前的你的数据。 没有发现消失请求 您尚未发送任何消失请求事件。 @@ -3173,7 +2808,6 @@ 封禁事件 允许类型 屏蔽IP - 公钥(十六进制) 事件 ID (十六进制) 类型编号 IP地址 @@ -3184,7 +2818,6 @@ 中继名称 中继描述 中继图标 URL - 管理中继 管理 成员 %1$s 的成员 @@ -3255,7 +2888,6 @@ 表情包操作 我的表情包 表情 - 浏览表情集 私密 私密表情 公开表情符号对所有人可见;当此表情包位于您的表情符号列表中时,它们会显示在您的“反应”菜单及“:”自动补全选择器中。 @@ -3280,4 +2912,84 @@ Nowhere Drop Nowhere 艺术 Nowhere 论坛 + + Marmot 群 + 创建群组 + 创建Marmot群 + 将创建新的 MLS 群。您可以随后添加成员。 + Marmot 群 + 群 %1$s… + %1$s… + 已知 + 已知(%1$d) + 新请求 + 新请求 (%1$d) + 还没有群组 + 建群或接受邀请。 + 无邀请 + 当有人将您添加到一个群时,它会出现在这里,直到您回复。 + 尚无消息 + + %1$d 条消息 + + + %1$d 位成员 + + 群名称 + 输入群名称 + 输入群描述(可选) + 更改将通过 MLS 提交到该群,并传播给所有成员。 + 群信息已更新 + 更新失败: %1$s + 创建群失败: %1$s + 未设置密钥包中继 + 您还没有密钥包中继列表 (MIP-00)。 此列表告诉其他人您的密钥包在哪里发布,以便他们可以邀请您加入群聊。\n\n使用您当前的发件箱中继? + 使用发件箱中继 + 暂时跳过 + 群信息 + 编辑群信息 + 退群 + 此群 + 您确定要离开“%1$s”吗?您将不再收到来自此群的消息。 + 退群失败: %1$s + 正在添加 %1$s… + 添加 %1$s失败: %2$s + 未知错误 + 他们必须已经发布了一个要添加的 KeyPackage (kind:30443)。 + 添加到群 + 添加成员 + 添加成员 + 姓名, npub, 或 NIP-05 + (您) + - 管理员 + 成员已移除 + 移除成员失败: %1$s + 移除成员 + 您确定要从此群组中移除\"%1$s\"吗? + 授权 + 授予管理员权限 + 授予管理员权限 + 使“%1$s”成为此群的管理员?管理员可以添加或删除成员,更改群信息,并给予其他成员管理员权限。 + 已授予管理员权限 + 授予管理员权限失败: %1$s + 撤销 + 撤销管理员权限 + 授予管理员权限 + 撤销\"%1$s\"的管理员权限?他们将仍是群成员。 + 已撤销管理员权限 + 撤销管理员失败: %1$s + 中继 + 暂无事件 + 上次事件%1$s + 不是此群的成员 + 复制 + 重置为自动选择 + Explorer API 基础URL + 支付来自DVM的发票 + 支付 %1$s sats 到 DVM + %1$s 的接收者闪电服务不可用。它是根据雷电地址\"%2$s\"计算的。 错误: %3$s。请检查服务器是否已经上线,闪电地址是否正确 + 无法解析 %1$s。请检查你是否已连接,服务器是否启动,以及闪电地址 %2$s 是否正确。\n\n异常为:%3$s + 从 %1$s 的闪电发票获取解析JSON 发生错误。请检查用户的闪电设置 + 无法创建闪电发票。来自 %1$s 的消息:%2$s + 无法从 %1$s 创建闪电发票:在生成的 JSON 中找不到付款要求元素。 diff --git a/amethyst/src/main/res/values-zh-rHK/strings.xml b/amethyst/src/main/res/values-zh-rHK/strings.xml index 66a82f66c5..12c579e18a 100644 --- a/amethyst/src/main/res/values-zh-rHK/strings.xml +++ b/amethyst/src/main/res/values-zh-rHK/strings.xml @@ -15,8 +15,6 @@ 垃圾郵件 冒充 非法行為 - 未知 - 中繼器圖標 未知作者 複製文本 複製作者@npub @@ -25,14 +23,12 @@ 舉報垃圾郵件/詐騙 舉報冒充 - 舉報明確內容 舉報非法行為 使用私鑰登錄以便回覆 使用私鑰登錄以便提升帖子 使用私鑰登錄以便點贊帖子 沒有設置Zap金額。長按以更改 使用私鑰登錄以便發送Zaps - 瀏覽次數 提升 已提升 引用 @@ -40,7 +36,6 @@ 添加 "回覆 " " 和 " - " 在頻道 " 個人檔案橫幅 " 關注" " 粉絲" @@ -55,9 +50,7 @@ 非常感謝! 聰數量 發送聰 - "解析 %1$s 預覽出錯:%2$s" "預覽 %1$s 卡片圖片" - 新頻道 頻道名 我的精彩羣聊 圖片鏈接 @@ -68,34 +61,20 @@ 保存 創建 取消 - 上傳圖片失敗 - 中繼器地址 - 帖文 錯誤 - 主頁 - 私信 - 公開聊天 - 全球 - 搜索 添加中繼器 顯示名稱 我的顯示名稱 用户名 - 我的用户名 關於我 頭像鏈接 橫幅鏈接 網站鏈接 - LN地址 - LN鏈接(過期) 圖片已保存到相冊 保存圖片失敗 上傳圖片 - 上傳中… 用户尚未設置閃電地址以接收聰 "🔏 在此回覆… " - 複製筆記ID到剪貼板,供分享 - 複製頻道ID(筆記)到剪貼板 編輯頻道元數據 加入 私聊 @@ -105,16 +84,12 @@ 會話 動態 回覆 - "關注" "舉報" 更多選項 "中繼" 網站 閃電地址 複製 Nsec ID(您的私人密鑰)到剪貼板以備備份 - 複製私鑰到剪貼板 - 複製公鑰到剪貼板以供共享 - 複製公鑰(NPub)到剪貼板 發送直接消息 編輯用户元數據 關注 @@ -133,7 +108,6 @@ 需要接受條款 需要密鑰 登錄 - 生成新密鑰 正在加載 @@ -141,12 +115,6 @@ 重試 信息流為空。 刷新 - 創建 - 描述為 - 並上傳圖片 - 將聊天名稱修改為 - 描述更改為 - 圖片更改為 離開 取關 頻道已創建 @@ -169,7 +137,6 @@ 不文雅的言辭 / 敵意言論 舉報敵意言論 舉報裸體 / 情色內容 - 其他 將所有已知內容標記為已讀 將所有新內容標記為已讀 將所有內容標記為已讀 @@ -177,23 +144,18 @@ 私人密鑰(nsec)已複製到剪貼板 複製我的私人密鑰 身份驗證失敗 - 錯誤 - "由 %1$s 創建" "頒發給 %1$s 的徽章圖片" 您收到了新的徽章獎勵 徽章獎勵授予 文本已複製到剪貼板 複製作者的 @npub 到剪貼板 複製文章ID (@note1) 到剪貼板 - 選擇文本 "<無法解密私人消息>\n\n您被%1$s和%2$s之間的私人/加密會話引用。" 添加新賬户 賬户 選擇賬户 添加新賬户 活躍賬户 - 具有私鑰 - 只讀,無私鑰 返回 選擇 分享瀏覽網址 @@ -210,7 +172,6 @@ 刪除 隱藏 舉報 - 刪除 不再次顯示 垃圾信息或詐騙 不文明用語或仇恨行為 @@ -235,10 +196,6 @@ 添加到公開書籤 從私人書籤中移除 從公開書籤中移除 - 錢包綁定服務 - 使用您的私鑰在不離開應用程序的情況下支付 zaps。 任何具有訪問 Nostr 私鑰的人都可以使用您的錢包餘額。要保留您的資金避免損失,如果可能,請使用私人中繼器。中繼器操作員可以看到您的付款元數據。 - 錢包綁定公鑰 - 錢包綁定中繼 聰數量 "“正在查找事件%1$s”" @@ -258,4 +215,5 @@ + diff --git a/amethyst/src/main/res/values-zh-rSG/strings.xml b/amethyst/src/main/res/values-zh-rSG/strings.xml index fd00368279..6d9f1504ab 100644 --- a/amethyst/src/main/res/values-zh-rSG/strings.xml +++ b/amethyst/src/main/res/values-zh-rSG/strings.xml @@ -19,4 +19,5 @@ + diff --git a/amethyst/src/main/res/values-zh-rTW/strings.xml b/amethyst/src/main/res/values-zh-rTW/strings.xml index 1a9cb5e175..5b2069a0be 100644 --- a/amethyst/src/main/res/values-zh-rTW/strings.xml +++ b/amethyst/src/main/res/values-zh-rTW/strings.xml @@ -20,8 +20,6 @@ 冒充 非法行為 其它 - 未知 - 中繼器圖標 未知作者 複製文本 複製作者@npub @@ -35,7 +33,6 @@ 舉報垃圾郵件/詐騙 舉報冒充 - 舉報露骨內容 舉報非法行為 舉報惡意軟體 你正在使用公鑰,公鑰是只讀的。使用私鑰登錄以便回覆 @@ -48,7 +45,6 @@ 你正在使用公鑰,公鑰是只讀的。使用私鑰登錄以便能夠隱藏單詞或句子 你正在使用公鑰,公鑰是只讀的。使用私鑰登錄以便能夠顯示單詞或句子 打閃 - 瀏覽次數 提升 已提升 已編輯 @@ -60,9 +56,7 @@ 添加 "回覆 " " 和 " - "在頻道 " 個人檔案橫幅 - 付款成功 錯誤解析錯誤消息 " 關注" " 粉絲" @@ -77,9 +71,7 @@ 非常感謝! 聰金額 發送聰 - "解析 %1$s 預覽出錯:%2$s" "預覽 %1$s 卡片圖片" - 新頻道 頻道名 我的精彩羣聊 圖片鏈接 @@ -90,38 +82,21 @@ 保存 創建 取消 - 上傳圖片失敗 - 中繼器地址 - 貼文 - 位元組 錯誤 - 此會話中產生的連線錯誤數量 - 主頁 - 私信 - 公開聊天 - 全球 - 搜索 添加中繼器 顯示名稱 我的顯示名稱 歡迎! 用户名 - 我的用户名 關於我 頭像鏈接 橫幅鏈接 網站鏈接 - LN 地址 - LN 鏈接(過期) - 保存到相冊 圖片已保存到相冊 保存圖片失敗 上傳圖片 - 上傳中… 用户尚未設置閃電地址以接收聰 "回覆這裡.." - 複製筆記ID到剪貼板,供分享 - 複製頻道ID(筆記)到剪貼板 編輯頻道元數據 加入 已准 @@ -132,16 +107,12 @@ 動態 回覆 相冊 - "關注" "舉報" 更多選項 "中繼" 網站 閃電地址 複製 NSec (私人密鑰)到剪貼板以備備份 - 複製私鑰到剪貼板 - 複製公鑰到剪貼板以供共享 - 複製公鑰(NPub)到剪貼板 發送直接消息 編輯用户元數據 關注 @@ -170,8 +141,6 @@ 我們應該如何稱呼你? 還沒有 Nostr 帳戶? 已經有 Nostr 帳戶? - 創建新帳戶 - 生成新密鑰 正在加載 正在加載帳戶 @@ -180,12 +149,6 @@ 重試 信息流為空。 刷新 - 創建 - 描述為 - 並上傳圖片 - 將聊天名稱修改為 - 描述更改為 - 圖片更改為 離開 取關 頻道已創建 @@ -209,7 +172,6 @@ 不文雅的言辭 / 敵意言論 舉報敵意言論 舉報裸體 / 情色內容 - 其他 將所有已知內容標記為已讀 將所有新內容標記為已讀 將所有內容標記為已讀 @@ -230,23 +192,18 @@ 身份驗證失敗 生物計未能驗證此手機的所有者 生物計未能驗證此手機的所有者。錯誤:%1$s - 錯誤 - "由 %1$s 創建" "頒發給 %1$s 的徽章圖片" 您收到了新的徽章獎勵 徽章獎勵授予 文本已複製到剪貼板 複製作者的 @npub 到剪貼板 複製文章ID (@note1) 到剪貼板 - 選擇文本 "<無法解密私人消息>\n\n你被 %1$s 和 %2$s 之間的私人/加密對話引用。" 添加新帳戶 帳戶 選擇帳戶 添加新帳戶 活躍帳戶 - 有私鑰 - 只讀,無私鑰 返回 選擇 分享瀏覽網址 @@ -264,14 +221,12 @@ 刪除 屏蔽 舉報 - 刪除 不再顯示 垃圾信息或詐騙 不文明語言或仇恨行為 惡意冒充 暴露裸體或噁心內容 非法行為 - 惡意軟體 屏蔽一位用戶將會在你的應用中隱藏他的內容。你的筆記仍然是公開可見的,包括對被你屏蔽的用戶。屏蔽的用戶將會被列在安全過濾器屏幕上。 舉報違規 @@ -291,30 +246,15 @@ 添加到公開書籤 從私人書籤移除 從公開書籤移除 - 錢包綁定服務 - 允許使用 Nostr 私鑰在不離開應用程式的情況下支付打閃。請安全保存私鑰並在有可能的情況下使用私人中繼器 - 錢包綁定公鑰 - 錢包綁定中繼 - 錢包綁定私鑰 - 顯示私鑰 - nsec / 十六進制私鑰 承諾聰金額 - 發佈投票 - 必填欄位: - 打閃接收人 - 投票主要說明… 選項 %s 投票選擇說明 - 可選欄位: 打閃最低金額 打閃最高金額 共識 (0–100)% - 後關閉 - 天 無法投票 該投票已結束 - 打閃金額 這種投票只允許每個用戶一票 "正在查找事件 %1$s" 添加公開消息 @@ -343,38 +283,19 @@ 非打閃 Nostr 上沒有痕跡,僅在閃電上 文檔服務器 - LnAddress 或 @User 媒體服務器 設置首選媒體上傳服務器 - 內置媒體服務器 Amethyst 的默認列表。可單獨添加或添加整個列表。 使用默認列表 添加媒體服務器 刪除媒體服務器 - 你的中繼器 (NIP-95) - 文檔由你的中繼器託管。新的 NIP:檢查它們是否支持 - Tor/Orbot 設置 - 通過你的 Orbot 設置連接 - 斷開與你的 Orbot/Tor 連接? - 你的數據將立即在普通網絡上傳輸 是 否 - 關注列表 所有關注 全球 靜音列表 - ## 通過 Orbot 連線 Tor - \n\n1. 安裝 [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. 開啟 Orbot - \n3. 在 Orbot 中檢查 Socks 端口。默認使用9050 - \n4. 如果需要,在 Orbot 中更改端口 - \n5. 在此屏幕中配置 Socks 端口 - \n6. 按“啟用”按鈕以使用 Orbot 為代理 - Orbot Socks 端口 無效端口 - 使用 Orbot - 斷連 Tor/Orbot 私信 受到私信時通知你 收到打閃 @@ -384,20 +305,9 @@ 為 %1$s 通知: - 加入對話 - 用戶或群組 ID - npub,、nevent 或 hex - 創建 - 加入 今天 內容警告 這個帖子含有敏感內容,一些人可能會覺得有冒犯性或令人不安 - 始終隱藏敏感內容 - 始終顯示敏感內容 - 始終顯示內容警告 - 推薦: - 過濾來自陌生人的垃圾信息 - 當帖子有你的關注的報告時警告 新回應符號 未選擇回應類型。長按可更改 Zapraiser @@ -408,37 +318,24 @@ 寫入到中繼器 發送到此中繼的數據量,包括過濾和事件 從此中繼接收的數據量,包括過濾和事件 - 嘗試從 %1$s 獲取中繼器信息時出錯 機主 版本 軟體 聯絡 支持的 NIPs - 接納費 付款網址 限制 國家 語言 - 標籤 發佈政策 該中繼的錯誤和通知 - 消息長度 - 訂閱 - 篩選器 - 訂閱 ID 長度 最少前綴 最多事件標籤 - 內容長度 最低工作量證明 - 認證 - 付款 Cashu 代幣 兌換 - 發送到打閃錢包 - 在 Cashu 錢包中打開 複製代幣 未設定閃電地址 - 已將代幣複製到剪貼簿 直播 離線 已結束 @@ -461,7 +358,6 @@ (translated) row titles. Marked translatable="false" so protocol terms (blossom, nsec, negentropy, …) stay searchable in every locale and aren't sent to translators. --> 始終 - 僅限 WiFi 未計量的 WiFi 永不 完整版 @@ -479,7 +375,6 @@ 捲動時隱藏導航欄 界面模式 選擇帖子樣式 - 加載圖像 垃圾郵件 靜音。點擊取消靜音 聲音開啟。點擊靜音 @@ -487,17 +382,10 @@ Nostr 地址已驗證 Nostr 地址驗證失敗 正在檢查 Nostr 地址 - 全部選擇/取消選擇 默認 - 選擇中繼器以繼續 - 將打閃轉發到: - 支持的客戶端會將打閃轉發到以下的閃電地址或用戶個人檔案,而不是你的 將位置顯示為 將你所在位置的地理位置添加到帖子。公眾會知道你在當前位置的5公里之內(3英里) 在顯示你的內容之前添加敏感內容警告。針對任何 NSFW 內容或一些人可能覺得有冒犯性或令人不安的內容。 - 新功能 - 啟用此模式需要 Amethyst 發送一條 NIP-17 消息(包裝的、密封的私信和群聊消息)。因為 NIP-17 是新的,大多數客戶端尚未執行。請確保接收方正在使用兼容的客戶端。 - 啟用 公開 新建公開或私人群組 私人 @@ -514,7 +402,6 @@ 自動加載圖像和 GIF 自動播放視頻和 GIF 顯示鏈接預覽 - 何時加載圖像 複製至剪貼簿 複製 npub 至剪貼簿 分享或保存 @@ -522,43 +409,22 @@ 將筆記 ID 複製到剪貼簿 將媒體添加到相冊 創建於 - 規則 使用 Amber 登錄 更新你的狀態 - 錯誤解析錯誤消息 投票按照打閃金額進行加權。你可以設置最小金額以避免垃圾郵件,也可以設置最大金額以避免大型攻擊者攻擊民意調查。在兩個字段中使用相同的金額則確保每張投票的價值相同。留空即可接受任何金額。 無法發送打閃 向用戶發送消息 確定 - 無法連接 %1$s:%2$s - 無法連接 %1$s:%2$s - 無法解析來自 %1$s 的結果:%2$s - 中继拒绝请求 %1$s: %2$s - 無法連接 %1$s:%2$s - 無法解析來自 %1$s 的結果:%2$s - %1$s 失敗了,代碼 %2$s - 活躍於: - 首頁 - 私信 - 聊天 - 全球 - 搜索 拆分及轉發打閃 支持的客戶端將會把打閃拆分及轉發到在這裡添加的用戶,而不是你的 搜索並添加用戶 用戶名或顯示名 閃電設置缺失 用户 %1$s 尚未設置接收聰的閃電地址 - 百分比 - 25 - 與此用戶拆分打閃 - 將打閃轉發到 - 找不到閃電錢包 已支付 錢包:%1$s 打開簽署程式時出錯 找不到簽名應用。檢查應用是否已被預載。 - 簽署請求被拒絕了 請確保簽名應用程式已授權此交易 找不到支付閃電發票的錢包(錯誤:%1$s)。請安裝一個閃電錢包來使用打閃 找不到支付閃電發票的錢包。請安裝一個閃電錢包來使用打閃 @@ -569,35 +435,18 @@ 請選擇一個選項 無法支付發票 無法提款 - 無法設置錢包連接 - 解析 NIP-47 連接字符串時出錯。請與你的錢包提供商檢查這是否正確:%1$s。錯誤:%2$s - 解析 NIP-47 連接字符串時出錯。請與你的錢包提供商檢查這是否正確:%1$s。 無法兌換 Cashu 鑄幣廠提供了以下錯誤消息:%1$s - Cashu 代幣已花費。 已收到 Cashu %1$s 聰已被發送到你的錢包。(費用:%2$s 聰) 系統上沒有找到兼容的 Cashu 錢包 無法從接收方的伺服器獲取發票 你的錢包連接提供者返回了以下錯誤:%1$s - 無法連線到 Tor - 無法下載中繼文件 無法從閃電地址集合 LNURL “%1$s”。請檢查用戶設置 - %1$s 的接收方閃電服務不可用。它是根據閃電地址“%2$s”計算的。錯誤:%3$s。請檢查伺服器是否已上線,閃電地址是否正確 - 無法解析 %1$s。請檢查你是否已連接,伺服器是否啟動,以及閃電地址 %2$s 是否正確 - 無法解析 %1$s。請檢查你是否已連接,服務器是否啓動,以及閃電地址 %2$s 是否正確。\n\n異常爲:%3$s - 無法從 %1$s 獲取發票 - 從閃電地址解析 JSON 發生錯誤。請檢查用戶的閃電設置 從 %1$s 解析 JSON 發生錯誤。請檢查用戶的閃電設置 - 在用戶閃電地址伺服器配置中找不到回調 URL 從 %1$s 的響應中找不到回調 URL - 從閃電地址的發票獲取解析 JSON 發生錯誤。請檢查用戶的閃電設置 - 從 %1$s 的閃電發票獲取解析 JSON 發生錯誤。請檢查用戶的閃電設置 來自 %2$s 的錯誤的發票金額(%1$s 聰)。應該是 %3$s 無法在發送打閃前創建閃電發票。接收者閃電錢包發送了以下錯誤:%1$s - 無法創建閃電發票。來自 %1$s 的消息:%2$s - 無法在發送打閃前創建閃電發票。在生成的 JSON 中找不到 Element pr。 - 無法從 %1$s 創建閃電發票:在生成的 JSON 中找不到付款要求元素。 只讀用戶 沒有設置回應 選擇一個統一推送應用 @@ -615,13 +464,11 @@ 向賣方發送消息 嗨,%1$s,這個還能買到嗎? 你好,這個還能買到嗎? - 出售物品 標題 iPhone 13 狀態 類別 價格(聰) - 1000 地點 市,州,國家 全新 @@ -650,25 +497,18 @@ 其它 上傳媒體失敗 無法打開壓縮文件 - 壓縮媒體時出錯:%1$s 上傳錯誤:%1$s 上傳後伺服器沒有提供 URL 無法從伺服器下載上傳的媒體 - 無法準備要上傳的本地文件:%1$s - 上傳失敗:%1$s 刪除失敗:%1$s 編輯草稿 使用二維碼登錄 - 路徑 主頁 - 搜索 發現 訊息 通知 - 全球 短篇 - 安全濾鏡 新帖子 新短篇:圖像或視頻 新社區筆記 @@ -683,29 +523,22 @@ 中繼器 %1$s 展開中繼列表 筆記選項 - 中繼列表選擇器 投票 停用投票 比特幣發票 取消比特幣發票 - 取消出售物品 Zapraiser 取消 Zapraiser 地點 移除地點 - 打閃拆分 - 取消打閃拆分 添加內容警告 移除內容警告 將 npub 顯示爲二維碼 地址無效 Amethyst 收到了要打開的 URI,但該 URI 無效:%1$s 私信收件匣中繼 - 中繼器 %1$s - 正在使用常規中繼器 設定你的私人收件匣中繼 此設定讓大家知道向你發送訊息時要使用哪些中繼。如果沒有它們,你可能會錯過一些訊息。 - 不錯的選擇是:\n - inbox.nostr.wine(付費)\n - you.nostr1.com(個人中繼 - 付費) 輸入 1–3 個中繼作為你的私人收件匣。 私信收件匣中繼應該接受任何人的任何訊息,但只允許你下載它們。 立即設定 搜索中繼器 @@ -722,9 +555,6 @@ 輸入 1–3 個中繼作爲你的私人收件匣。他人將使用這些中繼向你發送私信。私信收件匣中繼應該接受來自任何人的訊息,但只允許你下載它們。不錯的選擇是:\n - inbox.nostr.wine (付費)\n - you.nostr1.com (私人中繼 - 付費) 私人中繼 輸入 1–3 個中繼用於存儲別人看不到的事件,例如你的草稿和/或應用設置。理想情況下,這些中繼要么是本地的,要么需要在下載每個用戶的內容之前進行驗證。 - 一般中繼器 - Amethyst 使用這些中繼爲你下載帖子。 - 推薦的中繼器 搜索中繼器 搜尋內容或用戶時使用的中繼列表。如果沒有可用選項,標記和搜索將無法運作。確保他們實施 NIP-50。 本地中繼器 @@ -736,9 +566,7 @@ 此版本贊助方: 版本 %1$s 謝謝! - 最大上限 寫入限制 - Git 倉庫:%1$s 網址 克隆: OTS:%1$s @@ -746,18 +574,11 @@ 有在 %1$s 之前的某個時間簽署了此帖子的證明。此證明是在那個日期和時間在比特幣區塊鏈中記錄的時間戳。 編輯帖子 提議改進帖子 - 變動摘要 - 快速修正… 接受提議 下載 - 開啓歌詞 - 關閉歌詞 - 密封消息關閉。點擊打開密封消息 - 密封消息關閉。點擊打開密封消息 發送 作爲音頻播放用戶名 掃描二維碼 - 導航到第三方錢包提供商 Alby 無法回覆筆記草稿 無法引用筆記草稿 無法回應筆記草稿 @@ -781,4 +602,10 @@ + + %1$s 的接收方閃電服務不可用。它是根據閃電地址“%2$s”計算的。錯誤:%3$s。請檢查伺服器是否已上線,閃電地址是否正確 + 無法解析 %1$s。請檢查你是否已連接,服務器是否啓動,以及閃電地址 %2$s 是否正確。\n\n異常爲:%3$s + 從 %1$s 的閃電發票獲取解析 JSON 發生錯誤。請檢查用戶的閃電設置 + 無法創建閃電發票。來自 %1$s 的消息:%2$s + 無法從 %1$s 創建閃電發票:在生成的 JSON 中找不到付款要求元素。 diff --git a/amethyst/src/main/res/values-zh/strings.xml b/amethyst/src/main/res/values-zh/strings.xml index 48ab496800..1473c75ccd 100644 --- a/amethyst/src/main/res/values-zh/strings.xml +++ b/amethyst/src/main/res/values-zh/strings.xml @@ -14,8 +14,6 @@ 垃圾邮件 冒充 非法行为 - 未知 - 中继器图标 未知作者 复制文本 复制作者@npub @@ -27,7 +25,6 @@ 举报垃圾邮件/诈骗 举报冒充 - 举报明确内容 举报非法行为 使用私钥登录以便回复 使用私钥登录以便提升帖子 @@ -35,7 +32,6 @@ 没有设置Zap金额。长按以更改 使用私钥登录以便发送Zaps Zaps - 浏览次数 提升 已提升 引用 @@ -43,7 +39,6 @@ 添加 "回复 " " 和 " - " 在频道 " 个人档案横幅 " 关注" " 粉丝" @@ -58,9 +53,7 @@ 非常感谢! 聪数量 发送聪 - "解析 %1$s 预览出错:%2$s" "预览 %1$s 卡片图片" - 新频道 频道名 我的精彩群聊 图片链接 @@ -71,35 +64,20 @@ 保存 创建 取消 - 上传图片失败 - 中继器地址 - 帖文 - 字节 错误 - 主页 - 私信 - 公开聊天 - 全球 - 搜索 添加中继器 显示名称 我的显示名称 用户名 - 我的用户名 关于我 头像链接 横幅链接 网站链接 - LN地址 - LN链接(过期) 图片已保存到相册 保存图片失败 上传图片 - 上传中… 用户尚未设置闪电地址以接收聪 "🔏在此回复… " - 复制笔记ID到剪贴板,供分享 - 复制频道ID(笔记)到剪贴板 修改频道元数据 加入 私聊 @@ -109,16 +87,12 @@ 会话 动态 回复 - 关注 举报 更多选项 中继 网站 闪电地址 复制 Nsec ID(您的私人密钥)到剪贴板以备备份 - 复制私钥到剪贴板 - 复制公钥到剪贴板以供共享 - 复制公钥(NPub)到剪贴板 发送直接消息 编辑用户元数据 关注 @@ -137,18 +111,11 @@ 需要接受条款 需要密钥 登录 - 生成新密钥 正在加载 加载回复出错: 重试 信息流为空。 刷新 - 创建 - 描述为 - 并上传图片 - 将聊天名称修改为 - 描述更改为 - 图片更改为 离开 取关 频道已创建 @@ -171,7 +138,6 @@ 不文雅的言辞 / 敌意言论 举报敌意言论 举报裸体 / 情色内容 - 其他 将所有已知内容标记为已读 将所有新内容标记为已读 将所有内容标记为已读 @@ -179,23 +145,18 @@ 私人密钥(nsec)已复制到剪贴板 复制我的私人密钥 身份验证失败 - 错误 - "由 %1$s 创建" "颁发给 %1$s 的徽章图片" 您收到了新的徽章奖励 徽章奖励授予 文本已复制到剪贴板 复制作者的 @npub 到剪贴板 复制文章ID (@note1) 到剪贴板 - 选择文本 "<无法解密私人消息>\n\n您被%1$s和%2$s之间的私人/加密会话引用。" 添加新账户 账户 选择账户 添加新账户 活跃账户 - 具有私钥 - 只读,无私钥 返回 选择 分享浏览网址 @@ -212,7 +173,6 @@ 删除 隐藏 举报 - 删除 不再次显示 垃圾信息或诈骗 不文明用语或仇恨行为 @@ -239,10 +199,6 @@ 添加到公开书签 从私人书签中移除 从公开书签中移除 - 钱包绑定服务 - 使用您的私钥在不离开应用程序的情况下支付 zaps。 任何具有访问 Nostr 私钥的人都可以使用您的钱包余额。要保留您的资金避免损失,如果可能,请使用私人中继器。中继器操作员可以看到您的付款元数据。 - 钱包绑定公钥 - 钱包绑定中继 聪数量 “正在查找事件%1$s” diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index 82e169ad23..dc07d6e262 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -1,7 +1,5 @@ Amethyst - Amy Debug - Amy Benchmark Point to the QR Code Show QR Profile Picture @@ -38,8 +36,6 @@ Other Harassment Violence - Unknown - Relay Icon Unknown Author Copy Text Copy Author ID @@ -54,13 +50,10 @@ Report Spam / Scam Report Impersonation - Report Explicit Content Report Illegal Behaviour Report Malware - Report Mod Malware - Mod You are using a public key and public keys are read-only. Login with a Private key to be able to reply You are using a public key and public keys are read-only. Login with a Private key to be able to boost posts @@ -75,7 +68,6 @@ You are using a public key and public keys are read-only. Login with a Private key to be able to unfollow You are using a public key and public keys are read-only. Login with a Private key to be able to hide a word or sentence You are using a public key and public keys are read-only. Login with a Private key to be able to show a word or sentence - You are using a public key and public keys are read-only. Login with a Private key to be able to change settings You are using a public key and public keys are read-only. Login with a Private key to be able to upload You are using a public key and public keys are read-only. Login with a Private key to be able to sign for events @@ -85,11 +77,9 @@ Signer not found Was the Signer app uninstalled? Check if the signer is installed and has this account. Log off and Log in again of the signer app has changed. - Signer misbehaved External signer returned a payload that is strange for the request. There might be a bug on either Amethyst or the Signer. Zaps - View count Boost boosted edited @@ -102,9 +92,7 @@ Add "replying to " " and " - "in channel " Profile Banner - Payment Successful Error parsing error message " Following" " Followers" @@ -179,7 +167,6 @@ Not enough balance in a mint this recipient accepts. Top up your Cashu wallet first. Spendable for this recipient: %1$s sats Network fee - your wallet app Transaction: %1$s Lightning Tips @@ -196,16 +183,13 @@ 😎 Add to Post - "Error parsing preview for %1$s : %2$s" "Preview Card Image for %1$s" Article - New Channel Channel Name My Awesome Group Picture Url Picture Url(Optional) Description - Description not found "About us… " What\'s on your mind? Write a message… @@ -215,42 +199,25 @@ Create Rename Cancel - Failed to upload the image - Relay Address - Posts - Bytes Error Errors Percentage of successful connections to the relay - The number of connection errors in this session - Home Feed - Private Message Feed - Public Chat Feed - Global Feed - Search Feed Search and add user - Add a User Add a Relay - Name - Name (for @tagging) My @tag name Display Name My display name Ostrich McAwesome Welcome Ostrich! Username - My username About me Avatar URL Banner URL Website URL Pronouns - LN Address - LN URL (outdated) Source relays may be stale Stale relay warning Save to Phone - Save to Gallery Image saved to the phone\'s photo gallery Video download has started… Media download has started… @@ -268,15 +235,12 @@ Record a video No camera app found on this device Record a message - Record a message Click and hold to record a message Re-record Recording Recording %1$s - Uploading… Upload Error Failed to upload voice message - Unexpected upload state NIP-95 is not supported for voice messages yet Voice upload failed: %1$s None @@ -288,8 +252,6 @@ User does not have a lightning address set up to receive sats "reply here… " In this chat - Copies the Note ID to the clipboard for sharing in Nostr - Copy Channel ID (Note) to the Clipboard Edits the Channel Metadata Join Known @@ -303,7 +265,6 @@ Replies Yours Gallery - "Follows" "Reports" "%1$s Reports" More Options @@ -311,11 +272,8 @@ Website Lightning Address Copies the Nsec ID (your password) to the clipboard for backup - Copy Secret Key to the Clipboard Show private key QR code Show encrypted private key QR code - Copies the public key to the clipboard for sharing - Copy Public Key (NPub) to the Clipboard Send a Direct Message Edits the User\'s Metadata Follow @@ -344,8 +302,6 @@ How should we call you? Don\'t have a Nostr account? Already have a Nostr account? - Create a new account - Generate a new key Loading feed Loading account encrypted @@ -361,13 +317,7 @@ Open Poll Feed is empty. Refresh - created - with description of - and picture - changed chat name to New chat profile: - description to - and picture to Leave Unfollow Channel created @@ -411,7 +361,6 @@ LNURL… never now - seconds h m d @@ -419,7 +368,6 @@ Profanity / Hateful speech Report Hateful speech Report Nudity / Porn - others Mark all Known as read Mark all New as read Mark all as read @@ -443,8 +391,6 @@ Authentication failed Biometrics failed to authenticate the owner of this phone Biometrics failed to authenticate the owner of this phone. Error: %1$s - Error - "Created by %1$s" "Badge award image for %1$s" "Badge award image You Received a new Badge Award @@ -452,13 +398,11 @@ Copied note text to clipboard Copied author’s @npub to clipboard Copied note ID (@note1) to clipboard - Select Text Github Gist w/ Proof Telegram Mastodon Post ID w/ Proof X Status w/ Proof https://gist.github.com/<user>/<gist> - https://t.me/<proof post> https://<server>/<user>/<proof post> https://x.com/<user>/status/<proof post> "<Unable to decrypt private message>\n\nYou were cited in a private/encrypted conversation between %1$s and %2$s." @@ -472,8 +416,6 @@ Select Account Add New Account Active account - Has private key - Read only, no private key Back Select Share Browser Link @@ -498,14 +440,12 @@ Mute thread Unmute thread Report - Delete Don\'t show again Spam or scams Profanity or hateful conduct Malicious impersonation Nudity or graphic content Illegal Behavior - Malware Blocking a user will hide their content in your app. Your notes are still publicly viewable, including to people you block. Blocked users are listed on the Security Filters screen. Report Abuse @@ -534,7 +474,6 @@ Pick scheduled time Schedule for… Publishes in %1$s - Was due %1$s ago Time Schedule post Cancel scheduling @@ -610,7 +549,6 @@ Author Requests Approvals - No communities match this filter. Verifiable rules (optional) Publishes a machine-readable rules document (NIP-9B) alongside the community. Clients that support it block posts that don\'t match before sending. Allowed event kinds @@ -639,26 +577,15 @@ Add WoT gate Global max event size (optional) Bytes \u2014 leave blank for no global cap. - Received - Mine - Awarded - Discover New Badge - Edit Badge Award Badge Accept Reject Remove from profile - Badge ID (d-tag) - bravery, contributor-2025… Name Human-readable badge name Description Why is this badge awarded? - Image URL (1024×1024) - https://example.com/badge.png - Thumbnail URL (optional) - https://example.com/badge-thumb.png Upload an image Pick a square image to be the face of your badge. Loading badge… @@ -667,7 +594,6 @@ Remove Untitled badge Awarded to %1$d - You received a badge Profile badges Badges · %1$d Choose which of the badges you\'ve received appear on your profile. @@ -678,6 +604,9 @@ Recommended apps Choose which Nostr apps you publicly recommend. Recommendations appear on your profile and help others discover apps for content this client can\'t open. No apps found yet. Apps will appear here as they are discovered on your relays. + Search apps by name + No apps match your search. + No recommended apps match this filter. Unnamed app Doesn\'t announce what content it handles Recommend @@ -706,6 +635,8 @@ Sets Reps Weight + Exercises + Volume Notes Hours Minutes @@ -713,12 +644,7 @@ Share your workouts Let Amethyst read finished workouts from Health Connect (Samsung Health, Google Fit, Fitbit, Garmin…) and suggest a post. Connect - New workout detected - Share - Dismiss %1$s km - %1$s bpm - %1$s kcal From Health Connect Running Walking @@ -731,6 +657,9 @@ Meditation Diet Fasting + Circuit + EMOM + AMRAP Apps Apps Napplets @@ -791,12 +720,10 @@ Topics Links Latest release - Comments Be the first to comment. by Show older releases Hide older releases - Calendars Shorts Public Chats Follow Packs @@ -806,18 +733,14 @@ a Nest Stage Waiting for speakers… - Audience Raise hand Lower hand Connect audio - Disconnect Mute Unmute - Connecting… Resolving room Opening transport Negotiating audio - Audio connected Reconnecting… Listen to recording Couldn\'t send message @@ -825,9 +748,7 @@ Close this room? All attendees will be disconnected. The room will show as CLOSED in the feed. Close room - Pick a future start time. Audio failed: %1$s - Audio is not available for this room Talk Leave stage Mute mic @@ -835,7 +756,6 @@ Going live… Broadcast failed: %1$s Mute failed: %1$s - Microphone access is required to talk in this room. No permissions Nests Keeps audio playing while a room is open. @@ -846,7 +766,6 @@ Join nest Host Open - Recent chat No one is in the room right now. %1$d listening Host @@ -874,8 +793,6 @@ Audience Hands No one in the audience yet. - Send - Say something… No messages yet. Be the first to chat. React Edit room @@ -909,7 +826,6 @@ Action failed The action could not be prepared. Share room - Minimize Minimize to keep listening Audio dropped Loading room… @@ -942,7 +858,6 @@ Choose which MoQ host servers Amethyst publishes your nests to. The first entry is used by default when you start a new space. Your servers Saved as a kind-10112 replaceable event so other clients can read your preference. - Add a nest server Relay (WebTransport) URL Auth (JWT mint) URL Add @@ -955,13 +870,11 @@ Remove server No nest servers yet. Add one below or pick a recommended server. Videos - Articles Music Playlists Episodes Podcasts View episodes - Episodes No episodes found yet %1$d episode @@ -973,9 +886,6 @@ Track title Artist Artist name - Audio URL - https://… .mp3 - Cover image URL (optional) Album (optional) Duration in seconds (optional) Lyrics or credits (optional) @@ -985,7 +895,6 @@ Add to playlist You don\'t own any playlists yet. Use the field above to create one. Manage all playlists - New playlist Playlist name Create (untitled playlist) @@ -1025,9 +934,6 @@ Delete Bookmark List View Posts View Articles - View Links - View Hashtags - You do not have any bookmark lists yet. Tap the new button below to make one. Hashtag Sets You do not have any interest sets yet. Tap the new button below to make one. @@ -1047,7 +953,6 @@ Private Posts(%1$s) Public Posts Public Posts(%1$s) - Private Articles Private Articles(%1$s) Public Articles Public Articles(%1$s) @@ -1075,16 +980,6 @@ Move to Public Move to Private - Wallet Connect Service - Authorizes Amethyst to pay zaps without leaving the app. Keep the secret safe. - Wallet Connect Pubkey - Wallet Connect Relay - Wallet Connect Secret - Show secret key - nsec / hex private key - Connected - Not connected - Advanced: enter connection details manually Quick Zap Amounts Shown when pressing the zap button. Each amount can be paid by any rail the recipient supports — Lightning, Cashu, or on-chain (on-chain only for larger amounts). Tap an amount to remove it. If you leave it empty, it will open the dialog to insert an amount every time. Send on-chain instead @@ -1118,14 +1013,8 @@ See Relay Feed Pledge Amount in Sats - Post Poll - Required fields: - Zap recipients - Primary poll description… - Option Option %s Poll option description - Optional fields: Zap minimum Zap maximum Consensus @@ -1134,11 +1023,8 @@ Multiple choice Poll Closing Date & Time Poll closes in %1$s - Close after - days Unable to vote Poll is closed to new votes - Zap amount Only one vote per user is allowed on this type of poll "Looking for Event %1$s" @@ -1152,7 +1038,6 @@ Create and Add Poll authors can\'t vote in their own polls. - #zappoll What does this mean? This content is the same since the post @@ -1191,13 +1076,10 @@ Anonymous - Post as a new throwaway identity. Your account will not be linked to this reply. - This reply will be posted from a new anonymous identity File Server Choose a server to upload this file to - LnAddress or @User Media Servers @@ -1210,11 +1092,9 @@ Only cache profile pictures Restrict the local cache to profile pictures. Feed images and videos will be fetched directly from the original servers. - You have no NIP-96 servers set. You can use Amethyst\'s list, or add one below ↓ You have no Blossom servers set. You can use Amethyst\'s list, or add one below ↓ Recommended Media Servers - Built-in Media Servers Amethyst\'s default list. You can add them individually or add the list. Use Default List Add media server @@ -1239,45 +1119,27 @@ Done Error - Your relays (NIP-95) - Files are hosted by your relays. New NIP: check if they support Privacy Options - Tor/Orbot setup - Connect through your Orbot setup Adjust Tor Settings - Disconnect from your Orbot/Tor? - Your data will be immediately transferred in the regular network Yes No - Follow List All Follows All User Follows Default Follow List - Follows via Proxy Around Me Global Curated - Chess Mine Mute List Follow Lists These are follow lists designed for your own usage. You can follow users privately or publicly - Labeled Bookmarks - General Bookmarks - Public - Private - Mixed - - It seems you do not have any follow sets yet. - \nTap below to refresh, or tap the add buttons to create a new one. - New Add author to follow list Add or remove user from lists, or create a new list with this user. @@ -1286,23 +1148,9 @@ %1$s is a private member Add as public member Add as private member - Public Members - Private Members - Public Profiles - Private Profiles - member - members - No members Empty - %1$s is not in this list %1$s is not a member Your Lists and %1$s - Your Lists - No follow lists were found, or you don\'t have any follow lists. Tap below to refresh, or use the menu to create one. - There was a problem while fetching: %1$s - Make New List - New list with %1$s membership - Creates a new follow set, and adds %1$s as a %2$s member. New Follow List New Follow Pack Copy/Clone Follow List @@ -1324,15 +1172,6 @@ Default port is 9050 - - ## Connect through Tor with Orbot - \n\n1. Install [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) - \n2. Start Orbot - \n3. In Orbot, check the Socks port. The default uses 9050 - \n4. If necessary change the port in Orbot - \n5. Configure the Socks port in this screen - \n6. Press the Activate button to use Orbot as a proxy - Orbot Socks Port Active Tor Engine @@ -1391,8 +1230,6 @@ Make your own Invalid port number - Use Orbot - Disconnect Tor/Orbot DefaultChannelID New notification arrived @@ -1463,12 +1300,8 @@ Bluetooth Voice call Video call - Waiting for others to join\u2026 Add participant Search users\u2026 - Failed to start call - Failed to accept call - Failed to create call session Permission needed Amethyst needs microphone access to start a voice call. Please enable it in the app settings. Amethyst needs camera and microphone access to start a video call. Please enable them in the app settings. @@ -1507,6 +1340,8 @@ Split notifications by Follows Show two notification tabs — Following (people you follow) and Everyone. The unread indicator glows only for activity from people you follow. + Show Messages + Include direct and group messages on the Notification tab. Turn off to keep messages only in the Messages tab. Following Everyone @@ -1516,28 +1351,17 @@ Notify: - Join Conversation - User or Group\'s ID - npub, nevent or hex - Create - Join Today Content warning Warning: %1$s This post contains sensitive content which some people may find offensive or disturbing - Always hide sensitive content - Always show sensitive content - Always show content warnings Hide Show Warn - Recommends: - Filter spam from strangers - Warn when posts have reports from your follows Filter spam Hides posts from strangers that were exactly the same for 5 or more times @@ -1574,22 +1398,17 @@ The amount in bytes that was sent to this relay, including filters and events The amount in bytes that was received from this relay, including filters and events Events stored - An error occurred trying to get relay information from %1$s Owner Used By Service Key - Running %1$s - Running %1$s (%2$s) Version Software Contact Supported NIPs Supported Grasps - Admission Fees Admission Subscription Publication - Payments %1$s Payments url Target Audience Policies & Links @@ -1597,7 +1416,6 @@ Limitations Countries Languages - Tags Topics All Countries All Languages @@ -1612,66 +1430,50 @@ Open Read Write - RTT Network Type Supported NIPs Requirements - Last check %1$d ms Accepted Kinds Location Active Subscriptions - Pending Outbox Events REQ Subscriptions (%1$d) COUNT Subscriptions (%1$d) Outbox Events (%1$d) - No active subscriptions for this relay %1$d authors %1$d ids since %1$s until %1$s limit %1$d - Message length - Subscriptions - Filters - Subscription id length Min Prefix Max Event Tags - Content length Max Content Length Discards older than Accepts up to %1$s in the future %1$s ago - %1$s zeros %1$s bits Event Retention Content Size Connectivity Access Control Min PoW Difficulty - Auth Auth Required - Payment Payment Required Max Message Length Max Subscriptions Max Filters per Sub Max Limit (Events Returning) - Default Limit (Events Returning) Max SubID Length Cashu Token Mint: %1$s Redeem - Send to Zap Wallet - Open in Cashu Wallet Copy Token Open in Another App No Lightning Address set - Copied token to clipboard LIVE OFFLINE @@ -1765,7 +1567,6 @@ Marmot state reset. Failed to reset Marmot state: %1$s Always - Wifi-only Unmetered WiFi Never @@ -1796,7 +1597,6 @@ Profile Gallery Style Choose the gallery style - Load Image Spammers @@ -1811,13 +1611,9 @@ Nostr address was verified Nostr address failed verification Checking Nostr address - Select/Deselect all Default Reset to Defaults - Select a relay to continue - Forward Zaps to: - Supporting clients will forward zaps to the LNAddress or User Profile below instead of yours Expose Location as Adds a Geohash of your location to the post. The public will know you are within 5km (3mi) of the current location @@ -1826,7 +1622,6 @@ Only followers of the location will see it. Your general followers won\'t see it. Hashtag-exclusive Post - Only followers of the hashtag will see it. Your general followers won\'t see it. Comment on a website Comment on an external resource @@ -1850,9 +1645,7 @@ Upload an audio file Pick an MP3, WAV, or FLAC. It will be uploaded to your media server on Save. Audio file ready to upload - Uploading… Uploading cover + audio and publishing. This will keep going even if you leave the screen. - Upload failed: %1$s Edit playlist Edit playlist Title @@ -1877,14 +1670,10 @@ Adds sensitive content warning before showing your content. This is ideal for any NSFW content or content some people may find offensive or disturbing Reason (optional) - New Feature - Activating this mode requires Amethyst to send a NIP-17 message (GiftWrapped, Sealed Direct and Group Messages). NIP-17 is new and most clients have not implemented it yet. Make sure the receiver is using a compatible client. - Activate Public Group New Public or Private Group - Relay Private To Subject @@ -1900,10 +1689,7 @@ Paste from clipboard - Invalid NIP-47 URI - The URI %1$s is not a valid NIP-47 login URI. - Connect to new NWC wallet Wallet not found Amethyst couldn\'t find any wallet apps that support Nostr Wallet Connect (NWC). \n\nWhat you can do: @@ -1921,7 +1707,6 @@ Automatically load videos and GIFs Automatically play videos when visible on screen Show URL previews - When to load images Copy Stack @@ -1940,9 +1725,7 @@ Media added to your Profile Gallery Created at - Rules - About Us Guidelines Moderators @@ -1950,7 +1733,6 @@ Update your status - Error parsing error message Votes are weighted by the zap amount. You can set a minimum amount to avoid spammers and a maximum amount to avoid a large zappers taking over the poll. Use the same amount in both fields to make sure every vote is valued the same amount. Leave it empty to accept any amount. Unable to send zap @@ -1958,23 +1740,9 @@ Message %1$s OK - Failed to reach %1$s: %2$s - Failed to assemble NIP-11 url for %1$s: %2$s - Failed to reach %1$s: %2$s - Failed to parse response from %1$s: %2$s - Relay declined request %1$s: %2$s - Failed to reach %1$s: %2$s - Failed to parse result from %1$s: %2$s - %1$s failed with code %2$s - Active for: - Home - DMs - Chats - Global - Search Split and Forward Zaps Supporting clients will split and forward zaps to the users added here instead of yours @@ -1982,12 +1750,7 @@ Username or display name Missing lightning setup User %1$s does not have a lightning address set up to receive sats - Percentage - 25 - Splitting zaps with - Forwarding zaps to - Lightning wallets not found Paid Wallet %1$s Error opening signer app @@ -1997,7 +1760,6 @@ The codec or format isn\'t supported on this device (%1$s). Try opening it in your browser. Open in browser Sign request rejected - Signer Application Rejected Make sure the signer application has authorized this transaction No Wallets found to pay a lightning invoice (Error: %1$s). Please install a Lightning wallet to use zaps @@ -2019,13 +1781,9 @@ Could not pay invoice Could not withdraw - Could not setup Wallet Connect - Error parsing NIP-47 connection string. Check if this is correct with your Wallet provider: %1$s. Error: %2$s - Error parsing NIP-47 connection string. Check if this is correct with your Wallet provider: %1$s. Could not redeem Cashu Mint provided the following error message: %1$s - Cashu tokens already spent. Cashu Received %1$s sats were sent to your wallet. (Fees: %2$s sats) @@ -2035,33 +1793,20 @@ Your wallet connect provider returned the following error: %1$s - Could not connect to Tor Tor isn\'t connecting Amethyst couldn\'t finish bootstrapping Tor. Use a regular (non-Tor) connection so the feed can load? We\'ll remember this choice for the next hour and re-try Tor after that. Use regular connection Keep waiting - Download relay document unavailable Could not assemble LNUrl from Lightning Address \"%1$s\". Check the user\'s setup - The receiver\'s lightning service at %1$s is not available. It was calculated from the lightning address \"%2$s\". Error: %3$s. Check if the server is up and if the lightning address is correct - Could not resolve %1$s. Check if you are connected, if the server is up and if the lightning address %2$s is correct - Could not resolve %1$s. Check if you are connected, if the server is up and if the lightning address %2$s is correct.\n\nException was: %3$s - Could not fetch invoice from %1$s Could not fetch invoice from %1$s: %2$s - Error Parsing JSON from Lightning Address. Check the user\'s lightning setup Error Parsing JSON from %1$s. Check the user\'s lightning setup - Callback URL not found in the User\'s lightning address server configuration Callback URL not found from %1$s\'s response - Error Parsing JSON from Lightning Address\'s invoice fetch. Check the user\'s lightning setup - Error Parsing JSON from %1$s\'s invoice fetch. Check the user\'s lightning setup Incorrect invoice amount (%1$s sats) from %2$s. It should have been %3$s Unable to create a lightning invoice before sending the zap. The receiver\'s lightning wallet sent the following error: %1$s - Unable to create a lightning invoice. Message from %1$s: %2$s - Unable to create a lightning invoice before sending the zap. Element pr not found in the resulting JSON. - Unable to create a lightning invoice from %1$s: Element pr not found in the resulting JSON. Read-only user @@ -2095,14 +1840,12 @@ Hi %1$s, is this still available? Hi there, is this still available? - Sell an Item Title iPhone 13 Condition Category Price (in Sats) - 1000 Location City, State, Country @@ -2137,21 +1880,14 @@ Failed to upload media Could not open the compressed file - Error when compressing media: %1$s Uploading error: %1$s Server did not provide a URL after uploading Could not download uploaded media from the server Could not check downloaded file after upload: %1$s - Could not prepare local file to upload: %1$s Failed to upload to %1$s: %2$s - Failed to upload: %1$s Failed to delete: %1$s Media is too big for NIP-95 - Unable to load thumbnail - Could not prepare header information: %1$s - Compression Cancelled - Compression failed to return a file Encrypt files Encrypt files before uploading for privacy. Some servers may not accept encrypted files on free accounts. @@ -2183,27 +1919,18 @@ Edit draft Login with QR Code - Route Home - Search Discover Messages Notifications - Global Shorts - Pictures - Workouts Calendars Calendar lists Chess Wallet - Balance Send Receive Transactions - No wallet connected - Set up a Nostr Wallet Connect (NWC) connection in your zap settings to use the wallet. - Set Up Wallet sats Paste a BOLT-11 invoice Pay @@ -2231,8 +1958,6 @@ This will remove the wallet connection. You can always add it back later. Wallet Name My Wallet - Your Wallets - Manage Wallets No wallets connected Connect one or more NWC wallets to send and receive payments. Add NWC Connection @@ -2252,12 +1977,9 @@ Remove mint Add mint History - Edit wallet Nutzap key (advanced) A separate private key used only to receive NIP-61 nutzaps. Not your Nostr identity key. Generate a new key - Will invalidate any pending nutzaps locked to the current key. - Keep current key P2PK private key (hex) Edit mints Save changes @@ -2273,7 +1995,6 @@ Popular mints Matching mints - Recommend this mint Receive Send LN Send Token @@ -2354,10 +2075,6 @@ Save Rename Rename Wallet - Edit - Invalid NWC connection URI - Move Up - Move Down Onchain Transactions No on-chain address available for this account. No chain backend is configured. @@ -2434,18 +2151,14 @@ Payment sent (%1$d of %2$d receipts published), but the next receipt could not be published - Security Filters Import Follows New Post New Shorts: images or videos New Community Note New Product - New Geo-Exclusive Post New Article New Poll - New Zap Poll - New Regular Poll New Picture New Calendar Event Edit Calendar Event @@ -2462,8 +2175,6 @@ Upcoming Past - No upcoming or past calendar events from your selected feed yet. - No calendar collections yet. Your calendar is empty Events shared by people you follow appear here. Tap the + button to create your own. No collections yet @@ -2491,8 +2202,6 @@ Next week Previous day Next day - No events on this day - No events Continues Day %1$d of %2$d Add to phone calendar @@ -2554,7 +2263,6 @@ The picked image couldn\'t be uploaded. Try again or paste a URL. Participants (%1$d) Search name, npub, or nip-05 - Enter a valid npub… or 64-character hex pubkey. Remove participant Calendar reminders Send reminders @@ -2576,10 +2284,7 @@ New Short Video New Long Video - Title Summary (optional) - Cover image URL (optional) - Write your article in markdown… Preview Edit Add a header image @@ -2670,13 +2375,11 @@ Relay %1$s Expand relay list Note options - Relay list selector Poll Disable Poll Bitcoin Invoice Cancel Bitcoin Invoice - Cancel Sell an Item Zapraiser Cancel Zapraiser @@ -2684,8 +2387,6 @@ Location Remove Location - Zap splits - Cancel Zap split Add content warning Remove content warning @@ -2704,11 +2405,8 @@ Amethyst received a URI to open but that uri was invalid: %1$s DM Inbox Relays - Relays: %1$s - Using Regular Relays Set up your Private Inbox relays This setting lets everybody know which relays to use when sending messages to you. Without them you might miss some messages. - Good options are:\n - inbox.nostr.wine (paid)\n - auth.nostr1.com (free)\n - you.nostr1.com (personal relays - paid) Good options are:\n - auth.nostr1.com (free)\n - inbox.nostr.wine (paid)\n - relay.0xchat.com (free) Insert between 1–3 relays to serve as your private inbox. DM Inbox relays should accept any message from anyone, but only allow you to download them. Set up now @@ -2732,7 +2430,6 @@ Insert between 1–3 relays that receive notifications for you. Make sure they don\'t require payment or web of trust from the sender otherwise you will only receive notifications from payers or long-term users Good options are:\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social - DM Upload Relay Settings Reorder relay Public Outbox/Home Relays @@ -2749,15 +2446,11 @@ Relays where your MLS KeyPackages are published (MIP-00). Other users fetch these KeyPackages to invite you into Marmot group chats. Insert between 1–3 relays that accept KeyPackage events from you and allow public reads. Private Home Relays Insert between 1–3 relays to store events no one else can see, like your Drafts and/or app settings. Ideally, these relays are either local or require authentication before downloading each user\'s content. - General Relays - Amethyst uses these relays to download posts for you. Connected Relays Current list of relays being used - Recommended Relays - Add the following relays to your General Relays list in order to receive posts from the listed users. Search Relays 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. Local Relays @@ -2800,11 +2493,8 @@ This version was brought to you by: Version %1$s Thank you! - Max Limit Restricted Writes Forked from - FORK - Git Repository: %1$s Web: Clone: Open @@ -2835,23 +2525,16 @@ Edit Article Edit Post Proposal to improve a post - Summary of changes - Quick fixes… Accept the Suggestion Start video in a popup Download - Lyrics on - Lyrics off - Sealed message off. Click to turn on sealed message - Sealed message on. Click to turn off sealed message Send Play username as audio Pushpin Scan QR code - Navigate to the third-party wallet provider Alby Select date It\'s not possible to reply a draft note It\'s not possible to quote a draft note @@ -2898,8 +2581,6 @@ Loop Detected - The server detects an infinite loop while processing the request Network Authentication Required - The client must be authenticated to access the network - NIP-96 Servers - Add as many servers as you want. You can choose which one to use later when uploading your picture Blossom Servers Add as many servers as you want. You can choose which one to use later when uploading your picture @@ -2909,7 +2590,6 @@ Delete all Are you sure you want to delete all drafts? " +%1$s" - Stack: Torrent File Download @@ -2917,9 +2597,7 @@ No torrent apps installed to open and download the file. Event doesn\'t have enough information to build a magnet link - My Lists/Sets My Lists - Users Select an option to filter the feed Feeds Hashtags @@ -2953,7 +2631,6 @@ Public Message Chat Relay - The relay that all users of this chat connect to Share image… Unable to share image, please try again later… Share video… @@ -3004,7 +2681,6 @@ Would you like to send the recent crash report to Amethyst in a DM? No personal information will be shared Send it This message will disappear in %1$s - This message will disappear in %1$d days Select Signer Already in the list @@ -3030,7 +2706,6 @@ Pack name New Pack name Pack description - New Pack description Broadcast List Broadcast Pack @@ -3046,13 +2721,9 @@ Collapse Expand Retry Failed (%1$d) - +%1$d more broadcasts - " (%1$d in progress)" - %1$d/%2$d relays Timeout Retrying… Retry - View Dismiss %1$d/%2$d Broadcasting @@ -3081,7 +2752,6 @@ Restart Accept Decline - New Game New Chess Game Loading game\u2026 Game Not Found @@ -3237,23 +2907,13 @@ Profile to import from search, npub1…, alice@example.com Supports npub, nprofile, NIP-05, hex, and Namecoin (.bit) - Look Up Follow List Tip %1$d accounts found %1$d selected - Resolved via Namecoin - Now following %1$d accounts - Your feed is ready. - Skip - Search Another Follow %1$d accounts - Import More - Continue Skip for now - Resolving %1$s… Fetching follow list… No follows found - Following %1$d accounts… "Enter the profile of a friend or community leader. You can use their npub, NIP-05 address, or a Namecoin name like alice@example.bit or id/alice for blockchain-verified identities." Select All %1$d%% uptime @@ -3261,7 +2921,6 @@ Test Connection Testing servers… Connected - Failed Test Results Diagnostics Last test @@ -3274,9 +2933,6 @@ Trust Reject Relay Sync - Relay Sync - Re-publish your events across all known relays to keep your outbox, inbox, and DM relays up to date. Requires Wi-Fi — this may use a lot of data. - Open Relay Sync… What this does This tool scans every relay your app has seen and redistributes your events to the correct destinations: Download all events you authored and send them to your outbox relays. @@ -3286,14 +2942,9 @@ Use Mobile Data? Start Sync Start Anyway (mobile data) - Pause - Resume - Start Over Cancel Relays: %1$d / %2$d Events redistributed: %1$d new out of %2$d sent and %3$d received - Sync Paused - Completed %1$d of %2$d relays — %3$d events redistributed so far. Tap Resume to continue. Sync complete Forwarded %1$d events to destination relays out of %2$d received. %1$d events accepted as new by destination relays. @@ -3308,16 +2959,13 @@ sent %1$s recv %1$s new %1$s - no events Bitcoin Explorer (OTS) - events events from you events to you searchable events DMs profiles outbox lists - relay settings Last seen %1$s ago Last seen on %1$s (%2$s ago) Last seen just now @@ -3401,7 +3049,6 @@ HLS Upload - Publish multi-resolution HLS to your media server Pick a video Your video will be transcoded into multiple resolutions so viewers get smooth playback on any connection. Change @@ -3416,10 +3063,6 @@ H.265 not available on this device — falling back to H.264. Renditions Source resolution: %1$d×%2$d - Will produce: %1$s - (%1$s skipped — above source) - %1$d kbps - above source — will be skipped Publish HD video Publishing “%1$s”… Transcoding %1$s @@ -3431,7 +3074,6 @@ Video published Your HD video is live on Nostr. Something went wrong - View note Done Try again @@ -3447,20 +3089,14 @@ Attestation Valid Invalid - Accepted - Rejected Verifying - Verified Revoked Valid from %1$s Valid to %1$s Attestation Request - Requesting attestation for an event Attestor Recommendation Recommended for kinds: Attestor Proficiency - Proficient in verifying kinds: %1$s - Attests to Requests attestation to Date Range @@ -3468,10 +3104,7 @@ Until Now All time - Last sync: %1$s - Since Last Sync Web Bookmarks - No web bookmarks yet. Tap + to add one. Add Web Bookmark Edit Web Bookmark URL @@ -3529,13 +3162,10 @@ https://example.com/image.jpg Website URL (optional) https://example.com - Deadline (optional) Set a deadline New Goal - Create Goal Request to Vanish Request relays to permanently delete all your data up to the selected date. This action is based on NIP-62 and is legally binding in some jurisdictions. - Select a relay Target Relays ALL RELAYS This will request ALL relays to delete everything associated with your key up to the selected date. This event will be broadcast as widely as possible. This action cannot be undone. @@ -3551,7 +3181,6 @@ Select date Select time Vanish History - Refresh These are your past Request to Vanish events found on connected relays. Relays tagged in these events should not hold any of your data from before the event date. No vanish requests found You haven\'t sent any Request to Vanish events yet. @@ -3594,7 +3223,6 @@ Ban Event Allow Kind Block IP - Pubkey (hex) Event ID (hex) Kind number IP address @@ -3605,7 +3233,6 @@ Relay Name Relay Description Relay Icon URL - Manage Relay Manage Members Members of %1$s @@ -3678,7 +3305,6 @@ Emoji pack actions My Emoji Packs Emojis - Browse Emoji Sets Private Private emoji Public emojis are visible to everyone and appear in your reaction menu and \":\" autocomplete picker when this pack is in your emoji list. @@ -3704,4 +3330,90 @@ Nowhere Drop Nowhere Art Nowhere Forum + + + Marmot Groups + Create Group + Create Marmot Group + A new MLS group will be created. You can add members after. + Marmot Group + Group %1$s… + %1$s… + Known + Known (%1$d) + New Requests + New Requests (%1$d) + No groups yet + Create a group or accept an invitation. + No invitations + When someone adds you to a group it will show up here until you reply. + No messages yet + + %1$d msg + %1$d msgs + + + %1$d member + %1$d members + + Group name + Enter group name + Enter group description (optional) + Changes will be committed to the group via MLS and propagated to all members. + Group info updated + Failed to update: %1$s + Failed to create group: %1$s + KeyPackage Relays not set + You don\'t have a KeyPackage Relay List yet (MIP-00). This list tells other people where your KeyPackage is published so they can invite you to group chats.\n\nUse your current outbox relays for this? + Use outbox relays + Skip for now + Group Info + Edit Group Info + Leave Group + this group + Are you sure you want to leave \"%1$s\"? You will no longer receive messages from this group. + Failed to leave group: %1$s + Adding %1$s… + Failed to add %1$s: %2$s + unknown error + They must have published a KeyPackage (kind:30443) to be added. + Add to group + Add member + Add Member + Name, npub, or NIP-05 + (you) + - admin + Member removed + Failed to remove member: %1$s + Remove Member + Are you sure you want to remove \"%1$s\" from this group? + Grant + Grant admin privileges + Grant Admin Privileges + Make \"%1$s\" an admin of this group? Admins can add or remove members, change group info, and grant admin privileges to other members. + Admin privileges granted + Failed to grant admin: %1$s + Revoke + Revoke admin privileges + Revoke Admin Privileges + Revoke admin privileges from \"%1$s\"? They will remain a member of the group. + Admin privileges revoked + Failed to revoke admin: %1$s + Relays + no events yet + last event%1$s + Not a member of this group + + Copy + Reset to auto-select + Explorer API base URL + Pay Invoice from the DVM + Pay %1$s sats to the DVM + The receiver\'s lightning service at %1$s is not available. It was calculated from the lightning address \"%2$s\". Error: %3$s. Check if the server is up and if the lightning address is correct + Could not resolve %1$s. Check if you are connected, if the server is up and if the lightning address %2$s is correct.\n\nException was: %3$s + Error Parsing JSON from %1$s\'s invoice fetch. Check the user\'s lightning setup + Unable to create a lightning invoice. Message from %1$s: %2$s + Unable to create a lightning invoice from %1$s: Element pr not found in the resulting JSON. + Amy Debug + Amy Benchmark diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/service/uploads/hls/HlsVideoEventBuilderTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/service/uploads/hls/HlsVideoEventBuilderTest.kt index 84e6c042a7..1d7223b49c 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/service/uploads/hls/HlsVideoEventBuilderTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/service/uploads/hls/HlsVideoEventBuilderTest.kt @@ -216,21 +216,17 @@ class HlsVideoEventBuilderTest { } @Test - fun horizontalTemplateCarriesAutoGeneratedAltTag() { + fun horizontalTemplateOmitsDeprecatedAltTag() { val result = HlsVideoEventBuilder.build(input(landscapeRenditions)) val tags = (result.template as HlsVideoEventTemplate.Horizontal).template.tags - val alt = tags.findTag("alt") - assertNotNull(alt) - assertEquals(VideoHorizontalEvent.ALT_DESCRIPTION, alt!![1]) + assertNull(tags.findTag("alt")) } @Test - fun verticalTemplateCarriesVerticalAltTag() { + fun verticalTemplateOmitsDeprecatedAltTag() { val result = HlsVideoEventBuilder.build(input(portraitRenditions)) val tags = (result.template as HlsVideoEventTemplate.Vertical).template.tags - val alt = tags.findTag("alt") - assertNotNull(alt) - assertEquals(VideoVerticalEvent.ALT_DESCRIPTION, alt!![1]) + assertNull(tags.findTag("alt")) } @Test diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarNestedScrollTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarNestedScrollTest.kt index 5f3a00a834..cad98a6229 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarNestedScrollTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarNestedScrollTest.kt @@ -79,17 +79,17 @@ class DisappearingBarNestedScrollTest { } @Test - fun `scrolling content down reveals both bars from a hidden state, damped`() { + fun `scrolling content down reveals both bars from a hidden state`() { val state = state(topLimit = 100f, bottomLimit = 50f) state.topHeightOffset = -100f state.bottomHeightOffset = -50f val connection = nsc(state) - // Reveal is damped by REVEAL_SENSITIVITY (0.5), so a 30px drag only reveals 15px. + // Reveal tracks the finger 1:1, so a 30px drag reveals 30px. connection.onPostScroll(Offset(0f, 30f), Offset(0f, 0f), NestedScrollSource.UserInput) - assertEquals(-85f, state.topHeightOffset) - assertEquals(-35f, state.bottomHeightOffset) + assertEquals(-70f, state.topHeightOffset) + assertEquals(-20f, state.bottomHeightOffset) } @Test @@ -100,26 +100,27 @@ class DisappearingBarNestedScrollTest { val connection = nsc(state) // The list consumed 20px of a 40px reveal drag; 20 more was left as overscroll. - // The bars should move by the total 40 (damped to 20 on reveal), not just one half. + // The bars should move by the total 40, not just one of the halves. connection.onPostScroll(Offset(0f, 20f), Offset(0f, 20f), NestedScrollSource.UserInput) - assertEquals(-30f, state.topHeightOffset) - assertEquals(-30f, state.bottomHeightOffset) + assertEquals(-10f, state.topHeightOffset) + assertEquals(-10f, state.bottomHeightOffset) } @Test - fun `revealing is less sensitive than hiding for the same drag distance`() { + fun `revealing tracks the finger 1 to 1, matching the hide rate so the bar stays glued to content`() { // Hiding a 40px drag moves the bars the full 40px... val hiding = state(topLimit = 100f, bottomLimit = 100f) nsc(hiding).onPostScroll(Offset(0f, -40f), Offset(0f, 0f), NestedScrollSource.UserInput) assertEquals(-40f, hiding.topHeightOffset) - // ...while revealing the same 40px from fully hidden only brings back 20px. + // ...and revealing the same 40px from fully hidden brings back the full 40px, so when the + // list returns to the top the bar is fully revealed with no blank band beneath it. val revealing = state(topLimit = 100f, bottomLimit = 100f) revealing.topHeightOffset = -100f revealing.bottomHeightOffset = -100f nsc(revealing).onPostScroll(Offset(0f, 40f), Offset(0f, 0f), NestedScrollSource.UserInput) - assertEquals(-80f, revealing.topHeightOffset) + assertEquals(-60f, revealing.topHeightOffset) } @Test diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarStateTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarStateTest.kt index bae001b849..52ba051e3e 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarStateTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingBarStateTest.kt @@ -93,4 +93,49 @@ class DisappearingBarStateTest { assertTrue("top bar overshot to $peakTop", peakTop <= 0.5f) assertTrue("bottom bar overshot to $peakBottom", peakBottom <= 0.5f) } + + @Test + fun `a partial collapse that never reached the hidden edge settles back into view`() = + runTest { + // The bar is past the halfway point but was only ever scrolled here from the top — it + // never reached -limit, so the content hasn't moved a full bar height. Snapping it fully + // hidden would expose a blank band, so it must settle back to visible instead. + val state = state(topLimit = 100f, bottomLimit = 50f) + state.topHeightOffset = -80f + + peakOffsetsDuring(state) { state.settleToNearestEdge() } + + assertEquals(0f, state.topHeightOffset, 0.01f) + } + + @Test + fun `a small reveal after fully hiding settles back to hidden, not into view`() = + runTest { + // Drive the bar to its hidden edge first (content has now scrolled a full bar height), + // then nudge it back a little — the small reverse drag a finger makes catching a scroll. + // Because it genuinely reached the hidden edge, snapping back hidden leaves no gap, so a + // sub-halfway reveal must not pop the chrome back open. + val state = state(topLimit = 100f, bottomLimit = 50f) + state.topHeightOffset = -100f + state.topHeightOffset = -90f + + peakOffsetsDuring(state) { state.settleToNearestEdge() } + + assertEquals(-100f, state.topHeightOffset, 0.01f) + } + + @Test + fun `returning fully into view re-arms the gap guard so the next near-top collapse settles open`() = + runTest { + // Hide fully (arms the latch), come all the way back to visible (disarms it), then do a + // small near-top collapse again. It must settle open, proving the latch resets at 0. + val state = state(topLimit = 100f, bottomLimit = 50f) + state.topHeightOffset = -100f + state.topHeightOffset = 0f + state.topHeightOffset = -80f + + peakOffsetsDuring(state) { state.settleToNearestEdge() } + + assertEquals(0f, state.topHeightOffset, 0.01f) + } } diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationPublicChatReplyTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationPublicChatReplyTest.kt new file mode 100644 index 0000000000..92022ae414 --- /dev/null +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/dal/NotificationPublicChatReplyTest.kt @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.dal + +import com.vitorpamplona.amethyst.commons.model.AddressableNote +import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.model.UserContext +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent +import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test + +/** + * Public chats (NIP-28, kind 42) frequently reply to a user without adding a + * `p` tag. [NotificationFeedFilter.isNotifiablePublicChatReply] recovers those + * by walking the cached reply chain for one of the user's own messages — a + * direct reply to my message, or a later message in a thread I am already part + * of — so the push dispatcher and the in-app feed can relax the p-tag gate for + * exactly these events and nothing else. + */ +class NotificationPublicChatReplyTest { + // User eagerly pins a few addressable note shells on construction; empty + // shells are enough since the relevance check only reads pubkeyHex. + private val noContext = UserContext { addr -> AddressableNote(addr) } + + private val me = "1".repeat(64) + private val other = "2".repeat(64) + private val sig = "f".repeat(128) + + private fun authoredNote( + id: String, + authorHex: String, + parents: List = emptyList(), + ): Note = + Note(id).apply { + author = User(authorHex, noContext) + replyTo = parents + } + + private fun channelMessage( + id: String, + authorHex: String, + parents: List, + ): Note = + Note(id).apply { + event = ChannelMessageEvent(id, authorHex, 1000, emptyArray(), "hi", sig) + author = User(authorHex, noContext) + replyTo = parents + } + + @Test + fun `direct reply to my channel message without a p-tag is notifiable`() { + val myMessage = channelMessage("a".repeat(64), me, emptyList()) + val reply = channelMessage("b".repeat(64), other, listOf(myMessage)) + + assertTrue(NotificationFeedFilter.isNotifiablePublicChatReply(reply, me)) + assertTrue(NotificationFeedFilter.tagsAnEventByUser(reply, me)) + } + + @Test + fun `reply two hops above me in a thread i posted in is notifiable`() { + // root(other) <- myMessage(me) <- someoneElse(other) <- newReply(other) + // newReply's immediate parent is `other`, so a single-hop check would + // miss me — this only passes if the walk climbs to the grandparent. + val root = channelMessage("d".repeat(64), other, emptyList()) + val myMessage = channelMessage("e".repeat(64), me, listOf(root)) + val someoneElse = channelMessage("9".repeat(64), other, listOf(myMessage)) + val newReply = channelMessage("8".repeat(64), other, listOf(someoneElse)) + + // Sanity: the immediate parent is not me, so this is a true multi-hop hit. + assertFalse(newReply.replyTo?.any { it.author?.pubkeyHex == me } == true) + assertTrue(NotificationFeedFilter.isNotifiablePublicChatReply(newReply, me)) + } + + @Test + fun `channel message in a thread i never posted in is not notifiable`() { + val root = channelMessage("a1".repeat(32), other, emptyList()) + val reply = channelMessage("a2".repeat(32), other, listOf(root)) + + assertFalse(NotificationFeedFilter.isNotifiablePublicChatReply(reply, me)) + assertFalse(NotificationFeedFilter.tagsAnEventByUser(reply, me)) + } + + @Test + fun `unloaded ancestor without an author does not match`() { + // Parent shell present in cache but its event/author hasn't loaded yet. + val unloadedParent = Note("a3".repeat(32)) + val reply = channelMessage("a4".repeat(32), other, listOf(unloadedParent)) + + assertFalse(NotificationFeedFilter.isNotifiablePublicChatReply(reply, me)) + } + + @Test + fun `non channel replies are out of scope for the public-chat relaxation`() { + // A kind-1 reply to my note must NOT be picked up by the public-chat + // path — the normal p-tag gate governs those. + val myNote = authoredNote("a5".repeat(32), me) + val reply = + Note("a6".repeat(32)).apply { + event = TextNoteEvent("a6".repeat(32), other, 1000, emptyArray(), "hi", sig) + author = User(other, noContext) + replyTo = listOf(myNote) + } + + assertFalse(NotificationFeedFilter.isNotifiablePublicChatReply(reply, me)) + } +} diff --git a/cli/DEVELOPMENT.md b/cli/DEVELOPMENT.md index 00fd9a4bf9..b9f37b73b8 100644 --- a/cli/DEVELOPMENT.md +++ b/cli/DEVELOPMENT.md @@ -85,7 +85,7 @@ cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/ ├── stores/FileStores.kt # File-backed MLS / KP / message stores ├── secrets/ # SecretStore backends (keychain / ncryptsec / plaintext) └── commands/ - ├── Commands.kt # dispatcher tables + ├── Router.kt # `route(...)` shared sub-verb dispatcher ├── UseCommand.kt # `amy use NAME` — pin active account ├── InitCommands.kt # init, whoami ├── CreateCommand.kt # full bootstrap (→ commons/account/) @@ -111,18 +111,19 @@ host. Never add a Gradle dependency on `:amethyst` or `:desktopApp`. **`Context.kt` is the backbone.** Most commands follow this template: ```kotlin -val ctx = Context.open(dataDir) -try { +Context.open(dataDir).use { ctx -> // .use closes the Context on exit ctx.prepare() // restore MLS state + connect relays ctx.syncIncoming() // pull new gift-wraps + group events // ...call into commons/ or quartz/ to build an event... val ack = ctx.publish(event, targets) Output.emit(mapOf(...)) -} finally { - ctx.close() // flush RunState, disconnect -} + return 0 +} // close() flushes RunState + disconnects ``` +`Context` is `AutoCloseable`, so wrap it in `use { }` rather than a +hand-rolled `try { } finally { ctx.close() }`. + --- ## How to add a command @@ -179,20 +180,15 @@ import com.vitorpamplona.amethyst.cli.DataDir import com.vitorpamplona.amethyst.cli.Output object NoteCommands { - suspend fun dispatch(dataDir: DataDir, tail: Array): Int { - if (tail.isEmpty()) return Output.error("bad_args", "note ") - val rest = tail.drop(1).toTypedArray() - return when (tail[0]) { - "publish" -> publish(dataDir, rest) - else -> Output.error("bad_args", "note ${tail[0]}") - } - } + suspend fun dispatch(dataDir: DataDir, tail: Array): Int = + route("note", tail, "note ", mapOf( + "publish" to { rest -> publish(dataDir, rest) }, + )) private suspend fun publish(dataDir: DataDir, rest: Array): Int { val args = Args(rest) val text = args.positional(0, "text") - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val event = com.vitorpamplona.amethyst.commons.note.buildTextNote(ctx.signer, text) val ack = ctx.publish(event, ctx.outboxRelays()) @@ -202,13 +198,15 @@ object NoteCommands { "published_to" to ack.filterValues { it }.keys.map { it.url }, )) return 0 - } finally { ctx.close() } + } } } ``` -Wire it into `Commands.kt`, add a top-level branch in `Main.kt`'s -`dispatch`, and extend `printUsage()`. Keep the command tour in +The shared `route(name, tail, usage, routes)` helper (in `Router.kt`) +handles the empty-input and unknown-verb `bad_args` cases, so each +`dispatch` is just the verb→handler map. Add a top-level branch in +`Main.kt`'s `dispatch` and extend `printUsage()`. Keep the command tour in [README.md](./README.md) and the parity matrix in [ROADMAP.md](./ROADMAP.md) in sync. diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt index b50689a36d..6ab7d37abb 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt @@ -34,6 +34,7 @@ import com.vitorpamplona.quartz.marmot.mip03GroupMessages.GroupEvent import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.crypto.verify +import com.vitorpamplona.quartz.nip01Core.jackson.JacksonMapper import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.publishAndConfirmDetailed @@ -128,12 +129,14 @@ class Context( * humans inspect these files. Verification always re-canonicalises, * so the stored bytes never feed back into a signature check. */ - val store: IEventStore by lazy { - FsEventStore( - root = dataDir.eventsDir.toPath(), - eventToJson = com.vitorpamplona.quartz.nip01Core.jackson.JacksonMapper::toJsonPretty, - ) - } + private val storeDelegate: Lazy = + lazy { + FsEventStore( + root = dataDir.eventsDir.toPath(), + eventToJson = JacksonMapper::toJsonPretty, + ) + } + val store: IEventStore by storeDelegate /** Fully-wired manager. Call [prepare] once before use to load persisted state. */ val marmot: MarmotManager = MarmotManager(signer, mlsStore, messageStore, keyPackageStore) @@ -611,25 +614,14 @@ class Context( } // Only close the store if it was actually opened — by-lazy // otherwise allocates the lock channel just to release it. - if (storeIsInitialized()) { + if (storeDelegate.isInitialized()) { try { - store.close() + storeDelegate.value.close() } catch (_: Exception) { } } } - private fun storeIsInitialized(): Boolean { - // Reflect on the lazy delegate to avoid forcing initialisation in close(). - return try { - val field = javaClass.getDeclaredField("store\$delegate").apply { isAccessible = true } - val delegate = field.get(this) as Lazy<*> - delegate.isInitialized() - } catch (_: Throwable) { - false - } - } - companion object { /** * Lookback applied to the gift-wrap `since` filter to compensate for diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Main.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Main.kt index 5ddad30bd8..e5f8cde7d2 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Main.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Main.kt @@ -20,7 +20,28 @@ */ package com.vitorpamplona.amethyst.cli -import com.vitorpamplona.amethyst.cli.commands.Commands +import com.vitorpamplona.amethyst.cli.commands.AwaitCommands +import com.vitorpamplona.amethyst.cli.commands.CreateCommand +import com.vitorpamplona.amethyst.cli.commands.DebitCommands +import com.vitorpamplona.amethyst.cli.commands.DmCommands +import com.vitorpamplona.amethyst.cli.commands.FollowCommand +import com.vitorpamplona.amethyst.cli.commands.GroupCommands +import com.vitorpamplona.amethyst.cli.commands.InitCommands +import com.vitorpamplona.amethyst.cli.commands.KeyPackageCommands +import com.vitorpamplona.amethyst.cli.commands.LoginCommand +import com.vitorpamplona.amethyst.cli.commands.MarmotResetCommand +import com.vitorpamplona.amethyst.cli.commands.MessageCommands +import com.vitorpamplona.amethyst.cli.commands.NappletCommands +import com.vitorpamplona.amethyst.cli.commands.NotesCommands +import com.vitorpamplona.amethyst.cli.commands.NsiteCommands +import com.vitorpamplona.amethyst.cli.commands.OfferCommands +import com.vitorpamplona.amethyst.cli.commands.ProfileCommands +import com.vitorpamplona.amethyst.cli.commands.RelayCommands +import com.vitorpamplona.amethyst.cli.commands.SearchCommand +import com.vitorpamplona.amethyst.cli.commands.StoreCommands +import com.vitorpamplona.amethyst.cli.commands.UseCommand +import com.vitorpamplona.amethyst.cli.commands.ZapCommand +import com.vitorpamplona.amethyst.cli.commands.route import com.vitorpamplona.amethyst.cli.secrets.SecretStore import kotlinx.coroutines.runBlocking import kotlin.system.exitProcess @@ -118,86 +139,31 @@ private suspend fun dispatch(argv: Array): Int { // resolve "multiple accounts, ambiguous" cases) — so it skips // DataDir.resolve. Other commands fall through to the normal path. if (head == "use") { - return com.vitorpamplona.amethyst.cli.commands.UseCommand - .run(tail) + return UseCommand.run(tail) } val secrets = SecretStore.from(backendFlag = secretBackendFlag, passphraseFile = passphraseFileFlag) val dataDir = DataDir.resolve(accountFlag = accountFlag, secrets = secrets) return when (head) { - "init" -> { - Commands.init(dataDir, Args(tail)) - } - - "create" -> { - Commands.create(dataDir, tail) - } - - "login" -> { - Commands.login(dataDir, tail) - } - - "whoami" -> { - Commands.whoami(dataDir) - } - - "relay" -> { - Commands.relay(dataDir, tail) - } - - "marmot" -> { - marmotDispatch(dataDir, tail) - } - - "dm" -> { - Commands.dm(dataDir, tail) - } - - "profile" -> { - Commands.profile(dataDir, tail) - } - - "notes" -> { - Commands.notes(dataDir, tail) - } - - "nsite" -> { - Commands.nsite(dataDir, tail) - } - - "napplet" -> { - Commands.napplet(dataDir, tail) - } - - "store" -> { - Commands.store(dataDir, tail) - } - - "follow" -> { - Commands.follow(dataDir, tail) - } - - "unfollow" -> { - Commands.unfollow(dataDir, tail) - } - - "search" -> { - Commands.search(dataDir, tail) - } - - "zap" -> { - Commands.zap(dataDir, tail) - } - - "offer" -> { - Commands.offer(dataDir, tail) - } - - "debit" -> { - Commands.debit(dataDir, tail) - } - + "init" -> InitCommands.init(dataDir, Args(tail)) + "create" -> CreateCommand.run(dataDir, tail) + "login" -> LoginCommand.run(dataDir, tail) + "whoami" -> InitCommands.whoami(dataDir) + "relay" -> RelayCommands.dispatch(dataDir, tail) + "marmot" -> marmotDispatch(dataDir, tail) + "dm" -> DmCommands.dispatch(dataDir, tail) + "profile" -> ProfileCommands.dispatch(dataDir, tail) + "notes" -> NotesCommands.dispatch(dataDir, tail) + "nsite" -> NsiteCommands.dispatch(dataDir, tail) + "napplet" -> NappletCommands.dispatch(dataDir, tail) + "store" -> StoreCommands.dispatch(dataDir, tail) + "follow" -> FollowCommand.follow(dataDir, tail) + "unfollow" -> FollowCommand.unfollow(dataDir, tail) + "search" -> SearchCommand.dispatch(dataDir, tail) + "zap" -> ZapCommand.dispatch(dataDir, tail) + "offer" -> OfferCommands.dispatch(dataDir, tail) + "debit" -> DebitCommands.dispatch(dataDir, tail) else -> { System.err.println("unknown subcommand: $head") printUsage() @@ -209,41 +175,20 @@ private suspend fun dispatch(argv: Array): Int { private suspend fun marmotDispatch( dataDir: DataDir, tail: Array, -): Int { - if (tail.isEmpty()) { - printUsage() - return 2 - } - val head = tail[0] - val rest = tail.drop(1).toTypedArray() - return when (head) { - "key-package" -> { - Commands.keyPackage(dataDir, rest) - } - - "group" -> { - Commands.group(dataDir, rest) - } - - "message" -> { - Commands.message(dataDir, rest) - } - - "await" -> { - Commands.await(dataDir, rest) - } - - "reset" -> { - Commands.reset(dataDir, rest) - } - - else -> { - System.err.println("unknown marmot subcommand: $head") - printUsage() - 2 - } - } -} +): Int = + route( + name = "marmot", + tail = tail, + usage = "marmot ", + routes = + mapOf( + "key-package" to { rest -> KeyPackageCommands.dispatch(dataDir, rest) }, + "group" to { rest -> GroupCommands.dispatch(dataDir, rest) }, + "message" to { rest -> MessageCommands.dispatch(dataDir, rest) }, + "await" to { rest -> AwaitCommands.dispatch(dataDir, rest) }, + "reset" to { rest -> MarmotResetCommand.run(dataDir, rest) }, + ), + ) private enum class GlobalFlag( val long: String, diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/AwaitCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/AwaitCommands.kt index eeea8b7458..0ad6e869b0 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/AwaitCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/AwaitCommands.kt @@ -42,20 +42,21 @@ object AwaitCommands { suspend fun dispatch( dataDir: DataDir, tail: Array, - ): Int { - if (tail.isEmpty()) return Output.error("bad_args", "await ") - val rest = tail.drop(1).toTypedArray() - return when (tail[0]) { - "key-package" -> awaitKeyPackage(dataDir, rest) - "group" -> awaitGroup(dataDir, rest) - "member" -> awaitMember(dataDir, rest) - "admin" -> awaitAdmin(dataDir, rest) - "message" -> awaitMessage(dataDir, rest) - "rename" -> awaitRename(dataDir, rest) - "epoch" -> awaitEpoch(dataDir, rest) - else -> Output.error("bad_args", "await ${tail[0]}") - } - } + ): Int = + route( + "await", + tail, + "await ", + mapOf( + "key-package" to { rest -> awaitKeyPackage(dataDir, rest) }, + "group" to { rest -> awaitGroup(dataDir, rest) }, + "member" to { rest -> awaitMember(dataDir, rest) }, + "admin" to { rest -> awaitAdmin(dataDir, rest) }, + "message" to { rest -> awaitMessage(dataDir, rest) }, + "rename" to { rest -> awaitRename(dataDir, rest) }, + "epoch" to { rest -> awaitEpoch(dataDir, rest) }, + ), + ) private suspend fun awaitKeyPackage( dataDir: DataDir, @@ -64,8 +65,7 @@ object AwaitCommands { if (rest.isEmpty()) return Output.error("bad_args", "await key-package ") val args = Args(rest.drop(1).toTypedArray()) val timeoutSecs = args.longFlag("timeout", 30) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val target = ctx.requireUserHex(rest[0]) val filter = ctx.marmot.subscriptionManager.keyPackageFilter(target) @@ -112,8 +112,6 @@ object AwaitCommands { delay(2_000) } throw AwaitTimeout("no KeyPackage for $target within ${timeoutSecs}s") - } finally { - ctx.close() } } @@ -124,8 +122,7 @@ object AwaitCommands { val args = Args(rest) val wantedName = args.flag("name") val timeoutSecs = args.longFlag("timeout", 30) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val deadline = System.currentTimeMillis() + timeoutSecs * 1000 while (System.currentTimeMillis() < deadline) { @@ -148,8 +145,6 @@ object AwaitCommands { delay(1_500) } throw AwaitTimeout("no group with name=$wantedName within ${timeoutSecs}s") - } finally { - ctx.close() } } @@ -197,8 +192,7 @@ object AwaitCommands { val args = Args(rest.drop(1).toTypedArray()) val wantedName = args.requireFlag("name") val timeoutSecs = args.longFlag("timeout", 30) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = ctx.resolveGroupId(rest[0]) val deadline = System.currentTimeMillis() + timeoutSecs * 1000 @@ -212,8 +206,6 @@ object AwaitCommands { delay(1_500) } throw AwaitTimeout("group $gid never renamed to $wantedName within ${timeoutSecs}s") - } finally { - ctx.close() } } @@ -225,8 +217,7 @@ object AwaitCommands { val args = Args(rest.drop(1).toTypedArray()) val min = args.longFlag("min", 1) val timeoutSecs = args.longFlag("timeout", 30) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = ctx.resolveGroupId(rest[0]) val deadline = System.currentTimeMillis() + timeoutSecs * 1000 @@ -240,8 +231,6 @@ object AwaitCommands { delay(1_500) } throw AwaitTimeout("group $gid epoch never reached $min within ${timeoutSecs}s") - } finally { - ctx.close() } } @@ -253,8 +242,7 @@ object AwaitCommands { val args = Args(rest.drop(1).toTypedArray()) val needle = args.requireFlag("match") val timeoutSecs = args.longFlag("timeout", 30) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = ctx.resolveGroupId(rest[0]) val deadline = System.currentTimeMillis() + timeoutSecs * 1000 @@ -285,8 +273,6 @@ object AwaitCommands { delay(1_500) } throw AwaitTimeout("no message matching '$needle' in $gid within ${timeoutSecs}s") - } finally { - ctx.close() } } @@ -304,8 +290,7 @@ object AwaitCommands { if (rest.size <= targetIdx) return Output.error("bad_args", usage) val args = Args(rest.drop(targetIdx + 1).toTypedArray()) val timeoutSecs = args.longFlag("timeout", 30) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val deadline = System.currentTimeMillis() + timeoutSecs * 1000 while (System.currentTimeMillis() < deadline) { @@ -318,8 +303,6 @@ object AwaitCommands { delay(1_500) } throw AwaitTimeout("condition never satisfied within ${timeoutSecs}s ($usage)") - } finally { - ctx.close() } } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/Commands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/Commands.kt deleted file mode 100644 index 0859b4dc8f..0000000000 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/Commands.kt +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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.cli.commands - -import com.vitorpamplona.amethyst.cli.Args -import com.vitorpamplona.amethyst.cli.DataDir - -/** - * Tiny dispatcher over the per-verb command groups. Each top-level subcommand - * (`init`, `relay`, `group`, `message`, …) gets its own file so no single - * file is too big to edit safely. - */ -object Commands { - suspend fun init( - dataDir: DataDir, - args: Args, - ): Int = InitCommands.init(dataDir, args) - - suspend fun create( - dataDir: DataDir, - tail: Array, - ): Int = CreateCommand.run(dataDir, tail) - - suspend fun login( - dataDir: DataDir, - tail: Array, - ): Int = LoginCommand.run(dataDir, tail) - - suspend fun whoami(dataDir: DataDir): Int = InitCommands.whoami(dataDir) - - suspend fun relay( - dataDir: DataDir, - tail: Array, - ): Int = RelayCommands.dispatch(dataDir, tail) - - suspend fun keyPackage( - dataDir: DataDir, - tail: Array, - ): Int = KeyPackageCommands.dispatch(dataDir, tail) - - suspend fun group( - dataDir: DataDir, - tail: Array, - ): Int = GroupCommands.dispatch(dataDir, tail) - - suspend fun message( - dataDir: DataDir, - tail: Array, - ): Int = MessageCommands.dispatch(dataDir, tail) - - suspend fun await( - dataDir: DataDir, - tail: Array, - ): Int = AwaitCommands.dispatch(dataDir, tail) - - suspend fun reset( - dataDir: DataDir, - tail: Array, - ): Int = MarmotResetCommand.run(dataDir, tail) - - suspend fun dm( - dataDir: DataDir, - tail: Array, - ): Int = DmCommands.dispatch(dataDir, tail) - - suspend fun profile( - dataDir: DataDir, - tail: Array, - ): Int = ProfileCommands.dispatch(dataDir, tail) - - suspend fun notes( - dataDir: DataDir, - tail: Array, - ): Int = NotesCommands.dispatch(dataDir, tail) - - suspend fun nsite( - dataDir: DataDir, - tail: Array, - ): Int = NsiteCommands.dispatch(dataDir, tail) - - suspend fun napplet( - dataDir: DataDir, - tail: Array, - ): Int = NappletCommands.dispatch(dataDir, tail) - - suspend fun store( - dataDir: DataDir, - tail: Array, - ): Int = StoreCommands.dispatch(dataDir, tail) - - suspend fun follow( - dataDir: DataDir, - tail: Array, - ): Int = FollowCommand.follow(dataDir, tail) - - suspend fun unfollow( - dataDir: DataDir, - tail: Array, - ): Int = FollowCommand.unfollow(dataDir, tail) - - suspend fun search( - dataDir: DataDir, - tail: Array, - ): Int = SearchCommand.dispatch(dataDir, tail) - - suspend fun zap( - dataDir: DataDir, - tail: Array, - ): Int = ZapCommand.dispatch(dataDir, tail) - - suspend fun offer( - dataDir: DataDir, - tail: Array, - ): Int = OfferCommands.dispatch(dataDir, tail) - - suspend fun debit( - dataDir: DataDir, - tail: Array, - ): Int = DebitCommands.dispatch(dataDir, tail) -} diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/CreateCommand.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/CreateCommand.kt index ddae68bd8b..876e45e69d 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/CreateCommand.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/CreateCommand.kt @@ -71,17 +71,14 @@ object CreateCommand { // store via verifyAndStore — so kind:10002 / 10050 / 10051 are // immediately readable by outboxRelays() / inboxRelays() / // keyPackageRelays() without a separate config file. - val ctx = Context.open(dataDir) val accepted = mutableMapOf>() - try { + Context.open(dataDir).use { ctx -> ctx.prepare() for (event in bootstrap.all()) { val ack = ctx.publish(event, DefaultNIP65RelaySet) accepted[event.kind.toString()] = ack.filterValues { it }.keys.map { it.url } } - } finally { - ctx.close() } Output.emit( diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/DebitCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/DebitCommands.kt index ba90f6f01c..f89d79c8b0 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/DebitCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/DebitCommands.kt @@ -47,16 +47,17 @@ object DebitCommands { suspend fun dispatch( dataDir: DataDir, tail: Array, - ): Int { - if (tail.isEmpty()) return Output.error("bad_args", "debit ") - val rest = tail.drop(1).toTypedArray() - return when (tail[0]) { - "info" -> info(rest) - "pay" -> pay(dataDir, rest) - "budget" -> budget(dataDir, rest) - else -> Output.error("bad_args", "debit ${tail[0]} (expected info|pay|budget)") - } - } + ): Int = + route( + "debit", + tail, + "debit ", + mapOf( + "info" to { rest -> info(rest) }, + "pay" to { rest -> pay(dataDir, rest) }, + "budget" to { rest -> budget(dataDir, rest) }, + ), + ) /** Local decode of an `ndebit` pointer — no network, no account needed. */ private fun info(rest: Array): Int { @@ -119,8 +120,7 @@ object DebitCommands { ?: return Output.error("bad_args", "not a valid ndebit pointer") if (debit.relays.isEmpty()) return Output.error("bad_pointer", "ndebit carries no relay to reach") - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() return when (val outcome = settle(ctx, debit, timeoutMs, buildRequest)) { Settle.Timeout -> { @@ -130,8 +130,6 @@ object DebitCommands { Settle.BadReply -> Output.error("bad_response", "service reply was not a kind-21002 debit event") is Settle.Replied -> emitDebit(outcome, debit.pubKey) } - } finally { - ctx.close() } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/DmCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/DmCommands.kt index 9cd003ae30..c387a1e72f 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/DmCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/DmCommands.kt @@ -61,17 +61,18 @@ object DmCommands { suspend fun dispatch( dataDir: DataDir, tail: Array, - ): Int { - if (tail.isEmpty()) return Output.error("bad_args", "dm …") - val rest = tail.drop(1).toTypedArray() - return when (tail[0]) { - "send" -> send(dataDir, rest) - "send-file" -> sendFile(dataDir, rest) - "list" -> list(dataDir, rest) - "await" -> await(dataDir, rest) - else -> Output.error("bad_args", "dm ${tail[0]}") - } - } + ): Int = + route( + "dm", + tail, + "dm …", + mapOf( + "send" to { rest -> send(dataDir, rest) }, + "send-file" to { rest -> sendFile(dataDir, rest) }, + "list" to { rest -> list(dataDir, rest) }, + "await" to { rest -> await(dataDir, rest) }, + ), + ) private suspend fun send( dataDir: DataDir, @@ -82,14 +83,11 @@ object DmCommands { val args = Args(rest.drop(2).toTypedArray()) val allowFallback = args.bool("allow-fallback") - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val recipient = ctx.requireUserHex(rest[0]) val result = DmActions.buildTextDm(ctx.signer, recipient, text) return publishWraps(ctx, result, allowFallback) - } finally { - ctx.close() } } @@ -118,8 +116,7 @@ object DmCommands { val allowFallback = args.bool("allow-fallback") val recipientInput = rest[0] - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val recipient = ctx.requireUserHex(recipientInput) @@ -133,8 +130,6 @@ object DmCommands { } return publishWraps(ctx, result, allowFallback, extra = summary) - } finally { - ctx.close() } } @@ -315,8 +310,7 @@ object DmCommands { val limit = args.intFlag("limit", Int.MAX_VALUE) val timeoutSecs = args.longFlag("timeout", 8) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val peerHex = peerInput?.let { ctx.requireUserHex(it) } @@ -357,8 +351,6 @@ object DmCommands { ), ) return 0 - } finally { - ctx.close() } } @@ -371,8 +363,7 @@ object DmCommands { val match = args.requireFlag("match") val timeoutSecs = args.longFlag("timeout", 30) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val peerHex = ctx.requireUserHex(peerInput) @@ -408,8 +399,6 @@ object DmCommands { delay(2_000) } throw AwaitTimeout("no DM from $peerHex matching '$match' within ${timeoutSecs}s") - } finally { - ctx.close() } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/FeedCommand.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/FeedCommand.kt index ba928622ec..25bce1e8b8 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/FeedCommand.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/FeedCommand.kt @@ -61,8 +61,7 @@ object FeedCommand { val until = args.flag("until")?.toLongOrNull() val timeoutSecs = args.longFlag("timeout", 8L) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val (authors, mode) = @@ -131,8 +130,6 @@ object FeedCommand { ), ) return 0 - } finally { - ctx.close() } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/FollowCommand.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/FollowCommand.kt index c96234c8f4..85c6123390 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/FollowCommand.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/FollowCommand.kt @@ -68,8 +68,7 @@ object FollowCommand { val args = Args(rest.drop(1).toTypedArray()) val timeoutSecs = args.longFlag("timeout", 8L) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val target = ctx.requireUserHex(userArg) val self = ctx.identity.pubKeyHex @@ -148,8 +147,6 @@ object FollowCommand { ), ) return 0 - } finally { - ctx.close() } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupAddMemberCommand.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupAddMemberCommand.kt index c47e862bdd..7622361451 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupAddMemberCommand.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupAddMemberCommand.kt @@ -46,8 +46,7 @@ object GroupAddMemberCommand { rest: Array, ): Int { if (rest.size < 2) return Output.error("bad_args", "group add [ ...]") - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = ctx.resolveGroupId(rest[0]) ctx.syncIncoming() @@ -168,8 +167,6 @@ object GroupAddMemberCommand { ), ) return 0 - } finally { - ctx.close() } } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupCommands.kt index 7c519cbb7a..fe8bf98aef 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupCommands.kt @@ -21,28 +21,28 @@ package com.vitorpamplona.amethyst.cli.commands import com.vitorpamplona.amethyst.cli.DataDir -import com.vitorpamplona.amethyst.cli.Output object GroupCommands { suspend fun dispatch( dataDir: DataDir, tail: Array, - ): Int { - if (tail.isEmpty()) return Output.error("bad_args", "group ") - val rest = tail.drop(1).toTypedArray() - return when (tail[0]) { - "create" -> GroupCreateCommand.run(dataDir, rest) - "list" -> GroupReadCommands.list(dataDir) - "show" -> GroupReadCommands.show(dataDir, rest) - "members" -> GroupReadCommands.members(dataDir, rest) - "admins" -> GroupReadCommands.admins(dataDir, rest) - "add" -> GroupAddMemberCommand.run(dataDir, rest) - "rename" -> GroupMetadataCommands.rename(dataDir, rest) - "promote" -> GroupMetadataCommands.promote(dataDir, rest) - "demote" -> GroupMetadataCommands.demote(dataDir, rest) - "remove" -> GroupMembershipCommands.remove(dataDir, rest) - "leave" -> GroupMembershipCommands.leave(dataDir, rest) - else -> Output.error("bad_args", "group ${tail[0]}") - } - } + ): Int = + route( + "group", + tail, + "group ", + mapOf( + "create" to { rest -> GroupCreateCommand.run(dataDir, rest) }, + "list" to { _ -> GroupReadCommands.list(dataDir) }, + "show" to { rest -> GroupReadCommands.show(dataDir, rest) }, + "members" to { rest -> GroupReadCommands.members(dataDir, rest) }, + "admins" to { rest -> GroupReadCommands.admins(dataDir, rest) }, + "add" to { rest -> GroupAddMemberCommand.run(dataDir, rest) }, + "rename" to { rest -> GroupMetadataCommands.rename(dataDir, rest) }, + "promote" to { rest -> GroupMetadataCommands.promote(dataDir, rest) }, + "demote" to { rest -> GroupMetadataCommands.demote(dataDir, rest) }, + "remove" to { rest -> GroupMembershipCommands.remove(dataDir, rest) }, + "leave" to { rest -> GroupMembershipCommands.leave(dataDir, rest) }, + ), + ) } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupCreateCommand.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupCreateCommand.kt index b639971c8f..ee138c4626 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupCreateCommand.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupCreateCommand.kt @@ -35,8 +35,7 @@ object GroupCreateCommand { ): Int { val args = Args(rest) val name = args.flag("name", "")!! - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = RandomInstance.bytes(32).toHexKey() @@ -65,8 +64,6 @@ object GroupCreateCommand { ), ) return 0 - } finally { - ctx.close() } } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupMembershipCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupMembershipCommands.kt index e79dc0135d..1239996981 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupMembershipCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupMembershipCommands.kt @@ -30,8 +30,7 @@ object GroupMembershipCommands { rest: Array, ): Int { if (rest.size < 2) return Output.error("bad_args", "group remove ") - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = ctx.resolveGroupId(rest[0]) val target = ctx.requireUserHex(rest[1]) @@ -56,8 +55,6 @@ object GroupMembershipCommands { ), ) return 0 - } finally { - ctx.close() } } @@ -66,8 +63,7 @@ object GroupMembershipCommands { rest: Array, ): Int { if (rest.isEmpty()) return Output.error("bad_args", "group leave ") - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = ctx.resolveGroupId(rest[0]) if (!ctx.marmot.isMember(gid)) return Output.error("not_member", gid) @@ -111,8 +107,6 @@ object GroupMembershipCommands { ), ) return 0 - } finally { - ctx.close() } } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupMetadataCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupMetadataCommands.kt index fe8940782e..841adf2c37 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupMetadataCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupMetadataCommands.kt @@ -69,8 +69,7 @@ object GroupMetadataCommands { rawGid: HexKey, mutate: suspend (Context, MarmotGroupData) -> MarmotGroupData, ): Int { - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = ctx.resolveGroupId(rawGid) ctx.syncIncoming() @@ -100,8 +99,6 @@ object GroupMetadataCommands { ), ) return 0 - } finally { - ctx.close() } } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupReadCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupReadCommands.kt index 925685ff93..46e06da5df 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupReadCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GroupReadCommands.kt @@ -29,8 +29,7 @@ import com.vitorpamplona.amethyst.cli.Output */ object GroupReadCommands { suspend fun list(dataDir: DataDir): Int { - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() ctx.syncIncoming() val ids = ctx.marmot.activeGroupIds() @@ -46,8 +45,6 @@ object GroupReadCommands { } Output.emit(mapOf("groups" to items)) return 0 - } finally { - ctx.close() } } @@ -56,8 +53,7 @@ object GroupReadCommands { rest: Array, ): Int { if (rest.isEmpty()) return Output.error("bad_args", "group show ") - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = ctx.resolveGroupId(rest[0]) ctx.syncIncoming() @@ -81,8 +77,6 @@ object GroupReadCommands { ), ) return 0 - } finally { - ctx.close() } } @@ -91,8 +85,7 @@ object GroupReadCommands { rest: Array, ): Int { if (rest.isEmpty()) return Output.error("bad_args", "group members ") - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = ctx.resolveGroupId(rest[0]) ctx.syncIncoming() @@ -103,8 +96,6 @@ object GroupReadCommands { } Output.emit(mapOf("group_id" to gid, "members" to members)) return 0 - } finally { - ctx.close() } } @@ -113,8 +104,7 @@ object GroupReadCommands { rest: Array, ): Int { if (rest.isEmpty()) return Output.error("bad_args", "group admins ") - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = ctx.resolveGroupId(rest[0]) ctx.syncIncoming() @@ -122,8 +112,6 @@ object GroupReadCommands { val m = ctx.marmot.groupMetadata(gid) Output.emit(mapOf("group_id" to gid, "admins" to (m?.adminPubkeys ?: emptyList()))) return 0 - } finally { - ctx.close() } } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/KeyPackageCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/KeyPackageCommands.kt index 843fd17653..ac35fca36a 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/KeyPackageCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/KeyPackageCommands.kt @@ -30,18 +30,19 @@ object KeyPackageCommands { suspend fun dispatch( dataDir: DataDir, tail: Array, - ): Int { - if (tail.isEmpty()) return Output.error("bad_args", "key-package …") - return when (tail[0]) { - "publish" -> publish(dataDir) - "check" -> check(dataDir, tail.drop(1).toTypedArray()) - else -> Output.error("bad_args", "key-package ${tail[0]}") - } - } + ): Int = + route( + "key-package", + tail, + "key-package …", + mapOf( + "publish" to { _ -> publish(dataDir) }, + "check" to { rest -> check(dataDir, rest) }, + ), + ) private suspend fun publish(dataDir: DataDir): Int { - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val relays = ctx.keyPackageRelays().ifEmpty { ctx.outboxRelays() }.ifEmpty { ctx.anyRelays() } if (relays.isEmpty()) return Output.error("no_relays", "configure relays first") @@ -57,8 +58,6 @@ object KeyPackageCommands { ), ) return 0 - } finally { - ctx.close() } } @@ -67,8 +66,7 @@ object KeyPackageCommands { rest: Array, ): Int { if (rest.isEmpty()) return Output.error("bad_args", "key-package check ") - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val targetHex = ctx.requireUserHex(rest[0]) // Per MIP-00: a user's KeyPackages live on the relays advertised @@ -109,8 +107,6 @@ object KeyPackageCommands { ), ) return 0 - } finally { - ctx.close() } } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/MarmotResetCommand.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/MarmotResetCommand.kt index 8d1a118b5b..4d5fd9c73e 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/MarmotResetCommand.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/MarmotResetCommand.kt @@ -46,8 +46,7 @@ object MarmotResetCommand { rest: Array, ): Int { val confirmed = rest.any { it == "--yes" || it == "-y" } - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val groupIds = ctx.marmot @@ -77,8 +76,6 @@ object MarmotResetCommand { ), ) return 0 - } finally { - ctx.close() } } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/MessageCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/MessageCommands.kt index 0706e7dc10..fc62fb9efa 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/MessageCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/MessageCommands.kt @@ -31,17 +31,18 @@ object MessageCommands { suspend fun dispatch( dataDir: DataDir, tail: Array, - ): Int { - if (tail.isEmpty()) return Output.error("bad_args", "message …") - val rest = tail.drop(1).toTypedArray() - return when (tail[0]) { - "send" -> send(dataDir, rest) - "list" -> list(dataDir, rest) - "react" -> react(dataDir, rest) - "delete" -> delete(dataDir, rest) - else -> Output.error("bad_args", "message ${tail[0]}") - } - } + ): Int = + route( + "message", + tail, + "message …", + mapOf( + "send" to { rest -> send(dataDir, rest) }, + "list" to { rest -> list(dataDir, rest) }, + "react" to { rest -> react(dataDir, rest) }, + "delete" to { rest -> delete(dataDir, rest) }, + ), + ) private suspend fun send( dataDir: DataDir, @@ -49,8 +50,7 @@ object MessageCommands { ): Int { if (rest.size < 2) return Output.error("bad_args", "message send ") val text = rest[1] - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = ctx.resolveGroupId(rest[0]) ctx.syncIncoming() @@ -70,8 +70,6 @@ object MessageCommands { ), ) return 0 - } finally { - ctx.close() } } @@ -82,8 +80,7 @@ object MessageCommands { if (rest.isEmpty()) return Output.error("bad_args", "message list ") val args = Args(rest.drop(1).toTypedArray()) val limit = args.intFlag("limit", Int.MAX_VALUE) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = ctx.resolveGroupId(rest[0]) ctx.syncIncoming() @@ -110,8 +107,6 @@ object MessageCommands { Output.emit(mapOf("group_id" to gid, "messages" to items)) return 0 - } finally { - ctx.close() } } @@ -122,8 +117,7 @@ object MessageCommands { if (rest.size < 3) return Output.error("bad_args", "message react ") val targetId = rest[1] val emoji = rest[2] - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = ctx.resolveGroupId(rest[0]) ctx.syncIncoming() @@ -146,8 +140,6 @@ object MessageCommands { ), ) return 0 - } finally { - ctx.close() } } @@ -156,8 +148,7 @@ object MessageCommands { rest: Array, ): Int { if (rest.size < 2) return Output.error("bad_args", "message delete [target_event_id ...]") - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val gid = ctx.resolveGroupId(rest[0]) ctx.syncIncoming() @@ -184,8 +175,6 @@ object MessageCommands { ), ) return 0 - } finally { - ctx.close() } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NappletCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NappletCommands.kt index d80c6c32c3..5c0a182e1a 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NappletCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NappletCommands.kt @@ -53,14 +53,15 @@ object NappletCommands { suspend fun dispatch( dataDir: DataDir, tail: Array, - ): Int { - if (tail.isEmpty()) return Output.error("bad_args", "napplet …") - val rest = tail.drop(1).toTypedArray() - return when (tail[0]) { - "fetch" -> fetch(dataDir, rest) - else -> Output.error("bad_args", "napplet ${tail[0]}") - } - } + ): Int = + route( + "napplet", + tail, + "napplet …", + mapOf( + "fetch" to { rest -> fetch(dataDir, rest) }, + ), + ) private suspend fun fetch( dataDir: DataDir, @@ -80,8 +81,7 @@ object NappletCommands { val extraServers = StaticSiteFetch.commaList(args.flag("server")) val extraRelays = StaticSiteFetch.commaList(args.flag("relay")) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val relays = extraRelays @@ -143,8 +143,6 @@ object NappletCommands { outFile = outFile, maxInlineBytes = maxInlineBytes, ) - } finally { - ctx.close() } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NotesCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NotesCommands.kt index f3ecad460d..8c0415ae17 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NotesCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NotesCommands.kt @@ -21,7 +21,6 @@ package com.vitorpamplona.amethyst.cli.commands import com.vitorpamplona.amethyst.cli.DataDir -import com.vitorpamplona.amethyst.cli.Output /** * `amy notes ` — NIP-10 kind:1 short text notes. Sits alongside @@ -32,13 +31,14 @@ object NotesCommands { suspend fun dispatch( dataDir: DataDir, tail: Array, - ): Int { - if (tail.isEmpty()) return Output.error("bad_args", "notes …") - val rest = tail.drop(1).toTypedArray() - return when (tail[0]) { - "post" -> PostCommand.run(dataDir, rest) - "feed" -> FeedCommand.run(dataDir, rest) - else -> Output.error("bad_args", "notes ${tail[0]}") - } - } + ): Int = + route( + "notes", + tail, + "notes …", + mapOf( + "post" to { rest -> PostCommand.run(dataDir, rest) }, + "feed" to { rest -> FeedCommand.run(dataDir, rest) }, + ), + ) } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NsiteCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NsiteCommands.kt index 81cdeb560d..5ab090f414 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NsiteCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/NsiteCommands.kt @@ -52,14 +52,15 @@ object NsiteCommands { suspend fun dispatch( dataDir: DataDir, tail: Array, - ): Int { - if (tail.isEmpty()) return Output.error("bad_args", "nsite …") - val rest = tail.drop(1).toTypedArray() - return when (tail[0]) { - "fetch" -> fetch(dataDir, rest) - else -> Output.error("bad_args", "nsite ${tail[0]}") - } - } + ): Int = + route( + "nsite", + tail, + "nsite …", + mapOf( + "fetch" to { rest -> fetch(dataDir, rest) }, + ), + ) private suspend fun fetch( dataDir: DataDir, @@ -75,8 +76,7 @@ object NsiteCommands { val extraServers = StaticSiteFetch.commaList(args.flag("server")) val extraRelays = StaticSiteFetch.commaList(args.flag("relay")) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val authorHex = ctx.requireUserHex(author) @@ -113,8 +113,6 @@ object NsiteCommands { outFile = outFile, maxInlineBytes = maxInlineBytes, ) - } finally { - ctx.close() } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/OfferCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/OfferCommands.kt index 388e9291f8..408f49704a 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/OfferCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/OfferCommands.kt @@ -57,17 +57,18 @@ object OfferCommands { suspend fun dispatch( dataDir: DataDir, tail: Array, - ): Int { - if (tail.isEmpty()) return Output.error("bad_args", "offer ") - val rest = tail.drop(1).toTypedArray() - return when (tail[0]) { - "info" -> info(rest) - "discover" -> discover(dataDir, rest) - "request" -> request(dataDir, rest) - "pay" -> pay(dataDir, rest) - else -> Output.error("bad_args", "offer ${tail[0]} (expected info|discover|request|pay)") - } - } + ): Int = + route( + "offer", + tail, + "offer ", + mapOf( + "info" to { rest -> info(rest) }, + "discover" to { rest -> discover(dataDir, rest) }, + "request" to { rest -> request(dataDir, rest) }, + "pay" to { rest -> pay(dataDir, rest) }, + ), + ) /** * Resolve a profile's advertised offer from its NIP-05 `.well-known/nostr.json` `clink_offer` @@ -83,8 +84,7 @@ object OfferCommands { Nip05Id.parse(args.positional(0, "nip05").trim()) ?: return Output.error("bad_args", "not a valid NIP-05 address (e.g. bob@example.com)") - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val noffer = ctx.nip05Client.loadClinkOffer(id) if (noffer == null) { @@ -105,8 +105,6 @@ object OfferCommands { ), ) return 0 - } finally { - ctx.close() } } @@ -152,8 +150,7 @@ object OfferCommands { ClinkPointerParser.parse(args.positional(0, "noffer").trim()) as? NOffer ?: return Output.error("bad_args", ERR_NOT_A_NOFFER) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() var hops = 0 while (hops <= MAX_FOLLOW_HOPS) { @@ -200,8 +197,6 @@ object OfferCommands { ) } return Output.error("offer_error", "too many redirects following moved offers (>$MAX_FOLLOW_HOPS)") - } finally { - ctx.close() } } @@ -232,8 +227,7 @@ object OfferCommands { if (offerRelays.isEmpty()) return Output.error("bad_pointer", "noffer carries no relay to reach") if (debit.relays.isEmpty()) return Output.error("bad_pointer", "ndebit carries no relay to reach") - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() // 1. fetch a fresh BOLT-11 from the offer service. @@ -287,8 +281,6 @@ object OfferCommands { ) } } - } finally { - ctx.close() } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/PostCommand.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/PostCommand.kt index dd27a82940..3a46c37bf4 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/PostCommand.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/PostCommand.kt @@ -50,8 +50,7 @@ object PostCommand { ?.map { it.trim() } ?.filter { it.isNotEmpty() } ?: emptyList() - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val outbox = ctx.outboxRelays() val extraNormalized = @@ -78,8 +77,6 @@ object PostCommand { ), ) return 0 - } finally { - ctx.close() } } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/ProfileCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/ProfileCommands.kt index 170e792189..a496cc1184 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/ProfileCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/ProfileCommands.kt @@ -45,15 +45,16 @@ object ProfileCommands { suspend fun dispatch( dataDir: DataDir, tail: Array, - ): Int { - if (tail.isEmpty()) return Output.error("bad_args", "profile …") - val rest = tail.drop(1).toTypedArray() - return when (tail[0]) { - "show" -> show(dataDir, rest) - "edit" -> edit(dataDir, rest) - else -> Output.error("bad_args", "profile ${tail[0]}") - } - } + ): Int = + route( + "profile", + tail, + "profile …", + mapOf( + "show" to { rest -> show(dataDir, rest) }, + "edit" to { rest -> edit(dataDir, rest) }, + ), + ) private suspend fun show( dataDir: DataDir, @@ -62,8 +63,7 @@ object ProfileCommands { val args = Args(rest) val refresh = args.bool("refresh") val timeoutSecs = args.longFlag("timeout", 8L) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val pubKey = args.positionalOrNull(0)?.let { ctx.requireUserHex(it) } @@ -118,8 +118,6 @@ object ProfileCommands { ), ) return 0 - } finally { - ctx.close() } } @@ -161,8 +159,7 @@ object ProfileCommands { ) } - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val targets = ctx.outboxRelays().ifEmpty { ctx.bootstrapRelays() } val latest = @@ -226,8 +223,6 @@ object ProfileCommands { ), ) return 0 - } finally { - ctx.close() } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/RelayCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/RelayCommands.kt index aade5d8298..416d6a6c63 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/RelayCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/RelayCommands.kt @@ -51,17 +51,17 @@ object RelayCommands { suspend fun dispatch( dataDir: DataDir, tail: Array, - ): Int { - if (tail.isEmpty()) return Output.error("bad_args", "relay …") - val sub = tail[0] - val rest = tail.drop(1).toTypedArray() - return when (sub) { - "add" -> add(dataDir, Args(rest)) - "list" -> list(dataDir) - "publish-lists" -> publishLists(dataDir) - else -> Output.error("bad_args", "relay $sub") - } - } + ): Int = + route( + "relay", + tail, + "relay …", + mapOf( + "add" to { rest -> add(dataDir, Args(rest)) }, + "list" to { _ -> list(dataDir) }, + "publish-lists" to { _ -> publishLists(dataDir) }, + ), + ) private suspend fun add( dataDir: DataDir, @@ -74,8 +74,7 @@ object RelayCommands { ?: return Output.error("bad_args", "invalid relay url: $rawUrl") val targets = if (type == "all") listOf("nip65", "inbox", "key_package") else listOf(type) - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> val addedTo = mutableListOf() val alreadyPresent = mutableListOf() for (t in targets) { @@ -89,8 +88,6 @@ object RelayCommands { ), ) return 0 - } finally { - ctx.close() } } @@ -138,8 +135,7 @@ object RelayCommands { } private suspend fun list(dataDir: DataDir): Int { - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> val self = ctx.identity.pubKeyHex Output.emit( mapOf( @@ -149,14 +145,11 @@ object RelayCommands { ), ) return 0 - } finally { - ctx.close() } } private suspend fun publishLists(dataDir: DataDir): Int { - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val self = ctx.identity.pubKeyHex val nip65Event = ctx.relaysOf(self) @@ -189,8 +182,6 @@ object RelayCommands { ), ) return 0 - } finally { - ctx.close() } } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/Router.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/Router.kt new file mode 100644 index 0000000000..4fefe297d5 --- /dev/null +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/Router.kt @@ -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.cli.commands + +import com.vitorpamplona.amethyst.cli.Output + +/** + * Shared sub-verb router used by every `*Commands.dispatch`. + * + * Maps the first token of [tail] to a handler over the remaining args. + * Empty input emits `bad_args: `; an unrecognised verb emits + * `bad_args: `. Handlers receive the args *after* the verb, + * mirroring the old hand-rolled `when (tail[0]) { … }` blocks. + */ +suspend fun route( + name: String, + tail: Array, + usage: String, + routes: Map) -> Int>, +): Int { + if (tail.isEmpty()) return Output.error("bad_args", usage) + val handler = routes[tail[0]] ?: return Output.error("bad_args", "$name ${tail[0]}") + return handler(tail.drop(1).toTypedArray()) +} diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/SearchCommand.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/SearchCommand.kt index 0c52732a96..4e0bedbcbd 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/SearchCommand.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/SearchCommand.kt @@ -52,15 +52,16 @@ object SearchCommand { suspend fun dispatch( dataDir: DataDir, tail: Array, - ): Int { - if (tail.isEmpty()) return Output.error("bad_args", "search [--limit N] [--timeout SECS]") - val rest = tail.drop(1).toTypedArray() - return when (tail[0]) { - "user" -> searchUsers(dataDir, rest) - "note" -> searchNotes(dataDir, rest) - else -> Output.error("bad_args", "search ${tail[0]} — expected user|note") - } - } + ): Int = + route( + "search", + tail, + "search [--limit N] [--timeout SECS]", + mapOf( + "user" to { rest -> searchUsers(dataDir, rest) }, + "note" to { rest -> searchNotes(dataDir, rest) }, + ), + ) private suspend fun searchUsers( dataDir: DataDir, @@ -144,8 +145,7 @@ object SearchCommand { timeoutMs: Long, render: (List) -> List>, ): Int { - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val relays = SearchActions.resolveSearchRelays( @@ -172,8 +172,6 @@ object SearchCommand { ), ) return 0 - } finally { - ctx.close() } } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/StoreCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/StoreCommands.kt index c1ff1b89eb..bab4c94a55 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/StoreCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/StoreCommands.kt @@ -54,18 +54,19 @@ object StoreCommands { suspend fun dispatch( dataDir: DataDir, tail: Array, - ): Int { - if (tail.isEmpty()) return Output.error("bad_args", "store ") - val rest = tail.drop(1).toTypedArray() - return when (tail[0]) { - "stat" -> stat(dataDir) - "sweep-expired" -> sweepExpired(dataDir) - "scrub" -> scrub(dataDir) - "compact" -> compact(dataDir) - "reindex-fts" -> reindexFts(dataDir) - else -> Output.error("bad_args", "store ${tail[0]}") - } - } + ): Int = + route( + "store", + tail, + "store ", + mapOf( + "stat" to { _ -> stat(dataDir) }, + "sweep-expired" to { _ -> sweepExpired(dataDir) }, + "scrub" to { _ -> scrub(dataDir) }, + "compact" to { _ -> compact(dataDir) }, + "reindex-fts" to { _ -> reindexFts(dataDir) }, + ), + ) private fun stat(dataDir: DataDir): Int { val storeRoot = dataDir.eventsDir.toPath() diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/ZapCommand.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/ZapCommand.kt index 6ef33e4557..18eb321bf2 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/ZapCommand.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/ZapCommand.kt @@ -94,8 +94,7 @@ object ZapCommand { ?: return Output.error("bad_args", "--with must be a valid ndebit pointer with a relay") } - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val recipient = ctx.requireUserHex(userArg) val metadata = @@ -117,8 +116,6 @@ object ZapCommand { emitZapResult(ctx, sats, lnAddress, comment, request, zapType, timeoutMs, settleWith) return 0 - } finally { - ctx.close() } } @@ -145,8 +142,7 @@ object ZapCommand { ?: return Output.error("bad_args", "--with must be a valid ndebit pointer with a relay") } - val ctx = Context.open(dataDir) - try { + Context.open(dataDir).use { ctx -> ctx.prepare() val zappedEvent = ctx.store.query(Filter(ids = listOf(eventId), limit = 1)).firstOrNull() @@ -197,8 +193,6 @@ object ZapCommand { emitSplitZapResult(ctx, sats, comment, zappedEvent.id, zapType, requests, timeoutMs, settleWith) return 0 - } finally { - ctx.close() } } diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/ImmutableListOfLists.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/ImmutableListOfLists.kt index d55aa531fe..f01f73ddd2 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/ImmutableListOfLists.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/ImmutableListOfLists.kt @@ -25,7 +25,17 @@ import androidx.compose.runtime.Stable @Stable class ImmutableListOfLists( val lists: Array>, -) +) { + // Memoized content hash of all tags. `lists` is an Array (identity hashCode), + // so any consumer that needs a *content*-based key (e.g. CachedRichTextParser, + // so an off-thread pre-parse maps to the same cache entry the renderer uses) + // would otherwise re-traverse every tag on each call. Computing it once per + // instance keeps that O(1)-amortized. Benign data race: concurrent first + // readers just recompute the same value. + private var cachedContentHash: Int? = null + + fun contentHash(): Int = cachedContentHash ?: lists.contentDeepHashCode().also { cachedContentHash = it } +} val EmptyTagList = ImmutableListOfLists(emptyArray()) diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/assemblers/CashuWalletFilterAssembler.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/assemblers/CashuWalletFilterAssembler.kt index d70325c0fc..c761981205 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/assemblers/CashuWalletFilterAssembler.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/assemblers/CashuWalletFilterAssembler.kt @@ -42,13 +42,23 @@ import com.vitorpamplona.quartz.nip87Ecash.recommendation.MintRecommendationEven * Query state for the NIP-60 / NIP-61 wallet subscription. * * `pubkey` is the wallet owner — used both as `authors=` for their own - * NIP-60 events and as the `#p` tag value for inbound nutzaps. `relays` is - * the union of relays to subscribe on (NIP-65 outbox + DM relays at minimum). + * NIP-60 events and as the `#p` tag value for inbound nutzaps. + * + * The two filters read from different relay sets, following the NIP-65 + * outbox model: + * - [ownEventRelays] — the user's own write/outbox relays, where they + * published their NIP-60 wallet/token/history events. Restoring those + * means reading from where they were written. + * - [inboxRelays] — where *other* people deliver kind:9321 nutzaps to this + * user. Per NIP-61 the source of truth is the `relay` tags in the user's + * own kind:10019; in practice we listen on the union of those plus the + * user's NIP-65 inbox + DM relays so a nutzap can't slip past us. */ @Immutable data class CashuWalletQueryState( val pubkey: HexKey, - val relays: Set, + val ownEventRelays: Set, + val inboxRelays: Set, ) /** @@ -91,11 +101,9 @@ private class CashuWalletSubAssembler( if (keys.isEmpty()) return null val pubkey = keys.first().pubkey - val relays = - keys - .flatMap { it.relays } - .toSet() - .ifEmpty { return null } + val ownEventRelays = keys.flatMap { it.ownEventRelays }.toSet() + val inboxRelays = keys.flatMap { it.inboxRelays }.toSet() + if (ownEventRelays.isEmpty() && inboxRelays.isEmpty()) return null val ownedFilter = Filter( @@ -121,18 +129,26 @@ private class CashuWalletSubAssembler( tags = mapOf("p" to listOf(pubkey)), ) - return relays.flatMap { relay -> - val sinceTime = since?.get(relay)?.time - listOf( + // Own NIP-60 events are read from the user's outbox; inbound nutzaps + // from the user's inbox set. A relay that appears in both gets both + // filters. + val ownedSubs = + ownEventRelays.map { relay -> + val sinceTime = since?.get(relay)?.time RelayBasedFilter( relay, if (sinceTime != null) ownedFilter.copy(since = sinceTime) else ownedFilter, - ), + ) + } + val inboundSubs = + inboxRelays.map { relay -> + val sinceTime = since?.get(relay)?.time RelayBasedFilter( relay, if (sinceTime != null) inboundNutzapsFilter.copy(since = sinceTime) else inboundNutzapsFilter, - ), - ) - } + ) + } + + return ownedSubs + inboundSubs } } diff --git a/commons/src/commonTest/kotlin/com/vitorpamplona/amethyst/commons/richtext/UrlParserTest.kt b/commons/src/commonTest/kotlin/com/vitorpamplona/amethyst/commons/richtext/UrlParserTest.kt index 7ce6c472d3..f1444b88cc 100644 --- a/commons/src/commonTest/kotlin/com/vitorpamplona/amethyst/commons/richtext/UrlParserTest.kt +++ b/commons/src/commonTest/kotlin/com/vitorpamplona/amethyst/commons/richtext/UrlParserTest.kt @@ -321,6 +321,34 @@ class UrlParserTest { Urls(withScheme = setOf("http://[2a01:5cc0:1:2::4]")), ) + @Test + fun testUrlWithBalancedParenthesis() = + test( + "https://en.wikipedia.org/wiki/Bitcoin_(disambiguation)", + Urls(withScheme = setOf("https://en.wikipedia.org/wiki/Bitcoin_(disambiguation)")), + ) + + @Test + fun testUrlWithCommaAndBalancedParenthesis() = + test( + "https://memory-alpha.fandom.com/wiki/Scorpion,_Part_II_(episode)", + Urls(withScheme = setOf("https://memory-alpha.fandom.com/wiki/Scorpion,_Part_II_(episode)")), + ) + + @Test + fun testUrlWithBalancedParenthesisInSentence() = + test( + "Read https://en.wikipedia.org/wiki/Bitcoin_(disambiguation) for context.", + Urls(withScheme = setOf("https://en.wikipedia.org/wiki/Bitcoin_(disambiguation)")), + ) + + @Test + fun testUrlWrappedInParenthesisDropsCloser() = + test( + "(see https://test.com)", + Urls(withScheme = setOf("https://test.com")), + ) + @Test fun testBlossom() { val blossom = "blossom:b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf?xs=cdn.satellite.earth" diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ComposeNoteDialog.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ComposeNoteDialog.kt index 707275d5d2..fedaa0a6c5 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ComposeNoteDialog.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ComposeNoteDialog.kt @@ -71,6 +71,7 @@ import com.vitorpamplona.amethyst.commons.ui.components.UserAvatar import com.vitorpamplona.amethyst.desktop.DesktopPreferences import com.vitorpamplona.amethyst.desktop.ImageCompressionStore import com.vitorpamplona.amethyst.desktop.account.AccountState +import com.vitorpamplona.amethyst.desktop.model.DesktopIAccount import com.vitorpamplona.amethyst.desktop.network.DesktopRelayConnectionManager import com.vitorpamplona.amethyst.desktop.service.upload.DesktopUploadTracker import com.vitorpamplona.amethyst.desktop.ui.compose.ComposeRelayPicker @@ -84,6 +85,7 @@ import com.vitorpamplona.amethyst.desktop.ui.media.QualitySelectorChip import com.vitorpamplona.amethyst.desktop.ui.media.buildPreview import com.vitorpamplona.amethyst.desktop.ui.media.cleanupPreviewTemps import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.events.eTag @@ -97,6 +99,8 @@ import com.vitorpamplona.quartz.nip10Notes.content.findURLs import com.vitorpamplona.quartz.nip18Reposts.quotes.QEventTag import com.vitorpamplona.quartz.nip18Reposts.quotes.quote import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip89AppHandlers.clientTag.isClient import com.vitorpamplona.quartz.nip92IMeta.IMetaTag import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -805,22 +809,38 @@ private suspend fun publishNote( } val template = - TextNoteEvent.build(content) { - if (replyTo != null) { - val etag = ETag(replyTo.id) - etag.relay = null - etag.author = replyTo.pubKey - eTag(etag) - pTag(PTag(replyTo.pubKey, relayHint = null)) + if (replyTo is TextNoteEvent && replyTo.isNewThread() && replyTo.isClient(DesktopIAccount.CLIENT_TAG_NAME)) { + // NIP-22: replying to a brand-new Amethyst kind-1 thread root produces + // a kind 1111 Comment instead of a kind 1 reply. + CommentEvent.replyBuilder(content, EventHintBundle(replyTo)) { + if (quoteOf != null) { + quote(QEventTag(quoteOf.id, relayHint = null, authorPubKeyHex = quoteOf.pubKey)) + pTag(PTag(quoteOf.pubKey, relayHint = null)) + } + hashtags(findHashtags(content)) + references(findURLs(content)) + for (imeta in imetaTags) { + add(imeta.toTagArray()) + } } - if (quoteOf != null) { - quote(QEventTag(quoteOf.id, relayHint = null, authorPubKeyHex = quoteOf.pubKey)) - pTag(PTag(quoteOf.pubKey, relayHint = null)) - } - hashtags(findHashtags(content)) - references(findURLs(content)) - for (imeta in imetaTags) { - add(imeta.toTagArray()) + } else { + TextNoteEvent.build(content) { + if (replyTo != null) { + val etag = ETag(replyTo.id) + etag.relay = null + etag.author = replyTo.pubKey + eTag(etag) + pTag(PTag(replyTo.pubKey, relayHint = null)) + } + if (quoteOf != null) { + quote(QEventTag(quoteOf.id, relayHint = null, authorPubKeyHex = quoteOf.pubKey)) + pTag(PTag(quoteOf.pubKey, relayHint = null)) + } + hashtags(findHashtags(content)) + references(findURLs(content)) + for (imeta in imetaTags) { + add(imeta.toTagArray()) + } } } diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/highlights/HighlightPublishAction.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/highlights/HighlightPublishAction.kt index 992640b028..764f7e521d 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/highlights/HighlightPublishAction.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/highlights/HighlightPublishAction.kt @@ -23,7 +23,6 @@ package com.vitorpamplona.amethyst.desktop.ui.highlights import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent import com.vitorpamplona.quartz.nip84Highlights.tags.CommentTag import com.vitorpamplona.quartz.nip84Highlights.tags.ContextTag @@ -39,7 +38,6 @@ object HighlightPublishAction { ): HighlightEvent { val tags = mutableListOf>() - tags.add(AltTag.assemble(HighlightEvent.ALT)) tags.add(ATag.assemble(articleAddressTag, null)) // Tag the article author diff --git a/docs/changelog/README.md b/docs/changelog/README.md index 08e6e79268..86cce14ed5 100644 --- a/docs/changelog/README.md +++ b/docs/changelog/README.md @@ -2,6 +2,7 @@ Release notes for Amethyst, one file per version. Files are named with zero-padded version numbers so they sort correctly in any file browser. Use [`TEMPLATE.md`](TEMPLATE.md) as the starting point for the next release. +- [v1.12.6 — Napplets, Static Sites & Cashu Multi-Mint](v1.12.06.md) - [v1.12.5 — macOS Desktop Signing Fix (cont.)](v1.12.05.md) - [v1.12.4 — macOS Desktop Signing Fix](v1.12.04.md) - [v1.12.3 — Relay Latency Health & a macOS Notarization Fix](v1.12.03.md) diff --git a/docs/changelog/translators.json b/docs/changelog/translators.json index 9288f70108..31cf8a58bc 100644 --- a/docs/changelog/translators.json +++ b/docs/changelog/translators.json @@ -73,9 +73,39 @@ "Kevin_1": "" }, "sinceLastTag": { - "tag": "v1.12.5", - "since": "2026-06-19T12:55:37-04:00", + "tag": "v1.12.6", + "since": "2026-06-19T19:01:59-04:00", "translators": [ + { + "user": "anthony-robin", + "languages": [ + "French" + ] + }, + { + "user": "maxblake2015", + "languages": [ + "Polish" + ] + }, + { + "user": "StellarStoic", + "languages": [ + "Slovenian" + ] + }, + { + "user": "hypnotichemionus4", + "languages": [ + "Chinese Simplified" + ] + }, + { + "user": "summoner001", + "languages": [ + "Hungarian" + ] + }, { "user": "vitorpamplona", "languages": [] @@ -116,10 +146,6 @@ "user": "Bardesss", "languages": [] }, - { - "user": "anthony-robin", - "languages": [] - }, { "user": "Pextar", "languages": [] @@ -240,18 +266,10 @@ "user": "hlcbump", "languages": [] }, - { - "user": "StellarStoic", - "languages": [] - }, { "user": "D4rkFIow", "languages": [] }, - { - "user": "summoner001", - "languages": [] - }, { "user": "fiddleway", "languages": [] @@ -268,14 +286,6 @@ "user": "Coool", "languages": [] }, - { - "user": "hypnotichemionus4", - "languages": [] - }, - { - "user": "maxblake2015", - "languages": [] - }, { "user": "eiie7", "languages": [] diff --git a/docs/changelog/v1.12.06.md b/docs/changelog/v1.12.06.md new file mode 100644 index 0000000000..7d0064e567 --- /dev/null +++ b/docs/changelog/v1.12.06.md @@ -0,0 +1,74 @@ +# v1.12.6: Napplets, Static Sites & Cashu Multi-Mint + +Highlights: + +- New protocol support for **Nostr Web Applets (NIP-5D)** and **static websites + (NIP-5A)**, resolved straight from signed manifests over Blossom. +- Cashu tokens that span **multiple mints** now redeem in full, and both Base64 + alphabets are accepted. +- A batch of stability fixes across notifications, playback, feeds, and the + emoji pack screens. + +## New Features + +- Add support for **Nostr Web Applets (NIP-5D)** and **static websites + (NIP-5A)**. Napplet manifests (snapshot/root/named kinds) and the NIP-5A + aggregate-hash layer land in Quartz, with a resolver that downloads each + listed Blossom server in order and accepts only the blob whose recomputed + SHA-256 matches the signed manifest — a substituted or corrupted blob fails + verification and is skipped. + +## Performance + +- Cashu token-prefix dispatch now compares against precomputed `DualCase` + prefixes instead of case-folding the cashuA/cashuB markers on every call. + +## Improvements and Bug fixes + +- Cashu: redeeming a pasted token now redeems **every mint/keyset group** in it + (previously only the first), validating all mints are in the wallet up front + and summing the redeemed amounts. The parser also tolerates both standard and + url-safe Base64 and mixed-case `cashuA`/`cashuB` prefixes. +- Stop the `DisappearingScaffold` top/bottom bars from overshooting their + resting edge during the show/hide animation. +- Dedupe emoji shortcodes in the Emoji Pack screen to prevent a `LazyGrid` + crash, and dedupe emoji pack addresses in the My Emoji List grid. +- Cap media-session artwork to the platform bitmap limit so large covers no + longer crash playback. +- Handle a missing camera app gracefully when taking photos or videos. +- Snapshot live-stream status order before sorting, and snapshot feed filters + too, to avoid `TimSort` "contract violation" crashes. +- Notifications: call `startForeground` on every start command and always + `stopSelf` when foreground promotion fails. +- Guard the Health Connect permission check against service-bind failures. +- Add a descriptive message to the media-download HTTP check. + +## Cli + +- `amy napplet fetch` resolves and fetches a NIP-5D napplet. +- `amy nsite fetch` resolves and verifies a NIP-5A static site / napplet. + +## Quartz + +- Implement NIP-5D napplets and the NIP-5A static-site resolver (manifest model, + path lookup, hash verification, Blossom candidate assembly) in `commonMain`, + with HTTP injected so Quartz keeps no networking dependency. +- Move the out-of-band Cashu token parser, the `cashuB` (v4) encoder, and the + token container model into Quartz, so Desktop's rich-text viewer can now parse + received Cashu tokens. Adds `kotlinx-serialization-cbor` (Apache-2.0). +- Centralize Blossom protocol strings in Quartz. +- Never let signer timeouts crash from auto-signing launches. + +## Build & Documentation + +- Generate the changelog translator credits offline from a committed + `translators.json`, track a rolling "since last tag" contributor list, and + seed it from Crowdin on every sync without rewriting the timestamp each run. + +## Contributors + +- @npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z + +## Translations + +- _None this release._ diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a1c932f65e..87fea3c9f0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,8 +2,8 @@ # Amethyst app version — single source of truth consumed by both Android (amethyst/) # and Desktop (desktopApp/). `appCode` is the Android versionCode: a monotonic # integer that must increment on every release, even when `app` is unchanged. -app = "1.12.5" -appCode = "453" +app = "1.12.6" +appCode = "454" accompanistAdaptive = "0.37.3" cachemapVersion = "0.2.4" composeMultiplatform = "1.11.1" diff --git a/quartz/plans/2026-06-20-powr-interop.md b/quartz/plans/2026-06-20-powr-interop.md new file mode 100644 index 0000000000..9b0cbe07cd --- /dev/null +++ b/quartz/plans/2026-06-20-powr-interop.md @@ -0,0 +1,68 @@ +# POWR interop: rendering kind-1301 strength workouts + +Research date: 2026-06-20. Source: POWR app (`DocNR/POWR`), spec at +`docs/technical/nostr/exercise_nip.md` (the NIP-101e "Workout Events" draft: +kinds 33401 exercise template, 33402 workout template, 1301 workout record). +Sample event provided by a POWR user (`client: POWR`, `relay.powr.build`). + +## The problem + +POWR and RUNSTR both publish **kind 1301**, but the tag schemas are +structurally incompatible. Amethyst already supported the RUNSTR dialect +(`quartz/.../experimental/fitness/workout/`), so a POWR event rendered badly: +the activity label showed the raw coordinate `33401:…:back-squat-bb`, there was +no duration, and none of the set data appeared. + +| Concern | RUNSTR dialect (existing) | POWR / NIP-101e dialect (new) | +|---|---|---| +| Activity type | `["exercise", "running"]` (verb) | `["type", "strength"]` (`strength`/`circuit`/`emom`/`amrap`) | +| `exercise` tag | the activity verb | one **logged set**, referencing a 33401 template: `["exercise", "33401:pubkey:d-tag", relay, weightKg, reps, rpe, set_type, set_number]` | +| Duration | `["duration", "HH:MM:SS"]` or raw seconds | none — derive from `["start", unix]` / `["end", unix]` | +| Weight unit | lbs | **kg** (empty = bodyweight, negative = assisted) | +| Misc | `source`, `t` hashtags | `completed`, `template`, `client` | + +## What was implemented (read/render only) + +Parsing + tests in Quartz, rendering in Amethyst. Amethyst still **publishes** +the RUNSTR-canonical form (no POWR writer) — this is rendering interop. + +### Quartz (`experimental/fitness/workout/`) +- `tags/WorkoutTypeTag.kt` — POWR `type`. +- `tags/WorkoutSessionTimeTags.kt` — `start` / `end` / `completed`. +- `tags/ExerciseSetTag.kt` — the per-set coordinate form, with `isCoordinate()` + to distinguish it from a RUNSTR verb (`kind:64-hex-pubkey:d-tag`). +- `ExerciseGroup.kt` — groups sets by template reference (first-seen order, + sorted by set number); `displayName()` prettifies the d-tag slug + (`back-squat-bb` → "Back Squat Bb"); `totalVolumeKg()` / `topWeightKg()`. +- `ExerciseTag.parse()` now returns null for the coordinate form, so the verb + path never surfaces `33401:…` as an activity. +- `ExerciseType` gains `CIRCUIT` / `EMOM` / `AMRAP` (icon + label reuse). +- `WorkoutRecordEvent`: `activityType()` (prefers `type`, falls back to the + verb), `effectiveDurationSeconds()` (duration tag, else `end - start`), + `exerciseGroups()`, `client()`, `workoutCompleted()`. + +### Exercise-template resolution (kind 33401) +- `ExerciseTemplateEvent.kt` (kind 33401, addressable) + tag accessors + (`title`, `format`, `format_units`, `equipment`, `difficulty`); registered + in `EventFactory`. +- `WorkoutRecordEvent` implements `AddressHintProvider`: `linkedAddressIds()` + (deduped 33401 + 33402 coordinates) seed the gatherer so the card re-renders + when a template arrives; `addressHints()` feed the relay-hint index with the + `relay.powr.build` hints from each `exercise`/`template` tag — without these + the fetch would only hit the viewer's own relays and usually miss. +- `ExerciseSetTag.parseAsHint` / `TemplateTag.parseAsHint` build the hints. + +### Amethyst (`WorkoutDisplay.kt`) +- Activity label/icon come from `activityType()`; coordinate never leaks. +- Hero = derived duration; secondary stats add Exercises / Sets / Volume. +- `ExerciseBreakdown` lists each exercise with its sets, e.g. + `Back Squat Bb → 3 × 8 × 84 kg`, in the viewer's preferred unit (kg↔lbs). +- Each row resolves its 33401 template via `LoadAddressableNote` + + `observeNoteEvent` (fetch-on-demand), showing the + template's real `title()` once it arrives and the slug until then. + +## Not done (possible follow-ups) +- Render 33402 (the planned template) to show planned-vs-done. +- A POWR-dialect writer (would need exercise-template authoring — large). +- Surface `rpe` / `set_type` (warmup/drop/failure) per set, and the template's + `equipment` as a per-exercise icon. diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/attestation/AttestationEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/attestation/AttestationEvent.kt index 8202989305..a4ee13f6f6 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/attestation/AttestationEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/attestation/AttestationEvent.kt @@ -37,7 +37,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.events.ETag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -85,7 +84,6 @@ class AttestationEvent( companion object { const val KIND = 31871 - const val ALT_DESCRIPTION = "Attestation" fun buildEvent( dTagId: String, @@ -98,7 +96,6 @@ class AttestationEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, content, createdAt) { - alt(ALT_DESCRIPTION) dTag(dTagId) about(about) status?.let { status(it) } @@ -119,7 +116,6 @@ class AttestationEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, content, createdAt) { - alt(ALT_DESCRIPTION) dTag(dTagId) aboutReplaceable(about) status?.let { status(it) } @@ -140,7 +136,6 @@ class AttestationEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, content, createdAt) { - alt(ALT_DESCRIPTION) dTag(dTagId) aboutAddressable(about) status?.let { status(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/proficiency/AttestorProficiencyEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/proficiency/AttestorProficiencyEvent.kt index 74dcd32098..ea8fff30ed 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/proficiency/AttestorProficiencyEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/proficiency/AttestorProficiencyEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.Kind import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -48,7 +47,6 @@ class AttestorProficiencyEvent( companion object { const val KIND = 11871 - const val ALT_DESCRIPTION = "Attestor Proficiency Declaration" fun build( kinds: List, @@ -56,7 +54,6 @@ class AttestorProficiencyEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description ?: "", createdAt) { - alt(ALT_DESCRIPTION) kinds(kinds) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/recommendation/AttestorRecommendationEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/recommendation/AttestorRecommendationEvent.kt index 373146bce6..e679dc2b10 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/recommendation/AttestorRecommendationEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/recommendation/AttestorRecommendationEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Kind import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -49,7 +48,6 @@ class AttestorRecommendationEvent( companion object { const val KIND = 31873 - const val ALT_DESCRIPTION = "Attestor Recommendation" fun build( attestorPubKey: HexKey, @@ -58,7 +56,6 @@ class AttestorRecommendationEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description ?: "", createdAt) { - alt(ALT_DESCRIPTION) dTag(attestorPubKey) kinds(kinds) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/request/AttestationRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/request/AttestationRequestEvent.kt index 0a1328c15a..c7b452a39e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/request/AttestationRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/attestations/request/AttestationRequestEvent.kt @@ -37,7 +37,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -82,7 +81,6 @@ class AttestationRequestEvent( companion object { const val KIND = 31872 - const val ALT_DESCRIPTION = "Attestation Request" fun buildEvent( dTagId: String, @@ -93,7 +91,6 @@ class AttestationRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, content, createdAt) { - alt(ALT_DESCRIPTION) dTag(dTagId) about(about) attestorPubKeys(attestorPubKeys) @@ -110,7 +107,6 @@ class AttestationRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, content, createdAt) { - alt(ALT_DESCRIPTION) dTag(dTagId) aboutReplaceable(about) attestorPubKeys(attestorPubKeys) @@ -127,7 +123,6 @@ class AttestationRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, content, createdAt) { - alt(ALT_DESCRIPTION) dTag(dTagId) aboutAddressable(about) attestorPubKeys(attestorPubKeys) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/header/AudioHeaderEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/header/AudioHeaderEvent.kt index acc168f39d..f9abe052c9 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/header/AudioHeaderEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/header/AudioHeaderEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -52,7 +51,6 @@ class AudioHeaderEvent( companion object { const val KIND = 1808 - const val ALT = "Audio header" fun build( description: String, @@ -62,7 +60,6 @@ class AudioHeaderEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description, createdAt) { - alt(ALT) downloadUrl.let { downloadUrl(it) } streamUrl?.let { streamUrl(it) } wavefront?.let { wavefront(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/track/AudioTrackEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/track/AudioTrackEvent.kt index 56c45a3920..4806cec67a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/track/AudioTrackEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/audio/track/AudioTrackEvent.kt @@ -32,7 +32,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip14Subject.SubjectTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils import kotlin.uuid.ExperimentalUuidApi @@ -65,7 +64,6 @@ class AudioTrackEvent( companion object { const val KIND = 31337 - const val ALT_DESCRIPTION = "Audio track" @OptIn(ExperimentalUuidApi::class) fun build( @@ -79,7 +77,6 @@ class AudioTrackEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { dTag(dTag) - alt(ALT_DESCRIPTION) type(type) media(media) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/bounties/BountyAddValueEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/bounties/BountyAddValueEvent.kt index 25b4ad29cd..39921e4602 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/bounties/BountyAddValueEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/bounties/BountyAddValueEvent.kt @@ -30,7 +30,6 @@ import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag import com.vitorpamplona.quartz.nip10Notes.tags.markedETag import com.vitorpamplona.quartz.nip10Notes.tags.toMarkedETag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.BigDecimal import com.vitorpamplona.quartz.utils.TimeUtils @@ -40,7 +39,6 @@ import com.vitorpamplona.quartz.utils.TimeUtils class BountyAddValueEvent { companion object { const val KIND = 1 - const val ALT_DESCRIPTION = "Add Value to Bounty" const val BOUNTY_HASH_TAG = "bounty-added-reward" @@ -54,7 +52,6 @@ class BountyAddValueEvent { tags.markedETag(bountyRoot.toMarkedETag(MarkedETag.MARKER.ROOT)) tags.hashtag(BOUNTY_HASH_TAG) tags.pTag(bountyRootAuthor) - tags.alt(ALT_DESCRIPTION) return EventTemplate(createdAt, KIND, tags.build(), amount.toString()) } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/clink/debits/DebitEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/clink/debits/DebitEvent.kt index d5dc713ef3..fb5162f52c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/clink/debits/DebitEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/clink/debits/DebitEvent.kt @@ -32,7 +32,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils /** @@ -87,7 +86,6 @@ class DebitEvent( companion object { const val KIND = 21002 - const val ALT = "CLINK debit" /** Builds a request event (requestor side) addressed to the debit service. */ suspend fun createRequest( @@ -101,7 +99,6 @@ class DebitEvent( eventTemplate(KIND, encrypted, createdAt) { pTag(servicePubKey, null) clinkVersion() - alt(ALT) }, ) } @@ -120,7 +117,6 @@ class DebitEvent( pTag(requestorPubKey, null) add(ETag.assemble(requestEvent.id, null, null)) clinkVersion() - alt(ALT) }, ) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/clink/manage/ManageEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/clink/manage/ManageEvent.kt index c2901a8669..e2cfced7c8 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/clink/manage/ManageEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/clink/manage/ManageEvent.kt @@ -32,7 +32,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils /** @@ -87,7 +86,6 @@ class ManageEvent( companion object { const val KIND = 21003 - const val ALT = "CLINK manage" /** Builds a request event (app side) addressed to the wallet server. */ suspend fun createRequest( @@ -101,7 +99,6 @@ class ManageEvent( eventTemplate(KIND, encrypted, createdAt) { pTag(serverPubKey, null) clinkVersion() - alt(ALT) }, ) } @@ -120,7 +117,6 @@ class ManageEvent( pTag(appPubKey, null) add(ETag.assemble(requestEvent.id, null, null)) clinkVersion() - alt(ALT) }, ) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/clink/offers/OfferEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/clink/offers/OfferEvent.kt index fb35b0b57f..4041843a9b 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/clink/offers/OfferEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/clink/offers/OfferEvent.kt @@ -32,7 +32,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils /** @@ -91,7 +90,6 @@ class OfferEvent( companion object { const val KIND = 21001 - const val ALT = "CLINK offer" /** Builds a request event (payer side) addressed to the offer service. */ suspend fun createRequest( @@ -105,7 +103,6 @@ class OfferEvent( eventTemplate(KIND, encrypted, createdAt) { pTag(servicePubKey, null) clinkVersion() - alt(ALT) }, ) } @@ -124,7 +121,6 @@ class OfferEvent( pTag(payerPubKey, null) add(ETag.assemble(requestEvent.id, null, null)) clinkVersion() - alt(ALT) }, ) } @@ -147,7 +143,6 @@ class OfferEvent( pTag(payerPubKey, null) add(ETag.assemble(requestEvent.id, null, null)) clinkVersion() - alt(ALT) }, ) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/decoupling/setup/EncryptionKeyListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/decoupling/setup/EncryptionKeyListEvent.kt index ff3b6dc8d2..2a5d6f6a73 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/decoupling/setup/EncryptionKeyListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/decoupling/setup/EncryptionKeyListEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.signers.eventUpdate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -43,7 +42,6 @@ class EncryptionKeyListEvent( companion object { const val KIND = 10044 - const val ALT = "Encryption keys" fun add( key: KeyTag, @@ -51,7 +49,6 @@ class EncryptionKeyListEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventUpdate(currentEvent, createdAt) { - alt(ALT) key(key) initializer() } @@ -62,7 +59,6 @@ class EncryptionKeyListEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventUpdate(currentEvent, createdAt) { - alt(ALT) removeIf(KeyTag::isSameKey, key.toTagArray()) initializer() } @@ -72,7 +68,6 @@ class EncryptionKeyListEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) keys(keys) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/edits/TextNoteModificationEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/edits/TextNoteModificationEvent.kt index 47a06d6f7e..1545a8789a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/edits/TextNoteModificationEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/edits/TextNoteModificationEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.tags.events.firstTaggedEvent -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -43,7 +42,6 @@ class TextNoteModificationEvent( companion object { const val KIND = 1010 - const val ALT = "Content Change Event" suspend fun create( content: String, @@ -63,8 +61,6 @@ class TextNoteModificationEvent( tags.add(arrayOf("summary", it)) } - tags.add(AltTag.assemble(ALT)) - return signer.sign(createdAt, KIND, tags.toTypedArray(), content) } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/ephemChat/chat/EphemeralChatEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/ephemChat/chat/EphemeralChatEvent.kt index 135e716b11..b073d67792 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/ephemChat/chat/EphemeralChatEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/ephemChat/chat/EphemeralChatEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -50,7 +49,6 @@ class EphemeralChatEvent( companion object { const val KIND = 23333 - const val ALT_DESCRIPTION = "Ephemeral Chat" const val DEFAULT_ROOM = "_" @@ -63,7 +61,6 @@ class EphemeralChatEvent( ) = eventTemplate(KIND, message, createdAt) { room(room) relay(relay) - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/ephemChat/list/EphemeralChatListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/ephemChat/list/EphemeralChatListEvent.kt index 1ba12ec2b1..02e98a628b 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/ephemChat/list/EphemeralChatListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/ephemChat/list/EphemeralChatListEvent.kt @@ -27,12 +27,9 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.removeParsing @@ -53,7 +50,6 @@ class EphemeralChatListEvent( companion object { const val KIND = 10023 - const val ALT = "Ephemeral Chat List" const val FIXED_D_TAG = "" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, FIXED_D_TAG) @@ -136,16 +132,7 @@ class EphemeralChatListEvent( tags: TagArray, signer: NostrSigner, createdAt: Long = TimeUtils.now(), - ): EphemeralChatListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } - - return signer.sign(createdAt, KIND, newTags, content) - } + ): EphemeralChatListEvent = signer.sign(createdAt, KIND, tags, content) suspend fun create( publicRooms: List = emptyList(), @@ -168,7 +155,6 @@ class EphemeralChatListEvent( description = PrivateTagsInContent.encryptNip44(privateRooms.map { it.toTagArray() }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) rooms(publicRooms) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/ExerciseGroup.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/ExerciseGroup.kt new file mode 100644 index 0000000000..26b6664df2 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/ExerciseGroup.kt @@ -0,0 +1,63 @@ +/* + * 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.quartz.experimental.fitness.workout + +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.experimental.fitness.workout.tags.ExerciseSetTag + +/** + * The sets logged for one exercise within a POWR / NIP-101e workout, grouped by + * the referenced exercise-template coordinate and ordered by set number. + */ +@Immutable +class ExerciseGroup( + val reference: String, + val sets: List, +) { + /** Best-effort human label derived from the template d-tag, e.g. `back-squat-bb` → "Back Squat Bb". */ + fun displayName(): String? = sets.firstNotNullOfOrNull { it.dTag() }?.let(::slugToTitle) + + /** Sum of every set's volume in kilograms, or null if no set has both weight and reps. */ + fun totalVolumeKg(): Double? { + val volumes = sets.mapNotNull { it.volumeKg() } + return if (volumes.isEmpty()) null else volumes.sum() + } + + /** Heaviest weight logged across the group's sets, in kilograms. */ + fun topWeightKg(): Double? = sets.mapNotNull { it.weightKg }.filter { it > 0.0 }.maxOrNull() +} + +/** Groups exercise sets by their template reference, preserving first-seen order and sorting by set number. */ +fun groupExerciseSets(sets: List): List { + if (sets.isEmpty()) return emptyList() + val byReference = LinkedHashMap>() + sets.forEach { byReference.getOrPut(it.reference) { mutableListOf() }.add(it) } + return byReference.map { (reference, groupSets) -> + ExerciseGroup(reference, groupSets.sortedBy { it.setNumber ?: Int.MAX_VALUE }) + } +} + +/** Turns a NIP-101e d-tag slug (`seated-calf-raise-machine`) into a title (`Seated Calf Raise Machine`). */ +fun slugToTitle(slug: String): String = + slug + .split('-', '_', ' ') + .filter { it.isNotBlank() } + .joinToString(" ") { word -> word.replaceFirstChar { it.uppercaseChar() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/ExerciseTemplateEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/ExerciseTemplateEvent.kt new file mode 100644 index 0000000000..78b85eee05 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/ExerciseTemplateEvent.kt @@ -0,0 +1,67 @@ +/* + * 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.quartz.experimental.fitness.workout + +import androidx.compose.runtime.Immutable +import com.vitorpamplona.quartz.experimental.fitness.workout.tags.DifficultyTag +import com.vitorpamplona.quartz.experimental.fitness.workout.tags.EquipmentTag +import com.vitorpamplona.quartz.experimental.fitness.workout.tags.FormatTag +import com.vitorpamplona.quartz.experimental.fitness.workout.tags.FormatUnitsTag +import com.vitorpamplona.quartz.experimental.fitness.workout.tags.TitleTag +import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent +import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip50Search.SearchableEvent + +/** + * NIP-101e (draft) exercise template, kind 33401, as published by POWR. An + * addressable, reusable definition referenced from the per-set `exercise` tags + * of a [WorkoutRecordEvent] via its `33401:pubkey:d-tag` coordinate. + * + * Amethyst fetches these to show a real exercise name (and equipment) in a + * workout card instead of the d-tag slug. Parsing is lax: every tag optional. + */ +@Immutable +class ExerciseTemplateEvent( + id: HexKey, + pubKey: HexKey, + createdAt: Long, + tags: Array>, + content: String, + sig: HexKey, +) : BaseAddressableEvent(id, pubKey, createdAt, KIND, tags, content, sig), + SearchableEvent { + override fun indexableContent() = listOfNotNull(title(), content).joinToString("\n") + + fun title() = tags.firstNotNullOfOrNull(TitleTag::parse) + + fun format() = tags.firstNotNullOfOrNull(FormatTag::parse) + + fun formatUnits() = tags.firstNotNullOfOrNull(FormatUnitsTag::parse) + + fun equipment() = tags.firstNotNullOfOrNull(EquipmentTag::parse) + + fun difficulty() = tags.firstNotNullOfOrNull(DifficultyTag::parse) + + companion object { + const val KIND = 33401 + const val ALT_DESCRIPTION = "Exercise template" + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/TagArrayExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/TagArrayExt.kt index 2f56b1fa0b..eb80669d86 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/TagArrayExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/TagArrayExt.kt @@ -26,16 +26,23 @@ import com.vitorpamplona.quartz.experimental.fitness.workout.tags.DistanceTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.DurationTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.ElevationGainTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.ElevationLossTag +import com.vitorpamplona.quartz.experimental.fitness.workout.tags.ExerciseSetTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.ExerciseTag +import com.vitorpamplona.quartz.experimental.fitness.workout.tags.ExerciseType import com.vitorpamplona.quartz.experimental.fitness.workout.tags.MaxHeartRateTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.RepsTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.SetsTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.SourceTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.SplitTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.StepsTag +import com.vitorpamplona.quartz.experimental.fitness.workout.tags.TemplateTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.TitleTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.WeightTag +import com.vitorpamplona.quartz.experimental.fitness.workout.tags.WorkoutCompletedTag +import com.vitorpamplona.quartz.experimental.fitness.workout.tags.WorkoutEndTag +import com.vitorpamplona.quartz.experimental.fitness.workout.tags.WorkoutStartTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.WorkoutStartTimeTag +import com.vitorpamplona.quartz.experimental.fitness.workout.tags.WorkoutTypeTag import com.vitorpamplona.quartz.nip01Core.core.TagArray fun TagArray.title() = firstNotNullOfOrNull(TitleTag::parse) @@ -71,3 +78,31 @@ fun TagArray.weight() = firstNotNullOfOrNull(WeightTag::parse) fun TagArray.workoutSource() = firstNotNullOfOrNull(SourceTag::parse) fun TagArray.workoutStartTime() = firstNotNullOfOrNull(WorkoutStartTimeTag::parse) + +// --- POWR / NIP-101e strength dialect --- + +fun TagArray.workoutTypeCode() = firstNotNullOfOrNull(WorkoutTypeTag::parse) + +fun TagArray.workoutType() = workoutTypeCode()?.let(ExerciseType::parse) + +fun TagArray.workoutStart() = firstNotNullOfOrNull(WorkoutStartTag::parse) + +fun TagArray.workoutEnd() = firstNotNullOfOrNull(WorkoutEndTag::parse) + +fun TagArray.workoutCompleted() = firstNotNullOfOrNull(WorkoutCompletedTag::parse) + +fun TagArray.exerciseSets() = mapNotNull(ExerciseSetTag::parse) + +fun TagArray.exerciseSetAddressIds() = mapNotNull(ExerciseSetTag::parseAddressId) + +fun TagArray.exerciseSetHints() = mapNotNull(ExerciseSetTag::parseAsHint) + +fun TagArray.templateAddressId() = firstNotNullOfOrNull(TemplateTag::parseAddressId) + +fun TagArray.templateHint() = firstNotNullOfOrNull(TemplateTag::parseAsHint) + +/** The client name from a `["client", name, ...]` tag (RUNSTR and POWR both emit this). */ +fun TagArray.clientName() = + firstNotNullOfOrNull { tag -> + if (tag.size > 1 && tag[0] == "client" && tag[1].isNotEmpty()) tag[1] else null + } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/WorkoutRecordEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/WorkoutRecordEvent.kt index 028304279d..25935aa2f4 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/WorkoutRecordEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/WorkoutRecordEvent.kt @@ -25,9 +25,9 @@ import com.vitorpamplona.quartz.experimental.fitness.workout.tags.ExerciseType import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder +import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip22Comments.RootScope -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils import kotlin.uuid.ExperimentalUuidApi @@ -50,9 +50,21 @@ class WorkoutRecordEvent( sig: HexKey, ) : Event(id, pubKey, createdAt, KIND, tags, content, sig), RootScope, - SearchableEvent { + SearchableEvent, + AddressHintProvider { override fun indexableContent() = listOfNotNull(title(), content).joinToString("\n") + // POWR / NIP-101e workouts reference kind-33401 exercise templates (and a kind-33402 + // workout template) by coordinate + relay hint, so the templates can be fetched and + // rendered with real names. RUNSTR workouts carry none of these and contribute nothing. + override fun addressHints() = + buildList { + addAll(tags.exerciseSetHints()) + tags.templateHint()?.let { add(it) } + } + + override fun linkedAddressIds() = (tags.exerciseSetAddressIds() + listOfNotNull(tags.templateAddressId())).distinct() + fun title() = tags.title() fun exercise() = tags.exercise() @@ -87,9 +99,40 @@ class WorkoutRecordEvent( fun workoutStartTime() = tags.workoutStartTime() + // --- POWR / NIP-101e strength dialect --- + + fun workoutTypeCode() = tags.workoutTypeCode() + + fun workoutType() = tags.workoutType() + + fun workoutStart() = tags.workoutStart() + + fun workoutEnd() = tags.workoutEnd() + + fun workoutCompleted() = tags.workoutCompleted() + + fun exerciseSets() = tags.exerciseSets() + + fun exerciseGroups() = groupExerciseSets(exerciseSets()) + + fun client() = tags.clientName() + + /** Activity type, preferring the POWR `type` tag and falling back to the RUNSTR `exercise` verb. */ + fun activityType() = workoutType() ?: exerciseType() + + /** + * Duration in seconds: the explicit `duration` tag if present (RUNSTR), + * otherwise derived from the POWR `start`/`end` session timestamps. + */ + fun effectiveDurationSeconds(): Long? { + durationSeconds()?.let { return it } + val start = workoutStart() + val end = workoutEnd() + return if (start != null && end != null && end > start) end - start else null + } + companion object { const val KIND = 1301 - const val ALT_DESCRIPTION = "Workout record" @OptIn(ExperimentalUuidApi::class) fun build( @@ -101,7 +144,6 @@ class WorkoutRecordEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, notes, createdAt) { - alt(ALT_DESCRIPTION) dTag(workoutId) exercise(exercise) hashtag(exercise.hashtag) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/ExerciseSetTag.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/ExerciseSetTag.kt new file mode 100644 index 0000000000..e3dfc355af --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/ExerciseSetTag.kt @@ -0,0 +1,115 @@ +/* + * 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.quartz.experimental.fitness.workout.tags + +import androidx.compose.runtime.Stable +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint +import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer +import com.vitorpamplona.quartz.utils.ensure + +/** + * A single logged set in the POWR / NIP-101e strength dialect. + * + * Tag layout: `["exercise", "::", "", weight, reps, + * rpe, set_type, set_number]`, where the second element is an addressable + * coordinate to a kind-33401 exercise template. The set fields, in order: + * + * - **weight** — kilograms; empty string means bodyweight, negative means assisted. + * - **reps** — repetition count. + * - **rpe** — Rate of Perceived Exertion, 0..10. + * - **set_type** — `warmup` | `normal` | `drop` | `failure`. + * - **set_number** — 1-based index (POWR extension, not in the base spec). + * + * This is structurally distinct from RUNSTR's `exercise` tag (a plain activity + * verb such as `running`), so [parse] only matches the coordinate form. + */ +@Stable +class ExerciseSetTag( + val reference: String, + val relayHint: String?, + val weightKg: Double?, + val reps: Int?, + val rpe: Double?, + val setType: String?, + val setNumber: Int?, +) { + /** The d-tag slug of the referenced exercise template, e.g. `back-squat-bb`. */ + fun dTag(): String? = reference.split(":", limit = 3).getOrNull(2)?.ifBlank { null } + + /** Volume of this set in kilograms (weight × reps), when both are known and positive. */ + fun volumeKg(): Double? { + val w = weightKg ?: return null + val r = reps ?: return null + return if (w > 0.0 && r > 0) w * r else null + } + + companion object { + const val TAG_NAME = "exercise" + + const val SET_TYPE_WARMUP = "warmup" + const val SET_TYPE_NORMAL = "normal" + const val SET_TYPE_DROP = "drop" + const val SET_TYPE_FAILURE = "failure" + + /** + * True when [value] is an addressable coordinate (`kind:pubkey:d-tag`) rather + * than a plain verb. Used to tell the POWR `exercise` form from RUNSTR's. + */ + fun isCoordinate(value: String): Boolean { + val parts = value.split(":", limit = 3) + return parts.size == 3 && parts[0].toIntOrNull() != null && parts[1].length == 64 + } + + /** The referenced exercise-template coordinate, when the tag is the POWR set form. */ + fun parseAddressId(tag: Array): String? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + ensure(isCoordinate(tag[1])) { return null } + return tag[1] + } + + /** The relay hint for the referenced exercise template, so it can be fetched. */ + fun parseAsHint(tag: Array): AddressHint? { + ensure(tag.has(2)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + ensure(isCoordinate(tag[1])) { return null } + ensure(tag[2].isNotEmpty()) { return null } + val relayHint = RelayUrlNormalizer.normalizeOrNull(tag[2]) ?: return null + return AddressHint(tag[1], relayHint) + } + + fun parse(tag: Array): ExerciseSetTag? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + ensure(isCoordinate(tag[1])) { return null } + return ExerciseSetTag( + reference = tag[1], + relayHint = tag.getOrNull(2)?.ifBlank { null }, + weightKg = tag.getOrNull(3)?.toDoubleOrNull(), + reps = tag.getOrNull(4)?.toIntOrNull(), + rpe = tag.getOrNull(5)?.toDoubleOrNull(), + setType = tag.getOrNull(6)?.ifBlank { null }, + setNumber = tag.getOrNull(7)?.toIntOrNull(), + ) + } + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/ExerciseTag.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/ExerciseTag.kt index 0621bdf17b..ced95e493a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/ExerciseTag.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/ExerciseTag.kt @@ -24,9 +24,13 @@ import com.vitorpamplona.quartz.nip01Core.core.has import com.vitorpamplona.quartz.utils.ensure /** - * Activity verbs used by NIP-101e clients (RUNSTR dialect). The tag value is the - * lowercase [code]; the matching capitalized [hashtag] is published as a `t` tag - * so the workout is discoverable. + * Activity / workout types understood across the kind-1301 dialects. + * + * The first group are the RUNSTR activity verbs carried in the `exercise` tag; + * the [STRENGTH]/[CIRCUIT]/[EMOM]/[AMRAP] values double as the POWR / NIP-101e + * `type` tag classifications. The tag value is the lowercase [code]; the + * matching capitalized [hashtag] is published as a `t` tag so RUNSTR workouts + * stay discoverable. */ enum class ExerciseType( val code: String, @@ -43,6 +47,9 @@ enum class ExerciseType( MEDITATION("meditation", "Meditation"), DIET("diet", "Diet"), FASTING("fasting", "Fasting"), + CIRCUIT("circuit", "Circuit"), + EMOM("emom", "EMOM"), + AMRAP("amrap", "AMRAP"), ; companion object { @@ -56,11 +63,17 @@ class ExerciseTag { fun isTag(tag: Array) = tag.has(1) && tag[0] == TAG_NAME && tag[1].isNotEmpty() - /** Returns the raw verb. Other clients may publish verbs outside [ExerciseType]. */ + /** + * Returns the raw activity verb. Other clients may publish verbs outside + * [ExerciseType]. Returns null for the POWR coordinate form + * (`33401:pubkey:d-tag`), which carries per-set data, not a verb — parse + * those with [ExerciseSetTag] instead. + */ fun parse(tag: Array): String? { ensure(tag.has(1)) { return null } ensure(tag[0] == TAG_NAME) { return null } ensure(tag[1].isNotEmpty()) { return null } + ensure(!ExerciseSetTag.isCoordinate(tag[1])) { return null } return tag[1] } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/ExerciseTemplateTags.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/ExerciseTemplateTags.kt new file mode 100644 index 0000000000..55568d5268 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/ExerciseTemplateTags.kt @@ -0,0 +1,78 @@ +/* + * 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.quartz.experimental.fitness.workout.tags + +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.utils.ensure + +/** The ordered parameter names a kind-33401 exercise expects per set, e.g. `weight reps rpe set_type`. */ +class FormatTag { + companion object { + const val TAG_NAME = "format" + + fun parse(tag: Array): List? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + return tag.drop(1).filter { it.isNotEmpty() }.ifEmpty { null } + } + } +} + +/** The units for each [FormatTag] parameter, e.g. `kg count 0-10 enum`. */ +class FormatUnitsTag { + companion object { + const val TAG_NAME = "format_units" + + fun parse(tag: Array): List? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + return tag.drop(1).filter { it.isNotEmpty() }.ifEmpty { null } + } + } +} + +/** Equipment used by a kind-33401 exercise: `barbell` | `dumbbell` | `bodyweight` | `machine` | `cardio`. */ +class EquipmentTag { + companion object { + const val TAG_NAME = "equipment" + + fun parse(tag: Array): String? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + ensure(tag[1].isNotEmpty()) { return null } + return tag[1] + } + } +} + +/** Difficulty of a kind-33401 exercise: `beginner` | `intermediate` | `advanced`. */ +class DifficultyTag { + companion object { + const val TAG_NAME = "difficulty" + + fun parse(tag: Array): String? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + ensure(tag[1].isNotEmpty()) { return null } + return tag[1] + } + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/TemplateTag.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/TemplateTag.kt new file mode 100644 index 0000000000..176fed85cf --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/TemplateTag.kt @@ -0,0 +1,54 @@ +/* + * 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.quartz.experimental.fitness.workout.tags + +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint +import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer +import com.vitorpamplona.quartz.utils.ensure + +/** + * Reference to the kind-33402 workout template a POWR session was built from: + * `["template", "33402:pubkey:d-tag", ""]`. + */ +class TemplateTag { + companion object { + const val TAG_NAME = "template" + + fun isTag(tag: Array) = tag.has(1) && tag[0] == TAG_NAME && tag[1].isNotEmpty() + + fun parseAddressId(tag: Array): String? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + ensure(ExerciseSetTag.isCoordinate(tag[1])) { return null } + return tag[1] + } + + fun parseAsHint(tag: Array): AddressHint? { + ensure(tag.has(2)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + ensure(ExerciseSetTag.isCoordinate(tag[1])) { return null } + ensure(tag[2].isNotEmpty()) { return null } + val relayHint = RelayUrlNormalizer.normalizeOrNull(tag[2]) ?: return null + return AddressHint(tag[1], relayHint) + } + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/WorkoutSessionTimeTags.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/WorkoutSessionTimeTags.kt new file mode 100644 index 0000000000..52797eb38f --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/WorkoutSessionTimeTags.kt @@ -0,0 +1,78 @@ +/* + * 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.quartz.experimental.fitness.workout.tags + +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.utils.ensure + +/** + * Session start time (unix seconds) as published by the POWR / NIP-101e dialect. + * RUNSTR uses [WorkoutStartTimeTag] (`workout_start_time`) instead. + */ +class WorkoutStartTag { + companion object { + const val TAG_NAME = "start" + + fun isTag(tag: Array) = tag.has(1) && tag[0] == TAG_NAME && tag[1].isNotEmpty() + + fun parse(tag: Array): Long? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + return tag[1].toLongOrNull() + } + + fun assemble(timestamp: Long) = arrayOf(TAG_NAME, timestamp.toString()) + } +} + +/** Session end time (unix seconds), POWR / NIP-101e dialect. */ +class WorkoutEndTag { + companion object { + const val TAG_NAME = "end" + + fun isTag(tag: Array) = tag.has(1) && tag[0] == TAG_NAME && tag[1].isNotEmpty() + + fun parse(tag: Array): Long? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + return tag[1].toLongOrNull() + } + + fun assemble(timestamp: Long) = arrayOf(TAG_NAME, timestamp.toString()) + } +} + +/** Whether the session was completed as planned, POWR / NIP-101e dialect. */ +class WorkoutCompletedTag { + companion object { + const val TAG_NAME = "completed" + + fun isTag(tag: Array) = tag.has(1) && tag[0] == TAG_NAME && tag[1].isNotEmpty() + + fun parse(tag: Array): Boolean? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + return tag[1].toBooleanStrictOrNull() + } + + fun assemble(completed: Boolean) = arrayOf(TAG_NAME, completed.toString()) + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/WorkoutTypeTag.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/WorkoutTypeTag.kt new file mode 100644 index 0000000000..f175022bd6 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/fitness/workout/tags/WorkoutTypeTag.kt @@ -0,0 +1,46 @@ +/* + * 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.quartz.experimental.fitness.workout.tags + +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.utils.ensure + +/** + * Workout classification used by the POWR / NIP-101e strength dialect, e.g. + * `strength`, `circuit`, `emom`, `amrap`. RUNSTR clients put the activity verb + * in the `exercise` tag instead and omit this one, so treat it as optional. + */ +class WorkoutTypeTag { + companion object { + const val TAG_NAME = "type" + + fun isTag(tag: Array) = tag.has(1) && tag[0] == TAG_NAME && tag[1].isNotEmpty() + + fun parse(tag: Array): String? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + ensure(tag[1].isNotEmpty()) { return null } + return tag[1] + } + + fun assemble(type: String) = arrayOf(TAG_NAME, type) + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryReadingStateEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryReadingStateEvent.kt index 51d45eb745..32a71a23c3 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryReadingStateEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/interactiveStories/InteractiveStoryReadingStateEvent.kt @@ -35,7 +35,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip23LongContent.tags.ImageTag import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip94FileMetadata.tags.SummaryTag import com.vitorpamplona.quartz.nip99Classifieds.tags.StatusTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -63,8 +62,6 @@ class InteractiveStoryReadingStateEvent( companion object { const val KIND = 30298 - const val ALT1 = "Interactive Story Reading state" - const val ALT2 = "The reading state of " fun createAddress( pubKey: HexKey, @@ -125,7 +122,6 @@ class InteractiveStoryReadingStateEvent( } dTag(rootTag.toTag()) - alt(root.event.title()?.let { ALT2 + it } ?: ALT1) rootScene(rootTag) currentScene(sceneTag) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/medical/FhirResourceEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/medical/FhirResourceEvent.kt index 721aa0234b..b95823d72b 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/medical/FhirResourceEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/medical/FhirResourceEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -39,14 +38,12 @@ class FhirResourceEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 82 - const val ALT_DESCRIPTION = "Medical data" fun build( fhirPayload: String, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, fhirPayload, createdAt) { - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/music/playlist/MusicPlaylistEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/music/playlist/MusicPlaylistEvent.kt index 3484ef974c..d264b1c53a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/music/playlist/MusicPlaylistEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/music/playlist/MusicPlaylistEvent.kt @@ -39,7 +39,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils import kotlin.uuid.ExperimentalUuidApi @@ -92,7 +91,6 @@ class MusicPlaylistEvent( companion object { const val KIND = 34139 - const val ALT_DESCRIPTION_PREFIX = "Playlist" const val CATEGORY_TAG = "playlist" @OptIn(ExperimentalUuidApi::class) @@ -111,7 +109,6 @@ class MusicPlaylistEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, content, createdAt) { dTag(dTag) - alt("$ALT_DESCRIPTION_PREFIX: $title") title(title) hashtag(CATEGORY_TAG) @@ -172,7 +169,6 @@ class MusicPlaylistEvent( val newTags = earlierVersion.tags.builder { title(title) - alt("$ALT_DESCRIPTION_PREFIX: $title") setOrRemove(image, ImageTag.TAG_NAME, ::image) setOrRemove(description, DescriptionTag.TAG_NAME, ::description) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/music/track/MusicTrackEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/music/track/MusicTrackEvent.kt index 5256ee2c1b..1b29032bc8 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/music/track/MusicTrackEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/music/track/MusicTrackEvent.kt @@ -43,7 +43,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils import kotlin.uuid.ExperimentalUuidApi @@ -91,7 +90,6 @@ class MusicTrackEvent( companion object { const val KIND = 36787 - const val ALT_DESCRIPTION_PREFIX = "Music track" const val GENRE_TAG = "music" @OptIn(ExperimentalUuidApi::class) @@ -116,7 +114,6 @@ class MusicTrackEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description, createdAt) { dTag(dTag) - alt("$ALT_DESCRIPTION_PREFIX: $title by $artist") title(title) artist(artist) @@ -166,7 +163,6 @@ class MusicTrackEvent( title(title) artist(artist) url(url) - alt("$ALT_DESCRIPTION_PREFIX: $title by $artist") setOrRemove(image, ImageTag.TAG_NAME, ::image) setOrRemove(album, AlbumTag.TAG_NAME, ::album) if (duration != null) duration(duration) else remove(DurationTag.TAG_NAME) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/application/SoftwareApplicationEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/application/SoftwareApplicationEvent.kt index 2110f878ea..4b34461d2e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/application/SoftwareApplicationEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/application/SoftwareApplicationEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.HashtagTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -75,7 +74,6 @@ class SoftwareApplicationEvent( companion object { const val KIND = 32267 - const val ALT_DESCRIPTION = "Software application" fun build( appId: String, @@ -85,7 +83,6 @@ class SoftwareApplicationEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description, createdAt) { dTag(appId) - alt(ALT_DESCRIPTION) name(name) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/asset/SoftwareAssetEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/asset/SoftwareAssetEvent.kt index a58e4ddf5e..5d04e7606a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/asset/SoftwareAssetEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/asset/SoftwareAssetEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils /** @@ -81,7 +80,6 @@ class SoftwareAssetEvent( companion object { const val KIND = 3063 - const val ALT_DESCRIPTION = "Software asset" fun build( appId: String, @@ -93,7 +91,6 @@ class SoftwareAssetEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) appId(appId) mimeType(mimeType) hash(hash) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/release/SoftwareReleaseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/release/SoftwareReleaseEvent.kt index 1927c70c97..36d9a99d36 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/release/SoftwareReleaseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip82SoftwareApps/release/SoftwareReleaseEvent.kt @@ -30,7 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -77,7 +76,6 @@ class SoftwareReleaseEvent( companion object { const val KIND = 30063 - const val ALT_DESCRIPTION = "Software release" /** NIP-82 requires `d = @`. */ fun buildDTag( @@ -95,7 +93,6 @@ class SoftwareReleaseEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, releaseNotes, createdAt) { dTag(buildDTag(appId, version)) - alt(ALT_DESCRIPTION) appId(appId) version(version) channel(channel) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip95/data/FileStorageEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip95/data/FileStorageEvent.kt index 46b7385a13..ef2b7636d7 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip95/data/FileStorageEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip95/data/FileStorageEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils import kotlin.io.encoding.Base64 @@ -45,7 +44,6 @@ class FileStorageEvent( companion object { const val KIND = 1064 - const val ALT = "Binary data" fun decode(content: String): ByteArray? = runCatching { Base64.decode(content) }.getOrNull() @@ -58,7 +56,6 @@ class FileStorageEvent( initializer: TagArrayBuilder.() -> Unit = {}, ): EventTemplate = eventTemplate(KIND, encode(data), createdAt) { - alt(ALT) mimeType?.let { mimeType(it) } initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip95/header/FileStorageHeaderEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip95/header/FileStorageHeaderEvent.kt index 02c0625425..ad121b8bd0 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip95/header/FileStorageHeaderEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nip95/header/FileStorageHeaderEvent.kt @@ -31,7 +31,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.events.eTag import com.vitorpamplona.quartz.nip01Core.tags.events.toETag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag @@ -98,7 +97,6 @@ class FileStorageHeaderEvent( companion object { const val KIND = 1065 - const val ALT_DESCRIPTION = "Descriptors for a binary file" fun build( storageEvent: EventHintBundle, @@ -107,7 +105,6 @@ class FileStorageHeaderEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, caption ?: "", createdAt) { eTag(storageEvent.toETag()) - caption?.ifBlank { null }?.let { alt(caption) } ?: alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nipA3/PaymentTargetsEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nipA3/PaymentTargetsEvent.kt index fe38dcd24b..7ee3be366f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nipA3/PaymentTargetsEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nipA3/PaymentTargetsEvent.kt @@ -24,7 +24,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils class PaymentTargetsEvent( @@ -39,7 +38,6 @@ class PaymentTargetsEvent( companion object { const val KIND = 10133 - const val ALT = "Payment targets" const val FIXED_D_TAG = "" fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) @@ -54,13 +52,12 @@ class PaymentTargetsEvent( earlierVersion.tags .filter(PaymentTargetTag::notMatch) .plus(targets.map { PaymentTargetTag.assemble(it) }) - .plusElement(AltTag.assemble(ALT)) .toTypedArray() return signer.sign(createdAt, KIND, tags, earlierVersion.content) } - fun createPaymentTargets(targets: List) = (targets.map { PaymentTargetTag.assemble(it) } + listOf(AltTag.assemble(ALT))).toTypedArray() + fun createPaymentTargets(targets: List) = targets.map { PaymentTargetTag.assemble(it) }.toTypedArray() suspend fun create( targets: List, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nipsOnNostr/NipTextEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nipsOnNostr/NipTextEvent.kt index f25763b1b2..a754a6f817 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nipsOnNostr/NipTextEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nipsOnNostr/NipTextEvent.kt @@ -45,7 +45,6 @@ import com.vitorpamplona.quartz.nip19Bech32.eventHints import com.vitorpamplona.quartz.nip19Bech32.eventIds import com.vitorpamplona.quartz.nip22Comments.RootScope import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils import kotlin.uuid.ExperimentalUuidApi @@ -139,7 +138,6 @@ class NipTextEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description, createdAt) { dTag(dTag) - alt("NIP: $title") title(title) kinds(kinds) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nns/NNSEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nns/NNSEvent.kt index a5d5d2a402..5bd6403a58 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nns/NNSEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/nns/NNSEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -48,13 +47,11 @@ class NNSEvent( companion object { const val KIND = 30053 - const val ALT = "DNS records" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } @@ -63,7 +60,6 @@ class NNSEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) ipv4(ipv4) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/notifications/wake/WakeUpEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/notifications/wake/WakeUpEvent.kt index 33b567a8dd..0bd33866fb 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/notifications/wake/WakeUpEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/notifications/wake/WakeUpEvent.kt @@ -33,7 +33,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.kinds.kind import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.toPTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.serialization.json.JsonNull.content @@ -80,7 +79,6 @@ class WakeUpEvent( companion object { const val KIND = 23903 - const val ALT_DESCRIPTION = "WakeUp" // p-tags on a WakeUp identify the AUTHORS of the referenced events — // the people whose events are the subject of the wake-up and who should @@ -91,7 +89,6 @@ class WakeUpEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, content, createdAt) { - alt(ALT_DESCRIPTION) about(about) notify(about.toPTag()) kind(about.event.kind) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/profileGallery/GalleryListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/profileGallery/GalleryListEvent.kt index 64ef180927..f30941c49c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/profileGallery/GalleryListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/profileGallery/GalleryListEvent.kt @@ -24,7 +24,6 @@ import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -41,7 +40,6 @@ class GalleryListEvent( @Suppress("DEPRECATION") companion object { const val KIND = 10011 - const val ALT = "Profile Gallery" const val GALLERY_TAG_NAME = "url" suspend fun addEvent( @@ -127,16 +125,7 @@ class GalleryListEvent( tags: Array>, signer: NostrSigner, createdAt: Long = TimeUtils.now(), - ): GalleryListEvent { - val newTags = - if (tags.any { it.size > 1 && it[0] == "alt" }) { - tags - } else { - tags + AltTag.assemble(ALT) - } - - return signer.sign(createdAt, KIND, newTags, content) - } + ): GalleryListEvent = signer.sign(createdAt, KIND, tags, content) } @Immutable diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/profileGallery/ProfileGalleryEntryEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/profileGallery/ProfileGalleryEntryEvent.kt index 29cf7f16d0..b27bac9906 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/profileGallery/ProfileGalleryEntryEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/profileGallery/ProfileGalleryEntryEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.core.any import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.events.ETag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag @@ -99,7 +98,6 @@ class ProfileGalleryEntryEvent( companion object { const val KIND = 1163 - const val ALT_DESCRIPTION = "Profile Gallery Entry" fun build( url: String, @@ -107,7 +105,6 @@ class ProfileGalleryEntryEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { url(url) - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/roadstr/confirmation/RoadEventConfirmationEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/roadstr/confirmation/RoadEventConfirmationEvent.kt index 746fe9200b..1674a7fd97 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/roadstr/confirmation/RoadEventConfirmationEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/roadstr/confirmation/RoadEventConfirmationEvent.kt @@ -36,7 +36,6 @@ import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashes import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip40Expiration.expiration import com.vitorpamplona.quartz.utils.TimeUtils @@ -90,14 +89,6 @@ class RoadEventConfirmationEvent( companion object { const val KIND = 1316 - /** NIP-31 fallback for a confirmation (`still_there`), per the roadstr spec. */ - const val ALT_CONFIRMED = "Roadstr: event confirmed" - - /** NIP-31 fallback for a denial (`no_longer_there`), per the roadstr spec. */ - const val ALT_DENIED = "Roadstr: event denied" - - fun altDescription(status: RoadEventStatus) = if (status == RoadEventStatus.NO_LONGER_THERE) ALT_DENIED else ALT_CONFIRMED - fun build( reportId: HexKey, status: RoadEventStatus, @@ -113,7 +104,6 @@ class RoadEventConfirmationEvent( coordinates(latitude, longitude) } expiration(createdAt + RoadEventReportEvent.RELAY_TTL_SECONDS) - alt(altDescription(status)) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/roadstr/report/RoadEventReportEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/roadstr/report/RoadEventReportEvent.kt index 1d7eb8747c..319b8d22ee 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/roadstr/report/RoadEventReportEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/roadstr/report/RoadEventReportEvent.kt @@ -32,7 +32,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashes import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip40Expiration.expiration import com.vitorpamplona.quartz.utils.TimeUtils @@ -87,13 +86,10 @@ class RoadEventReportEvent( companion object { const val KIND = 1315 - const val ALT_PREFIX = "Roadstr: " /** Fixed relay-side NIP-40 window (14 days) for both report and confirmation events. */ const val RELAY_TTL_SECONDS = 1_209_600L - fun altDescription(type: RoadEventType) = "$ALT_PREFIX${type.code} report" - fun build( type: RoadEventType, latitude: Double, @@ -106,7 +102,6 @@ class RoadEventReportEvent( roadGeohashes(latitude, longitude) coordinates(latitude, longitude) expiration(createdAt + RELAY_TTL_SECONDS) - alt(altDescription(type)) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/zapPolls/ZapPollEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/zapPolls/ZapPollEvent.kt index 2b1ff294a1..385e58d3ad 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/zapPolls/ZapPollEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/experimental/zapPolls/ZapPollEvent.kt @@ -46,7 +46,6 @@ import com.vitorpamplona.quartz.nip19Bech32.eventHints import com.vitorpamplona.quartz.nip19Bech32.eventIds import com.vitorpamplona.quartz.nip19Bech32.pubKeyHints import com.vitorpamplona.quartz.nip19Bech32.pubKeys -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -129,7 +128,6 @@ class ZapPollEvent( companion object { const val KIND = 6969 - const val ALT_DESCRIPTION = "Poll event" fun build( post: String, @@ -139,7 +137,6 @@ class ZapPollEvent( ): EventTemplate { val tags = TagArrayBuilder() tags.pollOptions(options) - tags.alt(ALT_DESCRIPTION) tags.apply(initializer) return EventTemplate(createdAt, KIND, tags.build(), post) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/marmot/mip00KeyPackages/KeyPackageEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/marmot/mip00KeyPackages/KeyPackageEvent.kt index c8d01ddc6e..c00378e80f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/marmot/mip00KeyPackages/KeyPackageEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/marmot/mip00KeyPackages/KeyPackageEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils /** @@ -85,7 +84,6 @@ class KeyPackageEvent( companion object { const val KIND = 30443 - const val ALT_DESCRIPTION = "MLS KeyPackage" fun build( keyPackageBase64: String, @@ -97,7 +95,6 @@ class KeyPackageEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, keyPackageBase64, createdAt) { - alt(ALT_DESCRIPTION) dTag(dTagSlot) mlsProtocolVersion() mlsCiphersuite(ciphersuite) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/marmot/mip00KeyPackages/KeyPackageRelayListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/marmot/mip00KeyPackages/KeyPackageRelayListEvent.kt index dbbfff6198..137afb2c55 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/marmot/mip00KeyPackages/KeyPackageRelayListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/marmot/mip00KeyPackages/KeyPackageRelayListEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.isLocalHost import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils /** @@ -53,7 +52,6 @@ class KeyPackageRelayListEvent( companion object { const val KIND = 10051 - const val ALT_DESCRIPTION = "MLS KeyPackage relay list" fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) @@ -62,7 +60,6 @@ class KeyPackageRelayListEvent( private fun createTagArray(relays: List): Array> = relays .map { RelayTag.assemble(it) } - .plusElement(AltTag.assemble(ALT_DESCRIPTION)) .toTypedArray() suspend fun create( diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/marmot/mip04EncryptedMedia/Mip04IMetaTag.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/marmot/mip04EncryptedMedia/Mip04IMetaTag.kt index 7f78d36dd1..c07fffca78 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/marmot/mip04EncryptedMedia/Mip04IMetaTag.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/marmot/mip04EncryptedMedia/Mip04IMetaTag.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.quartz.marmot.mip04EncryptedMedia import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray import com.vitorpamplona.quartz.nip01Core.core.toHexKey +import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip92IMeta.IMetaTag import com.vitorpamplona.quartz.nip92IMeta.IMetaTagBuilder import com.vitorpamplona.quartz.utils.Log @@ -167,6 +168,7 @@ fun buildMip04IMetaTag( dimensions: String? = null, blurhash: String? = null, thumbhash: String? = null, + alt: String? = null, ): IMetaTag = IMetaTagBuilder(url) .apply { @@ -178,4 +180,6 @@ fun buildMip04IMetaTag( dimensions?.let { add(Mip04Fields.DIMENSIONS, it) } blurhash?.let { add(Mip04Fields.BLURHASH, it) } thumbhash?.let { add(Mip04Fields.THUMBHASH, it) } + // imeta accessibility description (NIP-92/94 "alt"); only when provided. + alt?.ifBlank { null }?.let { add(AltTag.TAG_NAME, it) } }.build() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/metadata/MetadataEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/metadata/MetadataEvent.kt index 2a3d427b70..8a2f1eb445 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/metadata/MetadataEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/metadata/MetadataEvent.kt @@ -41,7 +41,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip39ExtIdentities.IdentityClaimTag import com.vitorpamplona.quartz.nip39ExtIdentities.claims import com.vitorpamplona.quartz.nip39ExtIdentities.githubClaim @@ -127,8 +126,6 @@ class MetadataEvent( val content = Json.encodeToString(JsonObject.serializer(), newJsonObject) return eventTemplate(KIND, content, createdAt) { - alt("User profile for $name") - updateOrDeleteTagNames(metadata) initializer() @@ -175,8 +172,6 @@ class MetadataEvent( val content = Json.encodeToString(JsonObject.serializer(), newJsonObject) return eventTemplate(KIND, content, createdAt) { - alt("User profile for ${currentMetadata["name"]?.text ?: "Anonymous"}") - // For https://github.com/nostr-protocol/nips/pull/1770 updateOrDeleteTagNames(currentMetadata) @@ -233,8 +228,6 @@ class MetadataEvent( val tags = latest.tags.builder { - alt("User profile for ${currentMetadata["name"]?.text ?: "Anonymous"}") - updateOrDeleteTagNames(currentMetadata) val newClaims = latest.replaceClaims(twitter, mastodon, github) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip02FollowList/ContactListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip02FollowList/ContactListEvent.kt index 69fce5ddd0..293fc606d1 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip02FollowList/ContactListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip02FollowList/ContactListEvent.kt @@ -33,7 +33,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser import com.vitorpamplona.quartz.nip02FollowList.tags.ContactTag -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils @Stable @@ -80,7 +79,6 @@ class ContactListEvent( companion object { const val KIND = 3 - const val ALT = "Follow List" fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey) @@ -177,16 +175,7 @@ class ContactListEvent( tags: Array>, signer: NostrSigner, createdAt: Long = TimeUtils.now(), - ): ContactListEvent { - val newTags = - if (tags.any { it.size > 1 && it[0] == "alt" }) { - tags - } else { - tags + AltTag.assemble(ALT) - } - - return signer.sign(createdAt, KIND, newTags, content) - } + ): ContactListEvent = signer.sign(createdAt, KIND, tags, content) fun createFromScratch( followUsers: List = emptyList(), @@ -196,9 +185,7 @@ class ContactListEvent( ): ContactListEvent { val content = relayUse?.let { RelaySet.assemble(it) } ?: "" - val tags = - listOf(AltTag.assemble(ALT)) + - followUsers.map { it.toTagArray() } + val tags = followUsers.map { it.toTagArray() } return signer.sign(createdAt, KIND, tags.toTypedArray(), content) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip03Timestamp/OtsEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip03Timestamp/OtsEvent.kt index 0147ed3dbd..8661fb787e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip03Timestamp/OtsEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip03Timestamp/OtsEvent.kt @@ -30,7 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.events.toETag import com.vitorpamplona.quartz.nip03Timestamp.tags.TargetEventTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils import kotlin.io.encoding.Base64 @@ -60,7 +59,6 @@ class OtsEvent( companion object { const val KIND = 1040 - const val ALT = "Opentimestamps Attestation" /** * Stamp is used to save OTS requests locally while we want for the bitcoin @@ -102,7 +100,6 @@ class OtsEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, encodeOtsState(otsState), createdAt) { - alt(ALT) targetEvent(TargetEventTag(eventId)) initializer() @@ -114,8 +111,6 @@ class OtsEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, encodeOtsState(otsState), createdAt) { - alt(ALT) - targetEvent(event.toETag()) targetKind(event.event.kind) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip04Dm/messages/PrivateDmEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip04Dm/messages/PrivateDmEvent.kt index f3ccce358c..9b774e3c49 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip04Dm/messages/PrivateDmEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip04Dm/messages/PrivateDmEvent.kt @@ -36,7 +36,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.people.pTag import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip92IMeta.IMetaTag import com.vitorpamplona.quartz.utils.Hex import com.vitorpamplona.quartz.utils.TimeUtils @@ -102,7 +101,6 @@ class PrivateDmEvent( companion object { const val KIND = 4 - const val ALT = "Private Message" const val NIP_18_ADVERTISEMENT = "[//]: # (nip18)\n" fun prepareMessageToEncrypt( @@ -139,7 +137,6 @@ class PrivateDmEvent( ), createdAt = createdAt, ) { - alt(ALT) pTag(toUser) replyingTo?.let { reply(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip09Deletions/DeletionEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip09Deletions/DeletionEvent.kt index 2bd3265953..ec2f1de70a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip09Deletions/DeletionEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip09Deletions/DeletionEvent.kt @@ -41,7 +41,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.kinds.kinds import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTagIds -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -77,15 +76,12 @@ class DeletionEvent( companion object { const val KIND = 5 - const val ALT = "Deletion event" fun build( deleteEvents: List, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) - deleteEvents.forEach { eTag(ETag(it.id)) if (it is AddressableEvent) { @@ -104,8 +100,6 @@ class DeletionEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) - deleteEvents.forEach { if (it is AddressableEvent) { aTag(it.address()) @@ -123,8 +117,6 @@ class DeletionEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) - deleteEvents.forEach { pTag(PTag(it.pubKey)) eTag(ETag(it.id)) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip10Notes/TextNoteEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip10Notes/TextNoteEvent.kt index e2ab5a1f94..dd3deb8c2e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip10Notes/TextNoteEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip10Notes/TextNoteEvent.kt @@ -47,10 +47,8 @@ import com.vitorpamplona.quartz.nip19Bech32.eventHints import com.vitorpamplona.quartz.nip19Bech32.eventIds import com.vitorpamplona.quartz.nip19Bech32.pubKeyHints import com.vitorpamplona.quartz.nip19Bech32.pubKeys -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils -import com.vitorpamplona.quartz.utils.takeKeepingSurrogatePairs @Immutable class TextNoteEvent( @@ -124,22 +122,12 @@ class TextNoteEvent( companion object { const val KIND = 1 - const val ALT = "A short note: " - - private fun shortedMessageForAlt(msg: String): String { - if (msg.length < 50) return ALT + msg - // takeKeepingSurrogatePairs avoids leaving a lone surrogate (e.g. half - // of an emoji) in the alt tag, which would be unencodable as UTF-8 and - // corrupt the event id on the wire. - return ALT + msg.takeKeepingSurrogatePairs(50) + "..." - } fun build( note: String, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, note, createdAt) { - alt(shortedMessageForAlt(note)) initializer() } @@ -150,8 +138,6 @@ class TextNoteEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, note, createdAt) { - alt(shortedMessageForAlt(note)) - if (replyingTo != null || forkingFrom != null) { markedETags(prepareETagsAsReplyTo(replyingTo, forkingFrom)) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/auction/AuctionEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/auction/AuctionEvent.kt index 01487fcf5e..7cdce539c5 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/auction/AuctionEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/auction/AuctionEvent.kt @@ -29,7 +29,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.CancellationException @@ -56,7 +55,6 @@ class AuctionEvent( companion object { const val KIND = 30020 - const val ALT_DESCRIPTION = "Marketplace auction" fun build( auction: AuctionData, @@ -65,7 +63,6 @@ class AuctionEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, JsonMapper.toJson(auction), createdAt) { dTag(auction.id) - alt(ALT_DESCRIPTION) categories?.let { hashtags(it) } initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/bid/BidEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/bid/BidEvent.kt index d07f841acc..202a13f1ae 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/bid/BidEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/bid/BidEvent.kt @@ -31,7 +31,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip15Marketplace.auction.AuctionEvent -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -59,7 +58,6 @@ class BidEvent( companion object { const val KIND = 1021 - const val ALT_DESCRIPTION = "Auction bid" fun build( auction: EventHintBundle, @@ -67,7 +65,6 @@ class BidEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, amount.toLong().toString(), createdAt) { - alt(ALT_DESCRIPTION) auction(auction) notifyAuthor(auction) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/bidConfirmation/BidConfirmationEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/bidConfirmation/BidConfirmationEvent.kt index 55bc78d798..bac6333f7c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/bidConfirmation/BidConfirmationEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/bidConfirmation/BidConfirmationEvent.kt @@ -34,7 +34,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip15Marketplace.auction.AuctionEvent import com.vitorpamplona.quartz.nip15Marketplace.bid.BidEvent import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.CancellationException @@ -71,7 +70,6 @@ class BidConfirmationEvent( companion object { const val KIND = 1022 - const val ALT_DESCRIPTION = "Bid confirmation" const val STATUS_ACCEPTED = "accepted" const val STATUS_REJECTED = "rejected" @@ -85,7 +83,6 @@ class BidConfirmationEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, JsonMapper.toJson(confirmation), createdAt) { - alt(ALT_DESCRIPTION) bid(bid) auction(auction) notifyBidder(bid) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/marketplace/MarketplaceEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/marketplace/MarketplaceEvent.kt index 11d31790fd..b6e277c379 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/marketplace/MarketplaceEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/marketplace/MarketplaceEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.CancellationException @@ -55,7 +54,6 @@ class MarketplaceEvent( companion object { const val KIND = 30019 - const val ALT_DESCRIPTION = "Marketplace UI" fun build( marketplace: MarketplaceData, @@ -64,7 +62,6 @@ class MarketplaceEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, JsonMapper.toJson(marketplace), createdAt) { dTag(dTag) - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/product/ProductEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/product/ProductEvent.kt index e2a7dba304..90de4c2e71 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/product/ProductEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/product/ProductEvent.kt @@ -29,7 +29,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.CancellationException @@ -58,7 +57,6 @@ class ProductEvent( companion object { const val KIND = 30018 - const val ALT_DESCRIPTION = "Marketplace product" fun build( product: ProductData, @@ -67,7 +65,6 @@ class ProductEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, JsonMapper.toJson(product), createdAt) { dTag(product.id) - alt(ALT_DESCRIPTION) categories?.let { hashtags(it) } initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/stall/StallEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/stall/StallEvent.kt index c20e61dea8..92998a1583 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/stall/StallEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip15Marketplace/stall/StallEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.CancellationException @@ -55,7 +54,6 @@ class StallEvent( companion object { const val KIND = 30017 - const val ALT_DESCRIPTION = "Marketplace stall" fun build( stall: StallData, @@ -63,7 +61,6 @@ class StallEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, JsonMapper.toJson(stall), createdAt) { dTag(stall.id) - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip17Dm/files/ChatMessageEncryptedFileHeaderEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip17Dm/files/ChatMessageEncryptedFileHeaderEvent.kt index b1742a042d..902016f868 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip17Dm/files/ChatMessageEncryptedFileHeaderEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip17Dm/files/ChatMessageEncryptedFileHeaderEvent.kt @@ -33,7 +33,6 @@ import com.vitorpamplona.quartz.nip17Dm.files.tags.EncryptionKey import com.vitorpamplona.quartz.nip17Dm.files.tags.EncryptionNonce import com.vitorpamplona.quartz.nip17Dm.files.tags.FileTypeTag import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip94FileMetadata.tags.BlurhashTag import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag @@ -78,7 +77,6 @@ class ChatMessageEncryptedFileHeaderEvent( companion object { const val KIND = 15 - const val ALT_DESCRIPTION = "Encrypted file in chat" fun build( to: List, @@ -97,8 +95,6 @@ class ChatMessageEncryptedFileHeaderEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, url, createdAt) { - alt(ALT_DESCRIPTION) - group(to) encryptionAlgo(cipher.name()) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip17Dm/messages/ChatMessageEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip17Dm/messages/ChatMessageEvent.kt index 5ab47f319b..1dbbc919a2 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip17Dm/messages/ChatMessageEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip17Dm/messages/ChatMessageEvent.kt @@ -29,7 +29,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.toPTag import com.vitorpamplona.quartz.nip17Dm.base.BaseDMGroupEvent -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -50,7 +49,6 @@ class ChatMessageEvent( companion object { const val KIND = 14 - const val ALT_DESCRIPTION = "Direct message" fun build( msg: String, @@ -58,7 +56,6 @@ class ChatMessageEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, msg, createdAt) { - alt(ALT_DESCRIPTION) group(to) initializer() } @@ -69,7 +66,6 @@ class ChatMessageEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, msg, createdAt) { - alt(ALT_DESCRIPTION) reply(reply) group((reply.event.recipients() + reply.toPTag()).distinctBy { it.pubKey }) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip17Dm/settings/ChatMessageRelayListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip17Dm/settings/ChatMessageRelayListEvent.kt index bc77c4979e..80ed9a356f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip17Dm/settings/ChatMessageRelayListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip17Dm/settings/ChatMessageRelayListEvent.kt @@ -29,7 +29,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip17Dm.settings.tags.RelayTag -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -55,9 +54,7 @@ class ChatMessageRelayListEvent( fun createTagArray(relays: List): Array> = relays .map { RelayTag.assemble(it) } - .plusElement( - AltTag.assemble("Relay list to receive private messages"), - ).toTypedArray() + .toTypedArray() suspend fun updateRelayList( earlierVersion: ChatMessageRelayListEvent, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip18Reposts/GenericRepostEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip18Reposts/GenericRepostEvent.kt index 59ca0bec29..624ceba069 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip18Reposts/GenericRepostEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip18Reposts/GenericRepostEvent.kt @@ -39,7 +39,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.kinds.KindTag import com.vitorpamplona.quartz.nip01Core.tags.kinds.kind import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.lastNotNullOfOrNull @@ -93,7 +92,6 @@ class GenericRepostEvent( companion object { const val KIND = 16 - const val ALT = "Generic repost" fun build( eventHint: EventHintBundle, @@ -102,8 +100,6 @@ class GenericRepostEvent( ) = eventTemplate(KIND, eventHint.event.toJson(), createdAt) { val boostedPost = eventHint.event - alt(ALT) - kind(boostedPost.kind) pTag(PTag(boostedPost.pubKey, eventHint.authorHomeRelay)) eTag(ETag(boostedPost.id, eventHint.relay, boostedPost.pubKey)) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip18Reposts/RepostEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip18Reposts/RepostEvent.kt index 74e8146502..525b12cec9 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip18Reposts/RepostEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip18Reposts/RepostEvent.kt @@ -39,7 +39,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.kinds.KindTag import com.vitorpamplona.quartz.nip01Core.tags.kinds.kind import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.lastNotNullOfOrNull @@ -93,7 +92,6 @@ class RepostEvent( companion object { const val KIND = 6 - const val ALT = "Repost event" fun build( eventHint: EventHintBundle, @@ -102,8 +100,6 @@ class RepostEvent( ) = eventTemplate(KIND, eventHint.event.toJson(), createdAt) { val boostedPost = eventHint.event - alt(ALT) - pTag(PTag(boostedPost.pubKey, eventHint.authorHomeRelay)) eTag(ETag(boostedPost.id, eventHint.relay, boostedPost.pubKey)) if (boostedPost is AddressableEvent) { diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip22Comments/CommentEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip22Comments/CommentEvent.kt index 8bd085449d..07761c3b98 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip22Comments/CommentEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip22Comments/CommentEvent.kt @@ -44,7 +44,6 @@ import com.vitorpamplona.quartz.nip19Bech32.eventHints import com.vitorpamplona.quartz.nip19Bech32.eventIds import com.vitorpamplona.quartz.nip19Bech32.pubKeyHints import com.vitorpamplona.quartz.nip19Bech32.pubKeys -import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri import com.vitorpamplona.quartz.nip22Comments.tags.ReplyAddressTag import com.vitorpamplona.quartz.nip22Comments.tags.ReplyAuthorTag import com.vitorpamplona.quartz.nip22Comments.tags.ReplyEventTag @@ -55,7 +54,6 @@ import com.vitorpamplona.quartz.nip22Comments.tags.RootAuthorTag import com.vitorpamplona.quartz.nip22Comments.tags.RootEventTag import com.vitorpamplona.quartz.nip22Comments.tags.RootIdentifierTag import com.vitorpamplona.quartz.nip22Comments.tags.RootKindTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent import com.vitorpamplona.quartz.nip73ExternalIds.ExternalId @@ -240,7 +238,6 @@ class CommentEvent( companion object { const val KIND = 1111 - const val ALT = "Reply to " fun replyBuilder( msg: String, @@ -248,8 +245,6 @@ class CommentEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, msg, createdAt) { - alt(ALT + replyingTo.toNostrUri()) - if (replyingTo.event is CommentEvent) { addAll(replyingTo.event.rootScopes()) addAll(replyingTo.event.rootKinds()) @@ -278,8 +273,6 @@ class CommentEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, msg, createdAt) { - alt(ALT + extId.toScope()) - if (extId is GeohashId) { GeoHashTag.geoMipMap(extId.geohash).forEach { rootExternalIdentity(GeohashId(it, extId.hint)) } } else { diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt index 43d8c4c13c..93f4826b9f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip23LongContent/LongTextNoteEvent.kt @@ -49,7 +49,6 @@ import com.vitorpamplona.quartz.nip23LongContent.tags.ImageTag import com.vitorpamplona.quartz.nip23LongContent.tags.PublishedAtTag import com.vitorpamplona.quartz.nip23LongContent.tags.SummaryTag import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils import kotlin.uuid.ExperimentalUuidApi @@ -157,7 +156,6 @@ class LongTextNoteEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description, createdAt) { dTag(dTag) - alt("Blog post: $title") title(title) summary?.let { summary(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelCreateEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelCreateEvent.kt index be1db07883..ed61fa5d9e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelCreateEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelCreateEvent.kt @@ -31,7 +31,6 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip28PublicChat.base.ChannelData import com.vitorpamplona.quartz.nip28PublicChat.base.ChannelDataNorm -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils @@ -97,7 +96,6 @@ class ChannelCreateEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, data.toContent(), createdAt) { - alt("Public chat creation event ${data.name?.let { "about $it" }}") initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelHideMessageEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelHideMessageEvent.kt index b62fc271c9..3c261b869f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelHideMessageEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelHideMessageEvent.kt @@ -31,7 +31,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.events.eTags import com.vitorpamplona.quartz.nip01Core.tags.events.taggedEventIds import com.vitorpamplona.quartz.nip28PublicChat.base.BasePublicChatEvent import com.vitorpamplona.quartz.nip28PublicChat.base.channel -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -52,7 +51,6 @@ class ChannelHideMessageEvent( companion object { const val KIND = 43 - const val ALT = "Hide message instruction for public chats" fun build( reason: String, @@ -61,7 +59,6 @@ class ChannelHideMessageEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, reason, createdAt) { - alt(ALT) channel(channel) eTags(messagesToHide) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelMetadataEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelMetadataEvent.kt index 6395940cf2..59725804aa 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelMetadataEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelMetadataEvent.kt @@ -34,7 +34,6 @@ import com.vitorpamplona.quartz.nip28PublicChat.base.BasePublicChatEvent import com.vitorpamplona.quartz.nip28PublicChat.base.ChannelData import com.vitorpamplona.quartz.nip28PublicChat.base.ChannelDataNorm import com.vitorpamplona.quartz.nip28PublicChat.base.channel -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils @@ -116,7 +115,6 @@ class ChannelMetadataEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, data.toContent(), createdAt) { - alt("Public chat update to ${data.name}") channel(channel) initializer() } @@ -127,7 +125,6 @@ class ChannelMetadataEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, data.toContent(), createdAt) { - alt("Public chat update to ${data.name}") channel(channel) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelMuteUserEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelMuteUserEvent.kt index 51df858239..8d197750c8 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelMuteUserEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/admin/ChannelMuteUserEvent.kt @@ -31,7 +31,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.people.pTags import com.vitorpamplona.quartz.nip01Core.tags.people.taggedUserIds import com.vitorpamplona.quartz.nip28PublicChat.base.BasePublicChatEvent import com.vitorpamplona.quartz.nip28PublicChat.base.channel -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -52,7 +51,6 @@ class ChannelMuteUserEvent( companion object { const val KIND = 44 - const val ALT = "Mute user instruction for public chats" fun build( reason: String, @@ -61,7 +59,6 @@ class ChannelMuteUserEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, reason, createdAt) { - alt(ALT) channel(channel) pTags(usersToMute) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/list/ChannelListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/list/ChannelListEvent.kt index a0576e5804..5f97ccde41 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/list/ChannelListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip28PublicChat/list/ChannelListEvent.kt @@ -25,15 +25,12 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip28PublicChat.list.tags.ChannelTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.encryption.signNip51List @@ -57,7 +54,6 @@ class ChannelListEvent( companion object { const val KIND = 10005 - const val ALT = "Public Chat List" const val FIXED_D_TAG = "" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, FIXED_D_TAG) @@ -166,16 +162,7 @@ class ChannelListEvent( tags: TagArray, signer: NostrSigner, createdAt: Long = TimeUtils.now(), - ): ChannelListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } - - return signer.sign(createdAt, KIND, newTags, content) - } + ): ChannelListEvent = signer.sign(createdAt, KIND, tags, content) suspend fun create( publicChannels: List = emptyList(), @@ -194,7 +181,7 @@ class ChannelListEvent( createdAt: Long = TimeUtils.now(), ): ChannelListEvent { val privateTagArray = privateChannels.map { it.toTagArray() }.toTypedArray() - val publicTagArray = publicChannels.map { it.toTagArray() }.toTypedArray() + AltTag.assemble(ALT) + val publicTagArray = publicChannels.map { it.toTagArray() }.toTypedArray() return signer.signNip51List(createdAt, KIND, publicTagArray, privateTagArray) } @@ -209,7 +196,6 @@ class ChannelListEvent( description = PrivateTagsInContent.encryptNip44(privateChannels.map { it.toTagArray() }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) channels(publicChannels) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/GroupAdminsEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/GroupAdminsEvent.kt index af68af2f4f..c58b4d44e8 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/GroupAdminsEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/GroupAdminsEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip29RelayGroups.tags.GroupAdminTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -45,7 +44,6 @@ class GroupAdminsEvent( companion object { const val KIND = 39001 - const val ALT_DESCRIPTION = "Group admins" fun build( groupId: String, @@ -53,7 +51,6 @@ class GroupAdminsEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) dTag(groupId) addAll(GroupAdminTag.assemble(admins)) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/GroupMembersEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/GroupMembersEvent.kt index 56e6e3cb7b..243f008cec 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/GroupMembersEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/GroupMembersEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -45,7 +44,6 @@ class GroupMembersEvent( companion object { const val KIND = 39002 - const val ALT_DESCRIPTION = "Group members" fun build( groupId: String, @@ -53,7 +51,6 @@ class GroupMembersEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) dTag(groupId) memberPubKeys.forEach { add(arrayOf("p", it)) } initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/GroupMetadataEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/GroupMetadataEvent.kt index 1f5223a232..b15718f7c6 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/GroupMetadataEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/GroupMetadataEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.core.firstTagValue import com.vitorpamplona.quartz.nip01Core.core.hasTagWithContent import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -81,7 +80,6 @@ class GroupMetadataEvent( companion object { const val KIND = 39000 - const val ALT_DESCRIPTION = "Group metadata" fun build( groupId: String, @@ -92,7 +90,6 @@ class GroupMetadataEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) dTag(groupId) name?.let { add(arrayOf("name", it)) } about?.let { add(arrayOf("about", it)) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/SupportedRolesEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/SupportedRolesEvent.kt index 9dbf7eacb4..5efe39736b 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/SupportedRolesEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/metadata/SupportedRolesEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip29RelayGroups.tags.RoleTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -45,7 +44,6 @@ class SupportedRolesEvent( companion object { const val KIND = 39003 - const val ALT_DESCRIPTION = "Group supported roles" fun build( groupId: String, @@ -53,7 +51,6 @@ class SupportedRolesEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) dTag(groupId) addAll(RoleTag.assemble(roles)) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/CreateGroupEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/CreateGroupEvent.kt index 0554e2c4ca..0dbed7662e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/CreateGroupEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/CreateGroupEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -41,14 +40,12 @@ class CreateGroupEvent( companion object { const val KIND = 9007 - const val ALT_DESCRIPTION = "Group create" fun build( groupId: String, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) groupId(groupId) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/CreateInviteEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/CreateInviteEvent.kt index 44861e1acf..6b5ce7f322 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/CreateInviteEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/CreateInviteEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -43,7 +42,6 @@ class CreateInviteEvent( companion object { const val KIND = 9009 - const val ALT_DESCRIPTION = "Group create invite" fun build( groupId: String, @@ -51,7 +49,6 @@ class CreateInviteEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) groupId(groupId) inviteCode(code) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/DeleteEventEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/DeleteEventEvent.kt index 91674eb624..25ebd16183 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/DeleteEventEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/DeleteEventEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -45,7 +44,6 @@ class DeleteEventEvent( companion object { const val KIND = 9005 - const val ALT_DESCRIPTION = "Group delete event" fun build( groupId: String, @@ -54,7 +52,6 @@ class DeleteEventEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) groupId(groupId) eventIds.forEach { add(arrayOf("e", it)) } previous(previousEvents) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/DeleteGroupEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/DeleteGroupEvent.kt index 6f71cfdbbf..fb1bc7df0c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/DeleteGroupEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/DeleteGroupEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -41,14 +40,12 @@ class DeleteGroupEvent( companion object { const val KIND = 9008 - const val ALT_DESCRIPTION = "Group delete" fun build( groupId: String, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) groupId(groupId) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/EditMetadataEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/EditMetadataEvent.kt index f05b72d963..500c82e776 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/EditMetadataEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/EditMetadataEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip29RelayGroups.metadata.GroupMetadataEvent -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -44,7 +43,6 @@ class EditMetadataEvent( companion object { const val KIND = 9002 - const val ALT_DESCRIPTION = "Group edit metadata" fun build( groupId: String, @@ -56,7 +54,6 @@ class EditMetadataEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) groupId(groupId) name?.let { add(arrayOf("name", it)) } about?.let { add(arrayOf("about", it)) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/PutUserEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/PutUserEvent.kt index 0fbf979181..b6b9e48b9f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/PutUserEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/PutUserEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -45,7 +44,6 @@ class PutUserEvent( companion object { const val KIND = 9000 - const val ALT_DESCRIPTION = "Group add user" fun build( groupId: String, @@ -54,7 +52,6 @@ class PutUserEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) groupId(groupId) pubKeysWithRoles.forEach { (pubKey, roles) -> userPubKeyWithRoles(pubKey, roles) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/RemoveUserEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/RemoveUserEvent.kt index 162e63252d..09d7ea35fb 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/RemoveUserEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/moderation/RemoveUserEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -45,7 +44,6 @@ class RemoveUserEvent( companion object { const val KIND = 9001 - const val ALT_DESCRIPTION = "Group remove user" fun build( groupId: String, @@ -54,7 +52,6 @@ class RemoveUserEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) groupId(groupId) pubKeys.forEach { userPubKey(it) } previous(previousEvents) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/request/JoinRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/request/JoinRequestEvent.kt index c75f3021b7..2db9b25108 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/request/JoinRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/request/JoinRequestEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip29RelayGroups.moderation.groupId import com.vitorpamplona.quartz.nip29RelayGroups.moderation.inviteCode -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -45,7 +44,6 @@ class JoinRequestEvent( companion object { const val KIND = 9021 - const val ALT_DESCRIPTION = "Group join request" fun build( groupId: String, @@ -54,7 +52,6 @@ class JoinRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, reason, createdAt) { - alt(ALT_DESCRIPTION) groupId(groupId) inviteCode?.let { inviteCode(it) } initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/request/LeaveRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/request/LeaveRequestEvent.kt index 74999557d1..429750cc61 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/request/LeaveRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip29RelayGroups/request/LeaveRequestEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip29RelayGroups.moderation.groupId -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,7 +41,6 @@ class LeaveRequestEvent( companion object { const val KIND = 9022 - const val ALT_DESCRIPTION = "Group leave request" fun build( groupId: String, @@ -50,7 +48,6 @@ class LeaveRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, reason, createdAt) { - alt(ALT_DESCRIPTION) groupId(groupId) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip30CustomEmoji/pack/EmojiPackEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip30CustomEmoji/pack/EmojiPackEvent.kt index 46f9507929..92fd6e5bb1 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip30CustomEmoji/pack/EmojiPackEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip30CustomEmoji/pack/EmojiPackEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrlTag import com.vitorpamplona.quartz.nip30CustomEmoji.emojis -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.tags.DescriptionTag @@ -84,7 +83,6 @@ class EmojiPackEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) dTag(dTag) title(name) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip30CustomEmoji/selection/EmojiPackSelectionEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip30CustomEmoji/selection/EmojiPackSelectionEvent.kt index a2174bf871..774f834730 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip30CustomEmoji/selection/EmojiPackSelectionEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip30CustomEmoji/selection/EmojiPackSelectionEvent.kt @@ -32,7 +32,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventUpdate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.aTag.toATag import com.vitorpamplona.quartz.nip30CustomEmoji.pack.EmojiPackEvent -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -55,7 +54,6 @@ class EmojiPackSelectionEvent( companion object { const val KIND = 10030 - const val ALT_DESCRIPTION = "Emoji selection" const val FIXED_D_TAG = "" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, FIXED_D_TAG) @@ -87,7 +85,6 @@ class EmojiPackSelectionEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) packs(listOfEmojiPacks.map { it.toATag() }) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip31Alts/TagArrayBuilderExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip31Alts/TagArrayBuilderExt.kt index f53e5f41e8..10287e42bc 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip31Alts/TagArrayBuilderExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip31Alts/TagArrayBuilderExt.kt @@ -23,4 +23,11 @@ package com.vitorpamplona.quartz.nip31Alts import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder +/** + * Writes an `alt` tag. The generic NIP-31 "alt" client-hint is deprecated, so do + * NOT use this to add a boilerplate description of the event kind. It remains only + * for file-metadata events (e.g. NIP-94 kind 1063, NIP-17 encrypted file headers) + * where the `alt` tag is the accessibility description of the file itself, and only + * when the user actually provided one. + */ fun TagArrayBuilder.alt(altDescriptor: String) = addUnique(AltTag.assemble(altDescriptor)) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip32Labeling/LabelEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip32Labeling/LabelEvent.kt index 974bfec5a0..8ca3bd4f92 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip32Labeling/LabelEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip32Labeling/LabelEvent.kt @@ -39,7 +39,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.events.toETag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.HashtagTag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip32Labeling.tags.LabelNamespaceTag import com.vitorpamplona.quartz.nip32Labeling.tags.LabelTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -114,7 +113,6 @@ class LabelEvent( companion object { const val KIND = 1985 - const val ALT = "Label event" /** * NIP-32 tag-association namespace for hashtags. A label of the form @@ -133,7 +131,6 @@ class LabelEvent( hashtag: String, createdAt: Long = TimeUtils.now(), ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) eTag(labeledEvent.toETag()) val tag = LabelTag(hashtag.removePrefix("#").lowercase(), HASHTAG_NAMESPACE) labelNamespace(tag.namespace) @@ -151,7 +148,6 @@ class LabelEvent( content: String = "", createdAt: Long = TimeUtils.now(), ) = eventTemplate(KIND, content, createdAt) { - alt(ALT) eTag(ETag(labeledEventId, labeledEventRelay?.let { RelayUrlNormalizer.normalizeOrNull(it) }, labeledEventAuthor)) labels.map { it.namespace }.distinct().forEach { labelNamespace(it) } labels.forEach { label(it) } @@ -167,7 +163,6 @@ class LabelEvent( content: String = "", createdAt: Long = TimeUtils.now(), ) = eventTemplate(KIND, content, createdAt) { - alt(ALT) pTag(labeledPubKey, labeledPubKeyRelay?.let { RelayUrlNormalizer.normalizeOrNull(it) }) labels.map { it.namespace }.distinct().forEach { labelNamespace(it) } labels.forEach { label(it) } @@ -181,7 +176,6 @@ class LabelEvent( content: String = "", createdAt: Long = TimeUtils.now(), ) = eventTemplate(KIND, content, createdAt) { - alt(ALT) labels.map { it.namespace }.distinct().forEach { labelNamespace(it) } labels.forEach { label(it) } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/grasp/UserGraspListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/grasp/UserGraspListEvent.kt index 11ebd05b03..4ab519fa3b 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/grasp/UserGraspListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/grasp/UserGraspListEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip34Git.grasp.tags.GraspTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -55,7 +54,6 @@ class UserGraspListEvent( companion object { const val KIND = 10317 - const val ALT = "Preferred grasp servers for Git over Nostr" fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) @@ -64,7 +62,6 @@ class UserGraspListEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) grasps.forEach { add(GraspTag.assemble(it)) } initializer() } @@ -74,7 +71,6 @@ class UserGraspListEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) grasps.forEach { add(GraspTag.assemble(it)) } initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/issue/GitIssueEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/issue/GitIssueEvent.kt index 900a195233..8a693019dc 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/issue/GitIssueEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/issue/GitIssueEvent.kt @@ -43,7 +43,6 @@ import com.vitorpamplona.quartz.nip19Bech32.eventHints import com.vitorpamplona.quartz.nip19Bech32.eventIds import com.vitorpamplona.quartz.nip19Bech32.pubKeyHints import com.vitorpamplona.quartz.nip19Bech32.pubKeys -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip34Git.repository.GitRepositoryEvent import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -119,7 +118,6 @@ class GitIssueEvent( companion object { const val KIND = 1621 - const val ALT_DESCRIPTION = "A Git Issue" fun build( subject: String, @@ -130,7 +128,6 @@ class GitIssueEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, content, createdAt) { - alt(ALT_DESCRIPTION) subject(subject) repository(repository) notify(notify) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/patch/GitPatchEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/patch/GitPatchEvent.kt index 9547446908..fe22921a31 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/patch/GitPatchEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/patch/GitPatchEvent.kt @@ -37,7 +37,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTags import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip34Git.patch.tags.CommitPgpSigTag import com.vitorpamplona.quartz.nip34Git.patch.tags.CommitTag import com.vitorpamplona.quartz.nip34Git.patch.tags.Committer @@ -118,7 +117,6 @@ class GitPatchEvent( companion object { const val KIND = 1617 - const val ALT = "A Git Patch" const val ROOT = "root" const val ROOT_REVISION = "root-revision" @@ -150,7 +148,6 @@ class GitPatchEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, patch, createdAt) { - alt(ALT) repository(repository) euc(earliestUniqueCommit) pTag(repository.event.pubKey, repository.authorHomeRelay) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/pr/GitPullRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/pr/GitPullRequestEvent.kt index 16cc045e87..c9d67b6398 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/pr/GitPullRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/pr/GitPullRequestEvent.kt @@ -36,7 +36,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTags import com.vitorpamplona.quartz.nip14Subject.SubjectTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip34Git.pr.tags.BranchNameTag import com.vitorpamplona.quartz.nip34Git.pr.tags.CurrentCommitTag import com.vitorpamplona.quartz.nip34Git.pr.tags.MergeBaseTag @@ -103,7 +102,6 @@ class GitPullRequestEvent( companion object { const val KIND = 1618 - const val ALT = "A Git Pull Request" /** * Build a NIP-34 kind-1618 pull request event. @@ -135,7 +133,6 @@ class GitPullRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description, createdAt) { - alt(ALT) repository(repository) euc(earliestUniqueCommit) pTag(repository.event.pubKey, repository.authorHomeRelay) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/pr/GitPullRequestUpdateEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/pr/GitPullRequestUpdateEvent.kt index 81d2e19270..898187ae25 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/pr/GitPullRequestUpdateEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/pr/GitPullRequestUpdateEvent.kt @@ -35,7 +35,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.people.pTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTags import com.vitorpamplona.quartz.nip22Comments.tags.RootAuthorTag import com.vitorpamplona.quartz.nip22Comments.tags.RootEventTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip34Git.pr.tags.CurrentCommitTag import com.vitorpamplona.quartz.nip34Git.pr.tags.MergeBaseTag import com.vitorpamplona.quartz.nip34Git.repository.GitRepositoryEvent @@ -90,7 +89,6 @@ class GitPullRequestUpdateEvent( companion object { const val KIND = 1619 - const val ALT = "A Git Pull Request Update" /** * Build a NIP-34 kind-1619 pull-request update event. @@ -114,7 +112,6 @@ class GitPullRequestUpdateEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) parentPullRequest(parentPullRequest) parentPullRequestAuthor(parentPullRequest) repository(repository) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/repository/GitRepositoryEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/repository/GitRepositoryEvent.kt index 3cce25f932..cf3451008a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/repository/GitRepositoryEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/repository/GitRepositoryEvent.kt @@ -29,7 +29,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.HashtagTag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip34Git.repository.tags.CloneTag import com.vitorpamplona.quartz.nip34Git.repository.tags.DescriptionTag import com.vitorpamplona.quartz.nip34Git.repository.tags.EucTag @@ -94,7 +93,6 @@ class GitRepositoryEvent( companion object { const val KIND = 30617 - const val ALT_DESCRIPTION = "Git Repository" const val PERSONAL_FORK = "personal-fork" @OptIn(ExperimentalUuidApi::class) @@ -107,7 +105,6 @@ class GitRepositoryEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) dTag(dTag) name(name) description?.let { description(it) } @@ -131,7 +128,6 @@ class GitRepositoryEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) dTag(dTag) name(name) description?.let { description(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/state/GitRepositoryStateEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/state/GitRepositoryStateEvent.kt index 2c0f66f971..dd1c7a11b5 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/state/GitRepositoryStateEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/state/GitRepositoryStateEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip34Git.state.tags.HeadTag import com.vitorpamplona.quartz.nip34Git.state.tags.RefTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -61,7 +60,6 @@ class GitRepositoryStateEvent( companion object { const val KIND = 30618 - const val ALT_DESCRIPTION = "Git Repository State" fun build( dTag: String, @@ -70,7 +68,6 @@ class GitRepositoryStateEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) dTag(dTag) refs.forEach { ref(it) } head?.let { head(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusAppliedEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusAppliedEvent.kt index 32501ed204..7273666b3e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusAppliedEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusAppliedEvent.kt @@ -60,7 +60,6 @@ class GitStatusAppliedEvent( companion object { const val KIND = KIND_APPLIED - const val ALT = "A Git Applied Status" fun build( content: String, @@ -73,7 +72,6 @@ class GitStatusAppliedEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = GitStatusBuilders.buildStatus( kind = KIND, - altDescriptor = ALT, content = content, target = target, notify = notify, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusBuilders.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusBuilders.kt index b50a254449..7d16e3087d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusBuilders.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusBuilders.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTags import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils /** @@ -40,14 +39,12 @@ import com.vitorpamplona.quartz.utils.TimeUtils object GitStatusBuilders { fun buildStatus( kind: Int, - altDescriptor: String, content: String, target: EventHintBundle, notify: List = emptyList(), createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(kind, content, createdAt) { - alt(altDescriptor) add( MarkedETag.assemble( target.event.id, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusClosedEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusClosedEvent.kt index d2b15c35db..5a9f4baaf7 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusClosedEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusClosedEvent.kt @@ -39,7 +39,6 @@ class GitStatusClosedEvent( ) : GitStatusEvent(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = KIND_CLOSED - const val ALT = "A Git Closed Status" fun build( content: String, @@ -49,7 +48,6 @@ class GitStatusClosedEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = GitStatusBuilders.buildStatus( kind = KIND, - altDescriptor = ALT, content = content, target = target, notify = notify, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusDraftEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusDraftEvent.kt index 627f442f33..2f4fa4295b 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusDraftEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusDraftEvent.kt @@ -39,7 +39,6 @@ class GitStatusDraftEvent( ) : GitStatusEvent(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = KIND_DRAFT - const val ALT = "A Git Draft Status" fun build( content: String, @@ -49,7 +48,6 @@ class GitStatusDraftEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = GitStatusBuilders.buildStatus( kind = KIND, - altDescriptor = ALT, content = content, target = target, notify = notify, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusOpenEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusOpenEvent.kt index 67b2afe71e..649f9af5ec 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusOpenEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip34Git/status/GitStatusOpenEvent.kt @@ -39,7 +39,6 @@ class GitStatusOpenEvent( ) : GitStatusEvent(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = KIND_OPEN - const val ALT = "A Git Open Status" fun build( content: String, @@ -49,7 +48,6 @@ class GitStatusOpenEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = GitStatusBuilders.buildStatus( kind = KIND, - altDescriptor = ALT, content = content, target = target, notify = notify, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip35Torrents/TorrentCommentEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip35Torrents/TorrentCommentEvent.kt index 699e64911d..e381d01d0d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip35Torrents/TorrentCommentEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip35Torrents/TorrentCommentEvent.kt @@ -47,7 +47,6 @@ import com.vitorpamplona.quartz.nip19Bech32.eventHints import com.vitorpamplona.quartz.nip19Bech32.eventIds import com.vitorpamplona.quartz.nip19Bech32.pubKeyHints import com.vitorpamplona.quartz.nip19Bech32.pubKeys -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -118,7 +117,6 @@ class TorrentCommentEvent( @Suppress("DEPRECATION") companion object { const val KIND = 2004 - const val ALT_DESCRIPTION = "Comment for a Torrent file" fun build( message: String, @@ -152,7 +150,6 @@ class TorrentCommentEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, post, createdAt) { - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip35Torrents/TorrentEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip35Torrents/TorrentEvent.kt index 4648feaa5d..8475c527e2 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip35Torrents/TorrentEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip35Torrents/TorrentEvent.kt @@ -32,7 +32,6 @@ import com.vitorpamplona.quartz.nip10Notes.content.findNostrUris import com.vitorpamplona.quartz.nip10Notes.content.findURLs import com.vitorpamplona.quartz.nip18Reposts.quotes.quotes import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip35Torrents.tags.BtihTag import com.vitorpamplona.quartz.nip35Torrents.tags.FileTag import com.vitorpamplona.quartz.nip35Torrents.tags.InfoHashTag @@ -98,7 +97,6 @@ class TorrentEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description ?: "", createdAt) { - alt(ALT_DESCRIPTION) initializer() } @@ -109,11 +107,9 @@ class TorrentEvent( description: String? = null, x: String? = null, trackers: List? = null, - alt: String? = null, contentWarningReason: String? = null, createdAt: Long = TimeUtils.now(), ) = eventTemplate(KIND, description ?: "", createdAt) { - alt(alt ?: ALT_DESCRIPTION) title(title) btih(btih) files(files) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip37Drafts/DraftWrapEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip37Drafts/DraftWrapEvent.kt index 31d818e45a..b5d4954865 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip37Drafts/DraftWrapEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip37Drafts/DraftWrapEvent.kt @@ -31,7 +31,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.kinds.kind -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip40Expiration.expiration import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils @@ -67,7 +66,6 @@ class DraftWrapEvent( companion object { const val KIND = 31234 - const val ALT_DESCRIPTION = "Draft Event" fun createAddress( pubKey: HexKey, @@ -90,7 +88,6 @@ class DraftWrapEvent( description = signer.nip44Encrypt(draft.toJson(), signer.pubKey), createdAt = createdAt, ) { - alt(ALT_DESCRIPTION) dTag(dTag) kind(draft.kind) expiration(TimeUtils.ninetyDaysFromNow()) @@ -111,7 +108,6 @@ class DraftWrapEvent( description = "", createdAt = createdAt, ) { - alt(ALT_DESCRIPTION) expiration(TimeUtils.oneMinuteFromNow()) dTag(dTag) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip37Drafts/privateOutbox/PrivateOutboxRelayListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip37Drafts/privateOutbox/PrivateOutboxRelayListEvent.kt index da1f158441..ef1d066acf 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip37Drafts/privateOutbox/PrivateOutboxRelayListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip37Drafts/privateOutbox/PrivateOutboxRelayListEvent.kt @@ -30,8 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.encryption.signNip51List @@ -59,9 +57,6 @@ class PrivateOutboxRelayListEvent( const val KIND = 10013 const val FIXED_D_TAG = "" - val ALT = "Relay list to store private content from this author" - val TAGS = arrayOf(AltTag.assemble(ALT)) - fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) fun createAddressATag(pubKey: HexKey): ATag = ATag(KIND, pubKey, FIXED_D_TAG, null) @@ -89,7 +84,7 @@ class PrivateOutboxRelayListEvent( createdAt: Long = TimeUtils.now(), ): PrivateOutboxRelayListEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, TAGS, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } suspend fun create( @@ -98,7 +93,7 @@ class PrivateOutboxRelayListEvent( createdAt: Long = TimeUtils.now(), ): PrivateOutboxRelayListEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, TAGS, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } suspend fun build( @@ -112,7 +107,6 @@ class PrivateOutboxRelayListEvent( description = PrivateTagsInContent.encryptNip44(privateRelays.map { RelayTag.assemble(it) }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) privateRelays(publicRelays) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip39ExtIdentities/ExternalIdentitiesEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip39ExtIdentities/ExternalIdentitiesEvent.kt index fb3fc40a7b..d191cb17c3 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip39ExtIdentities/ExternalIdentitiesEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip39ExtIdentities/ExternalIdentitiesEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.core.builder import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,7 +41,6 @@ class ExternalIdentitiesEvent( ) : BaseReplaceableEvent(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 10011 - const val ALT_DESCRIPTION = "External Identities" const val FIXED_D_TAG = "" fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) @@ -57,7 +55,6 @@ class ExternalIdentitiesEvent( initializer: TagArrayBuilder.() -> Unit = {}, ): EventTemplate = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) twitter?.let { twitterClaim(it) } mastodon?.let { mastodonClaim(it) } github?.let { githubClaim(it) } @@ -74,7 +71,6 @@ class ExternalIdentitiesEvent( ): EventTemplate { val tags = latest.tags.builder { - alt(ALT_DESCRIPTION) val newClaims = latest.replaceClaims(twitter, mastodon, github) remove(IdentityClaimTag.TAG_NAME) claims(newClaims) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/addMember/RelayAddMemberEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/addMember/RelayAddMemberEvent.kt index 8c387a6a9f..2acd2de6da 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/addMember/RelayAddMemberEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/addMember/RelayAddMemberEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.people.PTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip70ProtectedEvts.protect import com.vitorpamplona.quartz.utils.TimeUtils @@ -43,14 +42,12 @@ class RelayAddMemberEvent( companion object { const val KIND = 8000 - const val ALT_DESCRIPTION = "Relay member added" fun build( memberPubKeys: List, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) protect() memberPubKeys.forEach { add(PTag.assemble(it, null)) } initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/inviteRequest/RelayInviteRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/inviteRequest/RelayInviteRequestEvent.kt index e5ad571670..fde64991fd 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/inviteRequest/RelayInviteRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/inviteRequest/RelayInviteRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -39,13 +38,11 @@ class RelayInviteRequestEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 28935 - const val ALT_DESCRIPTION = "Relay invite request" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/joinRequest/RelayJoinRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/joinRequest/RelayJoinRequestEvent.kt index 57c8667d28..3c64941867 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/joinRequest/RelayJoinRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/joinRequest/RelayJoinRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -41,14 +40,12 @@ class RelayJoinRequestEvent( companion object { const val KIND = 28934 - const val ALT_DESCRIPTION = "Relay join request" fun build( claim: String? = null, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) claim?.let { claim(it) } initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/leaveRequest/RelayLeaveRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/leaveRequest/RelayLeaveRequestEvent.kt index 07824cbb31..e28d410a7d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/leaveRequest/RelayLeaveRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/leaveRequest/RelayLeaveRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip70ProtectedEvts.protect import com.vitorpamplona.quartz.utils.TimeUtils @@ -40,13 +39,11 @@ class RelayLeaveRequestEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 28936 - const val ALT_DESCRIPTION = "Relay leave request" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) protect() initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/list/RelayMembershipListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/list/RelayMembershipListEvent.kt index 0b22cd6758..9993cb05b7 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/list/RelayMembershipListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/list/RelayMembershipListEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip70ProtectedEvts.protect import com.vitorpamplona.quartz.utils.TimeUtils @@ -42,14 +41,12 @@ class RelayMembershipListEvent( companion object { const val KIND = 13534 - const val ALT_DESCRIPTION = "Relay membership list" fun build( members: List, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) protect() members(members) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/removeMember/RelayRemoveMemberEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/removeMember/RelayRemoveMemberEvent.kt index 83b82c41c6..91f4ce7530 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/removeMember/RelayRemoveMemberEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip43RelayMembers/removeMember/RelayRemoveMemberEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.people.PTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip70ProtectedEvts.protect import com.vitorpamplona.quartz.utils.TimeUtils @@ -43,14 +42,12 @@ class RelayRemoveMemberEvent( companion object { const val KIND = 8001 - const val ALT_DESCRIPTION = "Relay member removed" fun build( memberPubKeys: List, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) protect() memberPubKeys.forEach { add(PTag.assemble(it, null)) } initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/LnZapPaymentRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/LnZapPaymentRequestEvent.kt index d98476399c..e9de87634e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/LnZapPaymentRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/LnZapPaymentRequestEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip47WalletConnect.rpc.PayInvoiceMethod import com.vitorpamplona.quartz.nip47WalletConnect.rpc.Request import com.vitorpamplona.quartz.utils.TimeUtils @@ -58,7 +57,6 @@ class LnZapPaymentRequestEvent( companion object { const val KIND = 23194 - const val ALT = "NWC request" suspend fun create( lnInvoice: String, @@ -84,9 +82,9 @@ class LnZapPaymentRequestEvent( val tags = if (useNip44) { - arrayOf(arrayOf("p", walletServicePubkey), AltTag.assemble(ALT), arrayOf("encryption", "nip44_v2")) + arrayOf(arrayOf("p", walletServicePubkey), arrayOf("encryption", "nip44_v2")) } else { - arrayOf(arrayOf("p", walletServicePubkey), AltTag.assemble(ALT)) + arrayOf(arrayOf("p", walletServicePubkey)) } val encrypted = diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/LnZapPaymentResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/LnZapPaymentResponseEvent.kt index ebabe68a79..88b6519e95 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/LnZapPaymentResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/LnZapPaymentResponseEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip47WalletConnect.rpc.Response import com.vitorpamplona.quartz.utils.TimeUtils @@ -58,7 +57,6 @@ class LnZapPaymentResponseEvent( companion object { const val KIND = 23195 - const val ALT = "NWC response" /** * Creates an NWC response event (server-side). @@ -84,7 +82,6 @@ class LnZapPaymentResponseEvent( arrayOf( arrayOf("p", clientPubkey), arrayOf("e", requestEvent.id), - AltTag.assemble(ALT), ) val encrypted = diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/NwcInfoEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/NwcInfoEvent.kt index 3691d3dc10..8c48c2e6e4 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/NwcInfoEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/NwcInfoEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip47WalletConnect.tags.EncryptionTag import com.vitorpamplona.quartz.nip47WalletConnect.tags.NotificationsTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -51,7 +50,6 @@ class NwcInfoEvent( companion object { const val KIND = 13194 - const val ALT_DESCRIPTION = "Wallet service info" fun build( capabilities: List, @@ -60,7 +58,6 @@ class NwcInfoEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, capabilities.joinToString(" "), createdAt) { - alt(ALT_DESCRIPTION) encryptionSchemes?.let { addUnique(EncryptionTag.assemble(it)) } notificationTypes?.let { addUnique(NotificationsTag.assemble(it)) } initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/NwcNotificationEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/NwcNotificationEvent.kt index 825b4c8942..e734941faa 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/NwcNotificationEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip47WalletConnect/events/NwcNotificationEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip47WalletConnect.rpc.Notification import com.vitorpamplona.quartz.utils.TimeUtils @@ -56,7 +55,6 @@ class NwcNotificationEvent( companion object { const val KIND = 23197 const val LEGACY_KIND = 23196 - const val ALT = "Wallet notification" /** * Creates an NWC notification event (server-side). @@ -78,7 +76,6 @@ class NwcNotificationEvent( val tags = arrayOf( arrayOf("p", clientPubkey), - AltTag.assemble(ALT), ) val encrypted = signer.nip44Encrypt(serialized, clientPubkey) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip50Search/SearchRelayListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip50Search/SearchRelayListEvent.kt index 3e36f2063f..dc23dc6e23 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip50Search/SearchRelayListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip50Search/SearchRelayListEvent.kt @@ -30,8 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.encryption.signNip51List @@ -58,8 +56,6 @@ class SearchRelayListEvent( companion object { const val KIND = 10007 - val ALT = "Relay list to use for Search" - val ALT_TAG = arrayOf(AltTag.assemble(ALT)) fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey) @@ -87,7 +83,7 @@ class SearchRelayListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): SearchRelayListEvent { - val publicTagArray = relays.map { RelayTag.assemble(it) }.plus(ALT_TAG).toTypedArray() + val publicTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() return signer.signNip51List(createdAt, KIND, publicTagArray, emptyArray()) } @@ -96,7 +92,7 @@ class SearchRelayListEvent( signer: NostrSignerSync, createdAt: Long = TimeUtils.now(), ): SearchRelayListEvent { - val publicTagArray = relays.map { RelayTag.assemble(it) }.plus(ALT_TAG).toTypedArray() + val publicTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() return signer.signNip51List(createdAt, KIND, publicTagArray, emptyArray()) } @@ -111,7 +107,6 @@ class SearchRelayListEvent( description = PrivateTagsInContent.encryptNip44(privateRelays.map { RelayTag.assemble(it) }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) searchRelays(publicRelays) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/PinListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/PinListEvent.kt index 13ac854473..1674ca6164 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/PinListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/PinListEvent.kt @@ -25,10 +25,8 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.EventBookmark import com.vitorpamplona.quartz.utils.TimeUtils @@ -54,7 +52,6 @@ class PinListEvent( companion object { const val KIND = 10001 - const val ALT = "Pinned Notes" fun createPinAddress(pubKey: HexKey) = Address(KIND, pubKey, "") @@ -63,7 +60,7 @@ class PinListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): PinListEvent { - val tags = arrayOf(pin.toTagArray(), AltTag.assemble(ALT)) + val tags = arrayOf(pin.toTagArray()) return signer.sign(createdAt, KIND, tags, "") } @@ -96,12 +93,7 @@ class PinListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): PinListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, "") } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/appCurationSet/AppCurationSetEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/appCurationSet/AppCurationSetEvent.kt index 2be5f3968d..2320bbd1b0 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/appCurationSet/AppCurationSetEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/appCurationSet/AppCurationSetEvent.kt @@ -26,13 +26,10 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark import com.vitorpamplona.quartz.nip51Lists.remove @@ -70,7 +67,6 @@ class AppCurationSetEvent( companion object { const val KIND = 30267 - const val ALT = "App Curation Set" fun createAddress( pubKey: HexKey, @@ -109,12 +105,7 @@ class AppCurationSetEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): AppCurationSetEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -150,7 +141,6 @@ class AppCurationSetEvent( createdAt = createdAt, ) { dTag(dTag) - alt(ALT) title(title) apps(apps) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/articleCurationSet/ArticleCurationSetEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/articleCurationSet/ArticleCurationSetEvent.kt index c98dd4fd15..1535c66d8e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/articleCurationSet/ArticleCurationSetEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/articleCurationSet/ArticleCurationSetEvent.kt @@ -25,15 +25,12 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark @@ -82,7 +79,6 @@ class ArticleCurationSetEvent( companion object { const val KIND = 30004 - const val ALT = "Article Curation Set" fun createAddress( pubKey: HexKey, @@ -155,12 +151,7 @@ class ArticleCurationSetEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): ArticleCurationSetEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -199,7 +190,6 @@ class ArticleCurationSetEvent( createdAt = createdAt, ) { dTag(dTag) - alt(ALT) title(title) bookmarks(publicItems) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/bookmarkList/BookmarkListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/bookmarkList/BookmarkListEvent.kt index 0438551672..0a2a9c95a1 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/bookmarkList/BookmarkListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/bookmarkList/BookmarkListEvent.kt @@ -25,14 +25,11 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.PrivateReplaceableTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark @@ -77,7 +74,6 @@ class BookmarkListEvent( companion object { const val KIND = 10003 - const val ALT = "List of bookmarks" fun createBookmarkAddress(pubKey: HexKey) = Address(KIND, pubKey, "") @@ -185,12 +181,7 @@ class BookmarkListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): BookmarkListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -218,7 +209,6 @@ class BookmarkListEvent( description = PrivateTagsInContent.encryptNip44(privateBookmarks.map { it.toTagArray() }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) title(title) bookmarks(publicBookmarks) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/bookmarkList/OldBookmarkListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/bookmarkList/OldBookmarkListEvent.kt index 32d9b050f2..ba49e6f75c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/bookmarkList/OldBookmarkListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/bookmarkList/OldBookmarkListEvent.kt @@ -25,15 +25,12 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark @@ -78,7 +75,6 @@ class OldBookmarkListEvent( companion object { const val KIND = 30001 - const val ALT = "List of bookmarks" const val DEFAULT_D_TAG_BOOKMARKS = "bookmark" fun createBookmarkAddress(pubKey: HexKey) = Address(KIND, pubKey, DEFAULT_D_TAG_BOOKMARKS) @@ -187,12 +183,7 @@ class OldBookmarkListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): OldBookmarkListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -223,7 +214,6 @@ class OldBookmarkListEvent( createdAt = createdAt, ) { dTag(dTag) - alt(ALT) addUnique(TitleTag.assemble(title)) addAll(publicBookmarks.map { it.toTagArray() }) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/favoriteAlgoFeedsList/FavoriteAlgoFeedsListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/favoriteAlgoFeedsList/FavoriteAlgoFeedsListEvent.kt index d4b673582b..e7a00838fe 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/favoriteAlgoFeedsList/FavoriteAlgoFeedsListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/favoriteAlgoFeedsList/FavoriteAlgoFeedsListEvent.kt @@ -25,12 +25,9 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent @@ -52,7 +49,6 @@ class FavoriteAlgoFeedsListEvent( companion object { const val KIND = 10090 - const val ALT = "Favorite algo-feeds list" const val FIXED_D_TAG = "" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, FIXED_D_TAG) @@ -148,12 +144,7 @@ class FavoriteAlgoFeedsListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): FavoriteAlgoFeedsListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -183,7 +174,6 @@ class FavoriteAlgoFeedsListEvent( ), createdAt = createdAt, ) { - alt(ALT) favoriteAlgoFeeds(publicFeeds) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/followList/FollowListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/followList/FollowListEvent.kt index 6edd0c861b..d1341702eb 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/followList/FollowListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/followList/FollowListEvent.kt @@ -25,13 +25,10 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.muteList.tags.UserTag import com.vitorpamplona.quartz.nip51Lists.remove @@ -73,7 +70,6 @@ class FollowListEvent( companion object { const val KIND = 39089 - const val ALT = "List of people to follow" fun createAddress( pubKey: HexKey, @@ -140,12 +136,7 @@ class FollowListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): FollowListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -175,7 +166,6 @@ class FollowListEvent( createdAt = createdAt, ) { dTag(dTag) - alt(ALT) title(name) people(people) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/geohashList/GeohashListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/geohashList/GeohashListEvent.kt index 15624bea87..4822e39119 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/geohashList/GeohashListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/geohashList/GeohashListEvent.kt @@ -25,14 +25,11 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.geohash.GeoHashTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.encryption.signNip51List @@ -57,7 +54,6 @@ class GeohashListEvent( companion object { const val KIND = 10081 - const val ALT = "Geohash List" const val FIXED_D_TAG = "" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, FIXED_D_TAG) @@ -169,12 +165,7 @@ class GeohashListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): GeohashListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -196,7 +187,7 @@ class GeohashListEvent( createdAt: Long = TimeUtils.now(), ): GeohashListEvent { val privateTagArray = publicGeohashes.map { GeoHashTag.assembleSingle(it) }.toTypedArray() - val publicTagArray = privateGeohashes.map { GeoHashTag.assembleSingle(it) }.toTypedArray() + AltTag.assemble(ALT) + val publicTagArray = privateGeohashes.map { GeoHashTag.assembleSingle(it) }.toTypedArray() return signer.signNip51List(createdAt, KIND, publicTagArray, privateTagArray) } @@ -211,7 +202,6 @@ class GeohashListEvent( description = PrivateTagsInContent.encryptNip44(privateGeohashes.map { GeoHashTag.assembleSingle(it) }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) geohashes(publicGeohashes) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/gitAuthorList/GitAuthorListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/gitAuthorList/GitAuthorListEvent.kt index 64dced6684..84d5999307 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/gitAuthorList/GitAuthorListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/gitAuthorList/GitAuthorListEvent.kt @@ -24,11 +24,9 @@ import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.gitAuthorList.tags.GitAuthorTag @@ -55,7 +53,6 @@ class GitAuthorListEvent( companion object { const val KIND = 10017 - const val ALT = "Git Authors List" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, "") @@ -129,12 +126,7 @@ class GitAuthorListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): GitAuthorListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/gitRepositoryList/GitRepositoryListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/gitRepositoryList/GitRepositoryListEvent.kt index 0cb4ee6223..a80e4f396e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/gitRepositoryList/GitRepositoryListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/gitRepositoryList/GitRepositoryListEvent.kt @@ -24,11 +24,9 @@ import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent @@ -55,7 +53,6 @@ class GitRepositoryListEvent( companion object { const val KIND = 10018 - const val ALT = "Git Repositories List" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, "") @@ -129,12 +126,7 @@ class GitRepositoryListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): GitRepositoryListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/goodWikiAuthorList/GoodWikiAuthorListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/goodWikiAuthorList/GoodWikiAuthorListEvent.kt index 9146d22ad9..8885ca44ab 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/goodWikiAuthorList/GoodWikiAuthorListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/goodWikiAuthorList/GoodWikiAuthorListEvent.kt @@ -24,11 +24,9 @@ import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.muteList.tags.UserTag @@ -55,7 +53,6 @@ class GoodWikiAuthorListEvent( companion object { const val KIND = 10101 - const val ALT = "Good Wiki Authors List" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, "") @@ -129,12 +126,7 @@ class GoodWikiAuthorListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): GoodWikiAuthorListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/goodWikiRelayList/GoodWikiRelayListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/goodWikiRelayList/GoodWikiRelayListEvent.kt index 536937ff46..c70b4cb373 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/goodWikiRelayList/GoodWikiRelayListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/goodWikiRelayList/GoodWikiRelayListEvent.kt @@ -24,11 +24,9 @@ import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.relayLists.tags.RelayTag @@ -53,7 +51,6 @@ class GoodWikiRelayListEvent( companion object { const val KIND = 10102 - const val ALT = "Good Wiki Relays List" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, "") @@ -128,12 +125,7 @@ class GoodWikiRelayListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): GoodWikiRelayListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/hashtagList/HashtagListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/hashtagList/HashtagListEvent.kt index a095271cc6..8d862ce132 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/hashtagList/HashtagListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/hashtagList/HashtagListEvent.kt @@ -25,14 +25,11 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.hashtags.HashtagTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.encryption.signNip51List @@ -53,7 +50,6 @@ class HashtagListEvent( companion object { const val KIND = 10015 - const val ALT = "Hashtag List" const val FIXED_D_TAG = "" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, FIXED_D_TAG) @@ -165,12 +161,7 @@ class HashtagListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): HashtagListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -192,7 +183,7 @@ class HashtagListEvent( createdAt: Long = TimeUtils.now(), ): HashtagListEvent { val privateTagArray = publicHashtags.map { HashtagTag.assemble(it) }.toTypedArray() - val publicTagArray = privateHashtags.map { HashtagTag.assemble(it) }.toTypedArray() + AltTag.assemble(ALT) + val publicTagArray = privateHashtags.map { HashtagTag.assemble(it) }.toTypedArray() return signer.signNip51List(createdAt, KIND, publicTagArray, privateTagArray) } @@ -207,7 +198,6 @@ class HashtagListEvent( description = PrivateTagsInContent.encryptNip44(privateHashtags.map { HashtagTag.assemble(it) }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) hashtags(publicHashtags) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/interestSet/InterestSetEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/interestSet/InterestSetEvent.kt index 12072ab335..6c1cc5e124 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/interestSet/InterestSetEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/interestSet/InterestSetEvent.kt @@ -25,14 +25,11 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.HashtagTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent @@ -68,7 +65,6 @@ class InterestSetEvent( companion object { const val KIND = 30015 - const val ALT = "Interest Set" fun createAddress( pubKey: HexKey, @@ -134,12 +130,7 @@ class InterestSetEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): InterestSetEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -172,7 +163,6 @@ class InterestSetEvent( createdAt = createdAt, ) { dTag(dTag) - alt(ALT) title(title) hashtags(publicHashtags) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/kindMuteSet/KindMuteSetEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/kindMuteSet/KindMuteSetEvent.kt index 6d231bb8ad..2dd938ae95 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/kindMuteSet/KindMuteSetEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/kindMuteSet/KindMuteSetEvent.kt @@ -25,14 +25,11 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.muteList.tags.UserTag @@ -59,7 +56,6 @@ class KindMuteSetEvent( companion object { const val KIND = 30007 - const val ALT = "Kind Mute Set" fun createAddress( pubKey: HexKey, @@ -123,12 +119,7 @@ class KindMuteSetEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): KindMuteSetEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -157,7 +148,6 @@ class KindMuteSetEvent( createdAt = createdAt, ) { dTag(kindNumber.toString()) - alt(ALT) peoples(publicMutedUsers) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/labeledBookmarkList/LabeledBookmarkListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/labeledBookmarkList/LabeledBookmarkListEvent.kt index cc20f2135c..4f3272d23a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/labeledBookmarkList/LabeledBookmarkListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/labeledBookmarkList/LabeledBookmarkListEvent.kt @@ -25,15 +25,12 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark @@ -95,8 +92,6 @@ class LabeledBookmarkListEvent( companion object { const val KIND = 30003 - const val ALT = "A labeled list of bookmarks" - @OptIn(ExperimentalUuidApi::class) fun createAddress( pubKey: HexKey, @@ -286,12 +281,7 @@ class LabeledBookmarkListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): LabeledBookmarkListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -330,7 +320,6 @@ class LabeledBookmarkListEvent( createdAt = createdAt, ) { dTag(dTag) - alt(ALT) title(title) bookmarks(publicBookmarks) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/mediaFollowList/MediaFollowListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/mediaFollowList/MediaFollowListEvent.kt index 60c0d6eade..b5e5f35a25 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/mediaFollowList/MediaFollowListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/mediaFollowList/MediaFollowListEvent.kt @@ -24,11 +24,9 @@ import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.muteList.tags.UserTag @@ -55,7 +53,6 @@ class MediaFollowListEvent( companion object { const val KIND = 10020 - const val ALT = "Media Follow List" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, "") @@ -129,12 +126,7 @@ class MediaFollowListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): MediaFollowListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/mediaStarterPack/MediaStarterPackEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/mediaStarterPack/MediaStarterPackEvent.kt index 9eeb887854..0082a17d05 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/mediaStarterPack/MediaStarterPackEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/mediaStarterPack/MediaStarterPackEvent.kt @@ -25,13 +25,10 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.followList.followIdSet import com.vitorpamplona.quartz.nip51Lists.followList.followIds @@ -76,7 +73,6 @@ class MediaStarterPackEvent( companion object { const val KIND = 39092 - const val ALT = "Media Starter Pack" fun createAddress( pubKey: HexKey, @@ -134,12 +130,7 @@ class MediaStarterPackEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): MediaStarterPackEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -157,7 +148,6 @@ class MediaStarterPackEvent( createdAt = createdAt, ) { dTag(dTag) - alt(ALT) title(name) people(people) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/muteList/MuteListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/muteList/MuteListEvent.kt index ebfecf2ad3..1230fe16b4 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/muteList/MuteListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/muteList/MuteListEvent.kt @@ -25,13 +25,10 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.muteList.tags.MuteTag @@ -65,7 +62,6 @@ class MuteListEvent( companion object { const val KIND = 10000 const val FIXED_D_TAG = "" - const val ALT = "Mute List" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, FIXED_D_TAG) @@ -168,12 +164,7 @@ class MuteListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): MuteListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -199,7 +190,6 @@ class MuteListEvent( description = PrivateTagsInContent.encryptNip44(privateMutes.map { it.toTagArray() }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) mutes(publicMutes) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/peopleList/PeopleListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/peopleList/PeopleListEvent.kt index 0705d75ec7..3a30f9548f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/peopleList/PeopleListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/peopleList/PeopleListEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner @@ -33,8 +32,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent @@ -93,7 +90,6 @@ class PeopleListEvent( companion object { const val KIND = 30000 const val BLOCK_LIST_D_TAG = "mute" - const val ALT = "List of people" fun createBlockAddress(pubKey: HexKey) = Address(KIND, pubKey, BLOCK_LIST_D_TAG) @@ -262,12 +258,7 @@ class PeopleListEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): PeopleListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -300,7 +291,6 @@ class PeopleListEvent( createdAt = createdAt, ) { dTag(dTag) - alt(ALT) title(title) peoples(publicMembers) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/pictureCurationSet/PictureCurationSetEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/pictureCurationSet/PictureCurationSetEvent.kt index f8546d4a24..b8ed6a0025 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/pictureCurationSet/PictureCurationSetEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/pictureCurationSet/PictureCurationSetEvent.kt @@ -25,14 +25,11 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.BookmarkIdTag @@ -75,7 +72,6 @@ class PictureCurationSetEvent( companion object { const val KIND = 30006 - const val ALT = "Picture Curation Set" fun createAddress( pubKey: HexKey, @@ -148,12 +144,7 @@ class PictureCurationSetEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): PictureCurationSetEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -192,7 +183,6 @@ class PictureCurationSetEvent( createdAt = createdAt, ) { dTag(dTag) - alt(ALT) title(title) bookmarks(publicItems) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/BlockedRelayListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/BlockedRelayListEvent.kt index 3c8a843bce..5676f4da24 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/BlockedRelayListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/BlockedRelayListEvent.kt @@ -30,8 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.encryption.signNip51List @@ -58,8 +56,6 @@ class BlockedRelayListEvent( companion object { const val KIND = 10006 - const val ALT = "Blocked relays from this author" - val ALT_TAG = arrayOf(AltTag.Companion.assemble(ALT)) fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, "") @@ -88,7 +84,7 @@ class BlockedRelayListEvent( createdAt: Long = TimeUtils.now(), ): BlockedRelayListEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, ALT_TAG, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } fun create( @@ -97,7 +93,7 @@ class BlockedRelayListEvent( createdAt: Long = TimeUtils.now(), ): BlockedRelayListEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, ALT_TAG, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } suspend fun build( @@ -111,7 +107,6 @@ class BlockedRelayListEvent( description = PrivateTagsInContent.encryptNip44(privateRelays.map { RelayTag.assemble(it) }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) blockedRelays(publicRelays) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/BroadcastRelayListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/BroadcastRelayListEvent.kt index a201da7f28..6cf4503639 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/BroadcastRelayListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/BroadcastRelayListEvent.kt @@ -30,8 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.encryption.signNip51List @@ -58,8 +56,6 @@ class BroadcastRelayListEvent( companion object { const val KIND = 10088 - const val ALT = "Broadcast relays from this author" - val TAGS = arrayOf(AltTag.assemble(ALT)) fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, "") @@ -87,7 +83,7 @@ class BroadcastRelayListEvent( createdAt: Long = TimeUtils.now(), ): BroadcastRelayListEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, TAGS, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } suspend fun create( @@ -96,7 +92,7 @@ class BroadcastRelayListEvent( createdAt: Long = TimeUtils.now(), ): BroadcastRelayListEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, TAGS, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } suspend fun build( @@ -110,7 +106,6 @@ class BroadcastRelayListEvent( description = PrivateTagsInContent.encryptNip44(privateRelays.map { RelayTag.assemble(it) }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) broadcastRelays(publicRelays) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/IndexerRelayListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/IndexerRelayListEvent.kt index 6a44448d64..e73816c900 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/IndexerRelayListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/IndexerRelayListEvent.kt @@ -30,8 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.encryption.signNip51List @@ -58,8 +56,6 @@ class IndexerRelayListEvent( companion object { const val KIND = 10086 - const val ALT = "Indexer relays from this author" - val TAGS = arrayOf(AltTag.assemble(ALT)) fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, "") @@ -88,7 +84,7 @@ class IndexerRelayListEvent( createdAt: Long = TimeUtils.now(), ): IndexerRelayListEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, TAGS, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } fun create( @@ -97,7 +93,7 @@ class IndexerRelayListEvent( createdAt: Long = TimeUtils.now(), ): IndexerRelayListEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, TAGS, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } suspend fun build( @@ -111,7 +107,6 @@ class IndexerRelayListEvent( description = PrivateTagsInContent.encryptNip44(privateRelays.map { RelayTag.assemble(it) }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) indexerRelays(publicRelays) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/ProxyRelayListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/ProxyRelayListEvent.kt index 8523db3ab9..834f324692 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/ProxyRelayListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/ProxyRelayListEvent.kt @@ -30,8 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.encryption.signNip51List @@ -58,8 +56,6 @@ class ProxyRelayListEvent( companion object { const val KIND = 10087 - const val ALT = "Proxy relays from this author" - val TAGS = arrayOf(AltTag.assemble(ALT)) fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, "") @@ -88,7 +84,7 @@ class ProxyRelayListEvent( createdAt: Long = TimeUtils.now(), ): ProxyRelayListEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, TAGS, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } suspend fun create( @@ -97,7 +93,7 @@ class ProxyRelayListEvent( createdAt: Long = TimeUtils.now(), ): ProxyRelayListEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, TAGS, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } suspend fun build( @@ -111,7 +107,6 @@ class ProxyRelayListEvent( description = PrivateTagsInContent.encryptNip44(privateRelays.map { RelayTag.assemble(it) }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) proxyRelays(publicRelays) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/RelayFeedsListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/RelayFeedsListEvent.kt index c802c0055d..ed36d3f423 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/RelayFeedsListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/RelayFeedsListEvent.kt @@ -30,8 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.encryption.signNip51List @@ -58,8 +56,6 @@ class RelayFeedsListEvent( companion object { const val KIND = 10012 - const val ALT = "Relay Feeds" - val TAGS = arrayOf(AltTag.assemble(ALT)) fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, "") @@ -88,7 +84,7 @@ class RelayFeedsListEvent( createdAt: Long = TimeUtils.now(), ): RelayFeedsListEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, TAGS, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } fun create( @@ -97,7 +93,7 @@ class RelayFeedsListEvent( createdAt: Long = TimeUtils.now(), ): RelayFeedsListEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, TAGS, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } suspend fun build( @@ -111,7 +107,6 @@ class RelayFeedsListEvent( description = PrivateTagsInContent.encryptNip44(privateRelays.map { RelayTag.assemble(it) }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) relayFeeds(publicRelays) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/TrustedRelayListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/TrustedRelayListEvent.kt index 3661ed939d..d47a5de7c3 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/TrustedRelayListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relayLists/TrustedRelayListEvent.kt @@ -30,8 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.encryption.signNip51List @@ -58,8 +56,6 @@ class TrustedRelayListEvent( companion object { const val KIND = 10089 - val ALT = "Trusted relays from this author" - val TAGS = arrayOf(AltTag.assemble(ALT)) fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, "") @@ -88,7 +84,7 @@ class TrustedRelayListEvent( createdAt: Long = TimeUtils.now(), ): TrustedRelayListEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, TAGS, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } suspend fun create( @@ -97,7 +93,7 @@ class TrustedRelayListEvent( createdAt: Long = TimeUtils.now(), ): TrustedRelayListEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, TAGS, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } suspend fun build( @@ -111,7 +107,6 @@ class TrustedRelayListEvent( description = PrivateTagsInContent.encryptNip44(privateRelays.map { RelayTag.assemble(it) }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) trustedRelays(publicRelays) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relaySets/RelaySetEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relaySets/RelaySetEvent.kt index 9780bdb630..89f004c4e5 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relaySets/RelaySetEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/relaySets/RelaySetEvent.kt @@ -28,8 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent @@ -66,8 +64,6 @@ class RelaySetEvent( companion object { const val KIND = 30002 - const val ALT = "Relay list" - val ALT_TAG = arrayOf(AltTag.assemble(ALT)) suspend fun updateRelayList( earlierVersion: RelaySetEvent, @@ -90,7 +86,7 @@ class RelaySetEvent( createdAt: Long = TimeUtils.now(), ): RelaySetEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, ALT_TAG, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } suspend fun create( @@ -99,7 +95,7 @@ class RelaySetEvent( createdAt: Long = TimeUtils.now(), ): RelaySetEvent { val privateTagArray = relays.map { RelayTag.assemble(it) }.toTypedArray() - return signer.signNip51List(createdAt, KIND, ALT_TAG, privateTagArray) + return signer.signNip51List(createdAt, KIND, emptyArray(), privateTagArray) } suspend fun build( @@ -113,7 +109,6 @@ class RelaySetEvent( description = PrivateTagsInContent.encryptNip44(privateRelays.map { RelayTag.assemble(it) }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) relaySet(publicRelays) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/releaseArtifactSet/ReleaseArtifactSetEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/releaseArtifactSet/ReleaseArtifactSetEvent.kt index 1c13812bae..f634bc4341 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/releaseArtifactSet/ReleaseArtifactSetEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/releaseArtifactSet/ReleaseArtifactSetEvent.kt @@ -25,14 +25,11 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.BookmarkIdTag @@ -74,7 +71,6 @@ class ReleaseArtifactSetEvent( companion object { const val KIND = 30063 - const val ALT = "Release Artifact Set" fun createAddress( pubKey: HexKey, @@ -113,12 +109,7 @@ class ReleaseArtifactSetEvent( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): ReleaseArtifactSetEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } + val newTags = tags return signer.sign(createdAt, KIND, newTags, content) } @@ -152,7 +143,6 @@ class ReleaseArtifactSetEvent( createdAt = createdAt, ) { dTag(dTag) - alt(ALT) title(title) artifacts(items) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/simpleGroupList/SimpleGroupListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/simpleGroupList/SimpleGroupListEvent.kt index 404720d281..bc7620a372 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/simpleGroupList/SimpleGroupListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/simpleGroupList/SimpleGroupListEvent.kt @@ -24,10 +24,8 @@ import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.remove @@ -48,7 +46,6 @@ class SimpleGroupListEvent( companion object { const val KIND = 10009 - const val ALT = "Simple Groups List" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, "") @@ -121,15 +118,6 @@ class SimpleGroupListEvent( tags: TagArray, signer: NostrSigner, createdAt: Long = TimeUtils.now(), - ): SimpleGroupListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } - - return signer.sign(createdAt, KIND, newTags, content) - } + ): SimpleGroupListEvent = signer.sign(createdAt, KIND, tags, content) } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/videoCurationSet/VideoCurationSetEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/videoCurationSet/VideoCurationSetEvent.kt index 881f8c4c21..65d0720dca 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/videoCurationSet/VideoCurationSetEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/videoCurationSet/VideoCurationSetEvent.kt @@ -25,15 +25,12 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark @@ -82,7 +79,6 @@ class VideoCurationSetEvent( companion object { const val KIND = 30005 - const val ALT = "Video Curation Set" fun createAddress( pubKey: HexKey, @@ -154,16 +150,7 @@ class VideoCurationSetEvent( tags: TagArray, signer: NostrSigner, createdAt: Long = TimeUtils.now(), - ): VideoCurationSetEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } - - return signer.sign(createdAt, KIND, newTags, content) - } + ): VideoCurationSetEvent = signer.sign(createdAt, KIND, tags, content) @OptIn(ExperimentalUuidApi::class) suspend fun create( @@ -199,7 +186,6 @@ class VideoCurationSetEvent( createdAt = createdAt, ) { dTag(dTag) - alt(ALT) title(title) bookmarks(publicItems) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/appt/day/CalendarDateSlotEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/appt/day/CalendarDateSlotEvent.kt index 251404c1c8..8c5e521bab 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/appt/day/CalendarDateSlotEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/appt/day/CalendarDateSlotEvent.kt @@ -34,7 +34,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.references.references import com.vitorpamplona.quartz.nip23LongContent.tags.ImageTag import com.vitorpamplona.quartz.nip23LongContent.tags.SummaryTag import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip52Calendar.appt.tags.LocationTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -77,7 +76,6 @@ class CalendarDateSlotEvent( companion object { const val KIND = 31922 - const val ALT = "Full-day calendar event" @OptIn(ExperimentalUuidApi::class) fun build( @@ -93,7 +91,6 @@ class CalendarDateSlotEvent( titleDay(title) startDate(start) end?.let { endDate(it) } - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/appt/time/CalendarTimeSlotEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/appt/time/CalendarTimeSlotEvent.kt index b036c88979..a616b8c523 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/appt/time/CalendarTimeSlotEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/appt/time/CalendarTimeSlotEvent.kt @@ -35,7 +35,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.references.references import com.vitorpamplona.quartz.nip23LongContent.tags.ImageTag import com.vitorpamplona.quartz.nip23LongContent.tags.SummaryTag import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip52Calendar.appt.tags.LocationTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -82,7 +81,6 @@ class CalendarTimeSlotEvent( companion object { const val KIND = 31923 - const val ALT = "Calendar time-slot event" @OptIn(ExperimentalUuidApi::class) fun build( @@ -102,7 +100,6 @@ class CalendarTimeSlotEvent( end?.let { endTimestamp(it) } startTzId?.let { startTzId(it) } endTzId?.let { endTzId(it) } - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/calendar/CalendarEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/calendar/CalendarEvent.kt index e11e4af522..311f24152d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/calendar/CalendarEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/calendar/CalendarEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.taggedAddresses import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils import kotlin.uuid.ExperimentalUuidApi @@ -52,7 +51,6 @@ class CalendarEvent( companion object { const val KIND = 31924 - const val ALT = "Calendar" @OptIn(ExperimentalUuidApi::class) fun build( @@ -64,7 +62,6 @@ class CalendarEvent( ) = eventTemplate(KIND, content, createdAt) { dTag(dTag) title(title) - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/rsvp/CalendarRSVPEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/rsvp/CalendarRSVPEvent.kt index a96ca7fd38..c58588e9ac 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/rsvp/CalendarRSVPEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip52Calendar/rsvp/CalendarRSVPEvent.kt @@ -33,7 +33,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.events.firstTaggedEvent import com.vitorpamplona.quartz.nip01Core.tags.people.PTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip52Calendar.appt.tags.RSVPStatusTag import com.vitorpamplona.quartz.nip52Calendar.rsvp.tags.FreeBusyTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -68,7 +67,6 @@ class CalendarRSVPEvent( companion object { const val KIND = 31925 - const val ALT = "Calendar event's invitation response" @OptIn(ExperimentalUuidApi::class) fun build( @@ -88,7 +86,6 @@ class CalendarRSVPEvent( calendarEventId?.let { add(it.toTagArray()) } calendarEventAuthor?.let { add(it.toTagArray()) } freebusy?.let { freebusy(it) } - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/clip/LiveActivitiesClipEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/clip/LiveActivitiesClipEvent.kt index 16f42ec884..2cb11ed6c6 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/clip/LiveActivitiesClipEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/clip/LiveActivitiesClipEvent.kt @@ -36,7 +36,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.aTag.aTag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.references.ReferenceTag import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -92,7 +91,6 @@ class LiveActivitiesClipEvent( companion object { const val KIND = 1313 - const val ALT = "Live activity clip" /** * Builds an event template for a clip. Typically published by the clip-authoring backend @@ -111,7 +109,6 @@ class LiveActivitiesClipEvent( add(PTag.assemble(host, null)) add(ReferenceTag.assemble(videoUrl)) add(TitleTag.assemble(title)) - add(AltTag.assemble(ALT)) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/meetingSpaces/MeetingRoomEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/meetingSpaces/MeetingRoomEvent.kt index c78c4208ea..2f5cc8c4b9 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/meetingSpaces/MeetingRoomEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/meetingSpaces/MeetingRoomEvent.kt @@ -36,8 +36,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip23LongContent.tags.ImageTag import com.vitorpamplona.quartz.nip23LongContent.tags.SummaryTag import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip53LiveActivities.LiveStreamLike import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.tags.MeetingSpaceTag @@ -160,13 +158,12 @@ class MeetingRoomEvent( companion object { const val KIND = 30313 - const val ALT = "Meeting room event" suspend fun create( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): MeetingRoomEvent { - val tags = arrayOf(AltTag.assemble(ALT)) + val tags = emptyArray>() return signer.sign(createdAt, KIND, tags, "") } @@ -185,7 +182,6 @@ class MeetingRoomEvent( title(title) starts(starts) status(status) - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/meetingSpaces/MeetingSpaceEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/meetingSpaces/MeetingSpaceEvent.kt index 2e8d2b09d5..69a4c5490b 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/meetingSpaces/MeetingSpaceEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/meetingSpaces/MeetingSpaceEvent.kt @@ -31,8 +31,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip23LongContent.tags.ImageTag import com.vitorpamplona.quartz.nip23LongContent.tags.SummaryTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.tags.EndpointUrlTag import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.tags.RelayListTag @@ -133,13 +131,12 @@ class MeetingSpaceEvent( companion object Companion { const val KIND = 30312 - const val ALT = "Interactive room event" suspend fun create( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): MeetingSpaceEvent { - val tags = arrayOf(AltTag.assemble(ALT)) + val tags = emptyArray>() return signer.sign(createdAt, KIND, tags, "") } @@ -158,7 +155,6 @@ class MeetingSpaceEvent( status(status) service(service) participant(host.pubKey, host.relayHint, host.role, host.proof) - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/nestsServers/NestsServersEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/nestsServers/NestsServersEvent.kt index 90fdc09e08..36e045eae8 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/nestsServers/NestsServersEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/nestsServers/NestsServersEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils /** @@ -102,7 +101,6 @@ class NestsServersEvent( companion object { const val KIND = 10112 - const val ALT = "Audio-room (nests) MoQ servers used by the author" fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) @@ -113,7 +111,6 @@ class NestsServersEvent( fun createTagArray(servers: List): Array> = servers .map { arrayOf("server", it.relay, it.auth) } - .plusElement(AltTag.assemble(ALT)) .toTypedArray() suspend fun updateRelayList( diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/presence/MeetingRoomPresenceEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/presence/MeetingRoomPresenceEvent.kt index 1a88ebd613..5e8d89253e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/presence/MeetingRoomPresenceEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/presence/MeetingRoomPresenceEvent.kt @@ -29,7 +29,6 @@ import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingRoomEvent import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.tags.MeetingSpaceTag @@ -67,7 +66,6 @@ class MeetingRoomPresenceEvent( companion object Companion { const val KIND = 10312 - const val ALT = "Room Presence tag" fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) @@ -81,8 +79,6 @@ class MeetingRoomPresenceEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(root.title() ?: ALT) - roomMeeting(MeetingSpaceTag(root.address(), root.relays().firstOrNull())) handRaised?.let { @@ -106,8 +102,6 @@ class MeetingRoomPresenceEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(root.room() ?: ALT) - roomMeeting(MeetingSpaceTag(root.address(), root.relays().firstOrNull())) handRaised?.let { handRaised(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/streaming/LiveActivitiesEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/streaming/LiveActivitiesEvent.kt index ea20dece90..e02bf44442 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/streaming/LiveActivitiesEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/streaming/LiveActivitiesEvent.kt @@ -34,8 +34,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip23LongContent.tags.ImageTag import com.vitorpamplona.quartz.nip23LongContent.tags.SummaryTag import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip53LiveActivities.LiveStreamLike import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.CurrentParticipantsTag @@ -156,14 +154,13 @@ class LiveActivitiesEvent( companion object { const val KIND = 30311 - const val ALT = "Live activity event" const val GOAL_TAG = "goal" suspend fun create( signer: NostrSigner, createdAt: Long = TimeUtils.now(), ): LiveActivitiesEvent { - val tags = arrayOf(AltTag.assemble(ALT)) + val tags = emptyArray>() return signer.sign(createdAt, KIND, tags, "") } @@ -174,7 +171,6 @@ class LiveActivitiesEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { dTag(dTag) - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt index ea7449d1fb..0298ab9346 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip54Wiki/WikiNoteEvent.kt @@ -55,7 +55,6 @@ import com.vitorpamplona.quartz.nip23LongContent.tags.ImageTag import com.vitorpamplona.quartz.nip23LongContent.tags.PublishedAtTag import com.vitorpamplona.quartz.nip23LongContent.tags.SummaryTag import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils import kotlin.uuid.ExperimentalUuidApi @@ -173,7 +172,6 @@ class WikiNoteEvent( ): EventTemplate = eventTemplate(KIND, description, createdAt) { dTag(dTag) - alt("Wiki entry: $title") title(title) summary?.let { summary(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip56Reports/ReportEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip56Reports/ReportEvent.kt index 95f6b87c62..422f31a0e8 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip56Reports/ReportEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip56Reports/ReportEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip56Reports.tags.DefaultReportTag import com.vitorpamplona.quartz.nip56Reports.tags.ReportedAddressTag import com.vitorpamplona.quartz.nip56Reports.tags.ReportedAuthorTag @@ -74,7 +73,6 @@ class ReportEvent( companion object { const val KIND = 1984 - const val ALT_PREFIX = "Report for " fun build( reportedPost: Event, @@ -82,7 +80,6 @@ class ReportEvent( comment: String = "", createdAt: Long = TimeUtils.now(), ) = eventTemplate(KIND, comment, createdAt) { - alt(ALT_PREFIX + type.code) event(reportedPost.id, type) user(reportedPost.pubKey, type) @@ -97,7 +94,6 @@ class ReportEvent( comment: String = "", createdAt: Long = TimeUtils.now(), ) = eventTemplate(KIND, comment, createdAt) { - alt(ALT_PREFIX + type.code) user(reportedUser, type) } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip57Zaps/LnZapRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip57Zaps/LnZapRequestEvent.kt index 371805438a..9e57317be8 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip57Zaps/LnZapRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip57Zaps/LnZapRequestEvent.kt @@ -36,7 +36,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.kinds.KindTag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -98,7 +97,6 @@ class LnZapRequestEvent( companion object { const val KIND = 9734 - const val ALT = "Zap request" suspend fun create( zappedEvent: Event, @@ -118,7 +116,6 @@ class LnZapRequestEvent( arrayOf("p", toUserPubHex ?: zappedEvent.pubKey), arrayOf("relays") + relays.map { it.url }, KindTag.assemble(zappedEvent.kind), - AltTag.assemble(ALT), ) if (zappedEvent is AddressableEvent) { tags = tags + listOf(ATag.assemble(zappedEvent.address(), null)) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/accepted/AcceptedBadgeSetEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/accepted/AcceptedBadgeSetEvent.kt index 451de1943b..fe4d7be2ba 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/accepted/AcceptedBadgeSetEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/accepted/AcceptedBadgeSetEvent.kt @@ -34,7 +34,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip58Badges.accepted.tags.AcceptedBadge import com.vitorpamplona.quartz.utils.TimeUtils @@ -71,7 +70,6 @@ class AcceptedBadgeSetEvent( companion object { const val KIND = 30008 private const val STANDARD_D_TAG = "profile_badges" - const val ALT_DESCRIPTION = "List of accepted badges by the author" fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, STANDARD_D_TAG) @@ -88,7 +86,6 @@ class AcceptedBadgeSetEvent( val prefix = tagArray { dTag(STANDARD_D_TAG) - alt(ALT_DESCRIPTION) initializer() } val pairs = AcceptedBadge.assemble(acceptedBadges).toTypedArray() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/award/BadgeAwardEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/award/BadgeAwardEvent.kt index a858699f5e..32df688097 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/award/BadgeAwardEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/award/BadgeAwardEvent.kt @@ -31,7 +31,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -66,7 +65,6 @@ class BadgeAwardEvent( companion object { const val KIND = 8 - const val ALT_DESCRIPTION = "Badge award" fun build( awardDefinition: ATag, @@ -74,7 +72,6 @@ class BadgeAwardEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) awardDefinition(awardDefinition) awardees(awardees) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/definition/BadgeDefinitionEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/definition/BadgeDefinitionEvent.kt index df73ec3dae..84b17898a4 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/definition/BadgeDefinitionEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/definition/BadgeDefinitionEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip58Badges.definition.tags.ImageTag import com.vitorpamplona.quartz.nip58Badges.definition.tags.ThumbTag @@ -59,7 +58,6 @@ class BadgeDefinitionEvent( companion object { const val KIND = 30009 - const val ALT_DESCRIPTION = "Badge definition" fun build( badgeId: String, @@ -71,7 +69,6 @@ class BadgeDefinitionEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { dTag(badgeId) - alt(ALT_DESCRIPTION) name?.let { name(it) } image?.let { image(it.url, it.dimensions) } description?.let { description(it) } @@ -92,7 +89,6 @@ class BadgeDefinitionEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { dTag(badgeId) - alt(ALT_DESCRIPTION) name?.let { name(it) } imageUrl?.let { image(it, imageDimensions) } description?.let { description(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/profile/ProfileBadgesEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/profile/ProfileBadgesEvent.kt index e683cc51c9..38bf805b9f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/profile/ProfileBadgesEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip58Badges/profile/ProfileBadgesEvent.kt @@ -33,7 +33,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip58Badges.accepted.tags.AcceptedBadge import com.vitorpamplona.quartz.utils.TimeUtils @@ -69,7 +68,6 @@ class ProfileBadgesEvent( companion object { const val KIND = 10008 - const val ALT_DESCRIPTION = "List of accepted badges by the author" fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, "") @@ -85,7 +83,6 @@ class ProfileBadgesEvent( // the builder, then append the ordered pair tags verbatim. val prefix = tagArray { - alt(ALT_DESCRIPTION) initializer() } val pairs = AcceptedBadge.assemble(acceptedBadges).toTypedArray() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5aStaticWebsites/NamedSiteEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5aStaticWebsites/NamedSiteEvent.kt index 96f09e79b2..fd235c3c43 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5aStaticWebsites/NamedSiteEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5aStaticWebsites/NamedSiteEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip5aStaticWebsites.tags.PathTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -57,7 +56,6 @@ class NamedSiteEvent( companion object { const val KIND = 35128 - const val ALT_DESCRIPTION = "Named Static Website" fun build( identifier: String, @@ -69,7 +67,6 @@ class NamedSiteEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) dTag(identifier) sitePaths(paths) if (servers.isNotEmpty()) siteServers(servers) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5aStaticWebsites/RootSiteEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5aStaticWebsites/RootSiteEvent.kt index 96af04bfed..52b45cfdc5 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5aStaticWebsites/RootSiteEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5aStaticWebsites/RootSiteEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip5aStaticWebsites.tags.PathTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -54,7 +53,6 @@ class RootSiteEvent( companion object { const val KIND = 15128 - const val ALT_DESCRIPTION = "Static Website" fun build( paths: List, @@ -65,7 +63,6 @@ class RootSiteEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) sitePaths(paths) if (servers.isNotEmpty()) siteServers(servers) title?.let { siteTitle(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5dNapplets/NamedNappletEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5dNapplets/NamedNappletEvent.kt index 349c42f605..40faba2996 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5dNapplets/NamedNappletEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5dNapplets/NamedNappletEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip5aStaticWebsites.siteAggregateHash import com.vitorpamplona.quartz.nip5aStaticWebsites.siteDescription @@ -59,7 +58,6 @@ class NamedNappletEvent( companion object { const val KIND = 35129 - const val ALT_DESCRIPTION = "Named Napplet" fun build( identifier: String, @@ -72,7 +70,6 @@ class NamedNappletEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) dTag(identifier) sitePaths(paths) siteAggregateHash(paths) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5dNapplets/NappletSnapshotEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5dNapplets/NappletSnapshotEvent.kt index 19aff15da0..3e77abbe2d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5dNapplets/NappletSnapshotEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5dNapplets/NappletSnapshotEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip5aStaticWebsites.siteAggregateHash import com.vitorpamplona.quartz.nip5aStaticWebsites.siteDescription @@ -56,7 +55,6 @@ class NappletSnapshotEvent( companion object { const val KIND = 5129 - const val ALT_DESCRIPTION = "Napplet snapshot" fun build( paths: List, @@ -68,7 +66,6 @@ class NappletSnapshotEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) sitePaths(paths) siteAggregateHash(paths) if (servers.isNotEmpty()) siteServers(servers) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5dNapplets/RootNappletEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5dNapplets/RootNappletEvent.kt index 6efd223122..9f029a4eb9 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5dNapplets/RootNappletEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip5dNapplets/RootNappletEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip5aStaticWebsites.siteAggregateHash import com.vitorpamplona.quartz.nip5aStaticWebsites.siteDescription @@ -56,7 +55,6 @@ class RootNappletEvent( companion object { const val KIND = 15129 - const val ALT_DESCRIPTION = "Napplet" fun build( paths: List, @@ -68,7 +66,6 @@ class RootNappletEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) sitePaths(paths) siteAggregateHash(paths) if (servers.isNotEmpty()) siteServers(servers) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/history/CashuSpendingHistoryEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/history/CashuSpendingHistoryEvent.kt index eebbfddea9..adcd455875 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/history/CashuSpendingHistoryEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/history/CashuSpendingHistoryEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.utils.TimeUtils @@ -110,7 +109,6 @@ class CashuSpendingHistoryEvent( companion object { const val KIND = 7376 - const val ALT_DESCRIPTION = "Cashu spending history" suspend fun build( direction: SpendingDirection, @@ -121,7 +119,6 @@ class CashuSpendingHistoryEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) // Unencrypted "e" tags for redeemed markers tokenReferences .filter { it.marker == TokenReference.MARKER_REDEEMED } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/quote/CashuMintQuoteEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/quote/CashuMintQuoteEvent.kt index 5dde71e5bb..47566e7d7a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/quote/CashuMintQuoteEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/quote/CashuMintQuoteEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip40Expiration.expiration import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.serialization.SerialName @@ -99,7 +98,6 @@ class CashuMintQuoteEvent( companion object { const val KIND = 7374 - const val ALT_DESCRIPTION = "Cashu mint quote" const val TWO_WEEKS_SECONDS = 14 * 24 * 60 * 60L suspend fun build( @@ -119,7 +117,6 @@ class CashuMintQuoteEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) expiration(expirationTimestamp) add(arrayOf("mint", mintUrl)) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/token/CashuTokenEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/token/CashuTokenEvent.kt index 9242511727..b19ae11e80 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/token/CashuTokenEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/token/CashuTokenEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils /** @@ -63,7 +62,6 @@ class CashuTokenEvent( companion object { const val KIND = 7375 - const val ALT_DESCRIPTION = "Cashu token" suspend fun build( tokenContent: TokenContent, @@ -71,7 +69,6 @@ class CashuTokenEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) initializer() }.let { template -> val encryptedContent = signer.nip44Encrypt(TokenContentParser.toJson(tokenContent), signer.pubKey) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/wallet/CashuWalletEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/wallet/CashuWalletEvent.kt index c9337d0429..9b2fd15b27 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/wallet/CashuWalletEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip60Cashu/wallet/CashuWalletEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.utils.TimeUtils @@ -72,7 +71,6 @@ class CashuWalletEvent( companion object { const val KIND = 17375 - const val ALT_DESCRIPTION = "Cashu wallet" const val FIXED_D_TAG = "" fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) @@ -84,7 +82,6 @@ class CashuWalletEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) initializer() }.let { template -> val privateTags = diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/info/NutzapInfoEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/info/NutzapInfoEvent.kt index 48ef04c993..8a876ccc7d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/info/NutzapInfoEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/info/NutzapInfoEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip61Nutzaps.info.tags.NutzapMintTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -48,7 +47,6 @@ class NutzapInfoEvent( companion object { const val KIND = 10019 - const val ALT_DESCRIPTION = "Nutzap receiving preferences" fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, BaseReplaceableEvent.FIXED_D_TAG) @@ -59,7 +57,6 @@ class NutzapInfoEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) mints(mints) relays(relays) p2pkPubkey(p2pkPubkey) @@ -67,8 +64,8 @@ class NutzapInfoEvent( } /** - * Build an empty kind:10019 — no mints, no relays, no P2PK pubkey, - * just the alt tag. Publishing this replaces a prior nutzap-info + * Build an empty kind:10019 — no mints, no relays, no P2PK pubkey. + * Publishing this replaces a prior nutzap-info * event and signals to other clients that this user no longer * advertises any way to receive nutzaps: a reader has no shared mint * and no pubkey to lock proofs against, so it cannot build a nutzap. @@ -81,7 +78,6 @@ class NutzapInfoEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/nutzap/NutzapEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/nutzap/NutzapEvent.kt index e7eb3262ac..0fb1a7b8da 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/nutzap/NutzapEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/nutzap/NutzapEvent.kt @@ -30,7 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -65,7 +64,6 @@ class NutzapEvent( companion object { const val KIND = 9321 - const val ALT_DESCRIPTION = "Nutzap" fun build( message: String, @@ -77,7 +75,6 @@ class NutzapEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, message, createdAt) { - alt(ALT_DESCRIPTION) proofs(proofs) mintUrl(mintUrl) unit(unit) @@ -100,7 +97,6 @@ class NutzapEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, message, createdAt) { - alt(ALT_DESCRIPTION) proofs(proofs) mintUrl(mintUrl) unit(unit) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/redemption/NutzapRedemptionEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/redemption/NutzapRedemptionEvent.kt index d15c42f726..8cfc908eef 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/redemption/NutzapRedemptionEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/redemption/NutzapRedemptionEvent.kt @@ -30,7 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip61Nutzaps.nutzap.NutzapEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -57,7 +56,6 @@ class NutzapRedemptionEvent( companion object { const val KIND = 7376 - const val ALT_DESCRIPTION = "Nutzap redemption" fun build( nutzap: EventHintBundle, @@ -65,7 +63,6 @@ class NutzapRedemptionEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, encryptedContent, createdAt) { - alt(ALT_DESCRIPTION) redeemedNutzap(nutzap) notifySender(nutzap) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/token/TokenEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/token/TokenEvent.kt index 1183bff2b1..0970ccde4a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/token/TokenEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip61Nutzaps/token/TokenEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -39,14 +38,12 @@ class TokenEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 7375 - const val ALT_DESCRIPTION = "Token" fun build( encryptedContent: String, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, encryptedContent, createdAt) { - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip62RequestToVanish/RequestToVanishEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip62RequestToVanish/RequestToVanishEvent.kt index e374820fe0..ad297aa64e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip62RequestToVanish/RequestToVanishEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip62RequestToVanish/RequestToVanishEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip62RequestToVanish.tags.shouldVanishFrom import com.vitorpamplona.quartz.nip62RequestToVanish.tags.vanishFrom import com.vitorpamplona.quartz.nip62RequestToVanish.tags.vanishFromAllRelays @@ -49,7 +48,6 @@ class RequestToVanishEvent( companion object { const val KIND = 62 - const val ALT = "Request to vanish" fun build( relay: NormalizedRelayUrl, @@ -57,7 +55,6 @@ class RequestToVanishEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, reason, createdAt) { - alt(ALT) vanishFrom(relay) initializer() } @@ -68,7 +65,6 @@ class RequestToVanishEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, reason, createdAt) { - alt(ALT) vanishFrom(relays) initializer() } @@ -78,7 +74,6 @@ class RequestToVanishEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, reason, createdAt) { - alt(ALT) vanishFromEverywhere() initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/challenge/accept/LiveChessGameAcceptEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/challenge/accept/LiveChessGameAcceptEvent.kt index a15fed4d9d..b378b328ff 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/challenge/accept/LiveChessGameAcceptEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/challenge/accept/LiveChessGameAcceptEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip64Chess.baseEvent.BaseChessEvent import com.vitorpamplona.quartz.nip64Chess.challenge.offer.LiveChessGameChallengeEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -54,7 +53,6 @@ class LiveChessGameAcceptEvent( companion object { const val KIND = 30065 - const val ALT_DESCRIPTION = "Chess game acceptance" fun build( gameId: String, @@ -65,7 +63,6 @@ class LiveChessGameAcceptEvent( dTag(gameId) challenge(challengeEvent) challenger(challengeEvent) - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/challenge/offer/LiveChessGameChallengeEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/challenge/offer/LiveChessGameChallengeEvent.kt index ebd8897a6f..e6599ce1c7 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/challenge/offer/LiveChessGameChallengeEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/challenge/offer/LiveChessGameChallengeEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip64Chess.Color import com.vitorpamplona.quartz.nip64Chess.baseEvent.BaseChessEvent import com.vitorpamplona.quartz.nip64Chess.baseEvent.opponent @@ -61,7 +60,6 @@ class LiveChessGameChallengeEvent( companion object { const val KIND = 30064 - const val ALT_DESCRIPTION = "Chess game challenge" fun build( gameId: String, @@ -75,7 +73,6 @@ class LiveChessGameChallengeEvent( playerColor(playerColor) opponent?.let { opponent(opponent) } timeControl?.let { timeControl(it) } - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/draw/LiveChessDrawOfferEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/draw/LiveChessDrawOfferEvent.kt index 1870f62b59..9d2ad8358f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/draw/LiveChessDrawOfferEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/draw/LiveChessDrawOfferEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip64Chess.baseEvent.BaseChessEvent import com.vitorpamplona.quartz.nip64Chess.baseEvent.opponent import com.vitorpamplona.quartz.nip64Chess.baseEvent.tags.OpponentTag @@ -56,7 +55,6 @@ class LiveChessDrawOfferEvent( companion object { const val KIND = 30068 - const val ALT_DESCRIPTION = "Chess draw offer" fun build( gameId: String, @@ -67,7 +65,6 @@ class LiveChessDrawOfferEvent( ) = eventTemplate(KIND, message, createdAt) { dTag(gameId) opponent(opponent) - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/end/LiveChessGameEndEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/end/LiveChessGameEndEvent.kt index 6f90d13161..83c74bb9c3 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/end/LiveChessGameEndEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/end/LiveChessGameEndEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip64Chess.GameResult import com.vitorpamplona.quartz.nip64Chess.GameTermination import com.vitorpamplona.quartz.nip64Chess.baseEvent.BaseChessEvent @@ -66,7 +65,6 @@ class LiveChessGameEndEvent( companion object { const val KIND = 30067 - const val ALT_DESCRIPTION = "Chess game ended" fun build( gameId: String, @@ -83,7 +81,6 @@ class LiveChessGameEndEvent( termination(termination) winnerPubkey?.let { winner(it) } opponent(opponent) - alt("$ALT_DESCRIPTION: ${result.notation}") initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/game/ChessGameEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/game/ChessGameEvent.kt index 002020023e..6a2f210ea3 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/game/ChessGameEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/game/ChessGameEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils /** @@ -57,24 +56,20 @@ class ChessGameEvent( companion object { const val KIND = 64 - const val ALT_DESCRIPTION = "Chess Game" /** * Create a chess game event from PGN content * Per NIP-64, clients should publish in strict "export format" * * @param pgnContent Valid PGN format string - * @param altDescription Alt text for non-supporting clients (NIP-31) * @param createdAt Event timestamp * @param initializer Additional tag builder operations */ fun build( pgnContent: String, - altDescription: String = ALT_DESCRIPTION, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, pgnContent, createdAt) { - alt(altDescription) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/move/LiveChessMoveEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/move/LiveChessMoveEvent.kt index 843953cba1..7dddb2791b 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/move/LiveChessMoveEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip64Chess/move/LiveChessMoveEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip64Chess.baseEvent.BaseChessEvent import com.vitorpamplona.quartz.nip64Chess.baseEvent.opponent import com.vitorpamplona.quartz.nip64Chess.baseEvent.tags.OpponentTag @@ -66,7 +65,6 @@ class LiveChessMoveEvent( companion object { const val KIND = 30066 - const val ALT_DESCRIPTION = "Chess move" fun build( gameId: String, @@ -84,7 +82,6 @@ class LiveChessMoveEvent( san(san) fen(fen) opponent(opponent) - alt("$ALT_DESCRIPTION: $san") initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/discovery/RelayDiscoveryEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/discovery/RelayDiscoveryEvent.kt index 5601954437..9dfc43895c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/discovery/RelayDiscoveryEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/discovery/RelayDiscoveryEvent.kt @@ -29,7 +29,6 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashes -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip66RelayMonitor.discovery.tags.RttType import com.vitorpamplona.quartz.utils.TimeUtils @@ -82,7 +81,6 @@ class RelayDiscoveryEvent( companion object { const val KIND = 30166 - const val ALT_DESCRIPTION = "Relay discovery" fun build( relayUrl: NormalizedRelayUrl, @@ -90,7 +88,6 @@ class RelayDiscoveryEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, content, createdAt) { - alt(ALT_DESCRIPTION) dTag(relayUrl.url) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/monitor/RelayMonitorEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/monitor/RelayMonitorEvent.kt index a84925eb36..2508667aab 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/monitor/RelayMonitorEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip66RelayMonitor/monitor/RelayMonitorEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohash import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashes -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip66RelayMonitor.monitor.tags.CheckType import com.vitorpamplona.quartz.nip66RelayMonitor.monitor.tags.TimeoutTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -63,7 +62,6 @@ class RelayMonitorEvent( companion object { const val KIND = 10166 - const val ALT_DESCRIPTION = "Relay monitor announcement" fun build( frequencySeconds: Long, @@ -73,7 +71,6 @@ class RelayMonitorEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) frequency(frequencySeconds) checks(checks) timeouts(timeouts) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip68Picture/PictureEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip68Picture/PictureEvent.kt index 4467964a30..12aa3abdc0 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip68Picture/PictureEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip68Picture/PictureEvent.kt @@ -29,7 +29,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohashes import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags import com.vitorpamplona.quartz.nip22Comments.RootScope import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip68Picture.tags.LocationTag import com.vitorpamplona.quartz.nip92IMeta.imetas @@ -70,7 +69,6 @@ class PictureEvent( companion object { const val KIND = 20 - const val ALT_DESCRIPTION = "List of pictures" fun build( image: PictureMeta, @@ -97,7 +95,6 @@ class PictureEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description, createdAt) { - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip69P2pOrderEvents/P2POrderEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip69P2pOrderEvents/P2POrderEvent.kt index ee4be304b5..50d3759304 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip69P2pOrderEvents/P2POrderEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip69P2pOrderEvents/P2POrderEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip40Expiration.expiration import com.vitorpamplona.quartz.nip69P2pOrderEvents.tags.FiatAmountTag import com.vitorpamplona.quartz.nip69P2pOrderEvents.tags.OrderStatus @@ -78,7 +77,6 @@ class P2POrderEvent( companion object { const val KIND = 38383 - const val ALT_DESCRIPTION = "P2P Order" @OptIn(ExperimentalUuidApi::class) fun build( @@ -122,7 +120,6 @@ class P2POrderEvent( makerName?.let { makerName(it) } geohash?.let { geohash(it) } bond?.let { bond(it) } - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoHorizontalEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoHorizontalEvent.kt index dbd5434a59..67abb889ff 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoHorizontalEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoHorizontalEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip22Comments.RootScope -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils import kotlin.uuid.ExperimentalUuidApi import kotlin.uuid.Uuid @@ -44,7 +43,6 @@ class VideoHorizontalEvent( RootScope { companion object { const val KIND = 34235 - const val ALT_DESCRIPTION = "Horizontal Video" fun build( video: VideoMeta, @@ -75,7 +73,6 @@ class VideoHorizontalEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description, createdAt) { dTag(dTag) - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoNormalEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoNormalEvent.kt index 132a493762..f7a6079805 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoNormalEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoNormalEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip22Comments.RootScope -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -40,7 +39,6 @@ class VideoNormalEvent( RootScope { companion object { const val KIND = 21 - const val ALT_DESCRIPTION = "Horizontal Video" fun build( video: VideoMeta, @@ -67,7 +65,6 @@ class VideoNormalEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description, createdAt) { - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoShortEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoShortEvent.kt index ecbda1e062..3650246586 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoShortEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoShortEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip22Comments.RootScope -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -40,7 +39,6 @@ class VideoShortEvent( RootScope { companion object { const val KIND = 22 - const val ALT_DESCRIPTION = "Vertical Video" fun build( video: VideoMeta, @@ -57,7 +55,6 @@ class VideoShortEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description, createdAt) { - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoVerticalEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoVerticalEvent.kt index 0f46b0433e..880c8bf885 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoVerticalEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip71Video/VideoVerticalEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip22Comments.RootScope -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils import kotlin.uuid.ExperimentalUuidApi import kotlin.uuid.Uuid @@ -44,7 +43,6 @@ class VideoVerticalEvent( RootScope { companion object { const val KIND = 34236 - const val ALT_DESCRIPTION = "Vertical Video" fun build( video: VideoMeta, @@ -64,7 +62,6 @@ class VideoVerticalEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description, createdAt) { dTag(dTag) - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/approval/CommunityPostApprovalEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/approval/CommunityPostApprovalEvent.kt index a3eadc1b3f..3347b88a9e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/approval/CommunityPostApprovalEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/approval/CommunityPostApprovalEvent.kt @@ -33,7 +33,6 @@ import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.kinds.kind import com.vitorpamplona.quartz.nip01Core.tags.people.PTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip72ModCommunities.approval.tags.ApprovedAddressTag import com.vitorpamplona.quartz.nip72ModCommunities.approval.tags.ApprovedEventTag import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent @@ -95,7 +94,6 @@ class CommunityPostApprovalEvent( companion object { const val KIND = 4550 - const val ALT_DESCRIPTION = "Community post approval" val KIND_LIST = listOf(CommunityPostApprovalEvent.KIND) fun build( @@ -104,8 +102,6 @@ class CommunityPostApprovalEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) - community(community) approved(approvedPost) notifyAuthor(approvedPost) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/definition/CommunityDefinitionEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/definition/CommunityDefinitionEvent.kt index 6a8a679b42..a74aa022da 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/definition/CommunityDefinitionEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/definition/CommunityDefinitionEvent.kt @@ -33,7 +33,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip18Reposts.quotes.QTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip72ModCommunities.definition.tags.DescriptionTag import com.vitorpamplona.quartz.nip72ModCommunities.definition.tags.ImageTag @@ -94,7 +93,6 @@ class CommunityDefinitionEvent( companion object { const val KIND = 34550 const val KIND_STR = "34550" - const val ALT_DESCRIPTION = "Community definition" @OptIn(ExperimentalUuidApi::class) fun build( @@ -108,8 +106,6 @@ class CommunityDefinitionEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) - dTag(dTag) name(name) description(description) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/follow/CommunityListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/follow/CommunityListEvent.kt index dd6bbd16bc..7a1536713a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/follow/CommunityListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/follow/CommunityListEvent.kt @@ -25,13 +25,10 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.remove @@ -59,7 +56,6 @@ class CommunityListEvent( companion object { const val KIND = 10004 - const val ALT = "Community List" const val FIXED_D_TAG = "" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, FIXED_D_TAG) @@ -188,16 +184,7 @@ class CommunityListEvent( tags: TagArray, signer: NostrSigner, createdAt: Long = TimeUtils.now(), - ): CommunityListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } - - return signer.sign(createdAt, KIND, newTags, content) - } + ): CommunityListEvent = signer.sign(createdAt, KIND, tags, content) suspend fun create( publicCommunities: List = emptyList(), @@ -220,7 +207,6 @@ class CommunityListEvent( description = PrivateTagsInContent.encryptNip44(privateCommunities.map { it.toTagArray() }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) communities(publicCommunities) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/rules/CommunityRulesEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/rules/CommunityRulesEvent.kt index 6880633307..fe10a155f3 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/rules/CommunityRulesEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip72ModCommunities/rules/CommunityRulesEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip72ModCommunities.rules.tags.KindRuleTag import com.vitorpamplona.quartz.nip72ModCommunities.rules.tags.MaxEventSizeTag import com.vitorpamplona.quartz.nip72ModCommunities.rules.tags.MinRulesCreatedAtTag @@ -101,7 +100,6 @@ class CommunityRulesEvent( companion object { const val KIND = 34551 const val KIND_STR = "34551" - const val ALT_DESCRIPTION = "Community rules" fun build( dTag: String, @@ -114,8 +112,6 @@ class CommunityRulesEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) - dTag(dTag) add(communityAddress.toATagArray()) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip75ZapGoals/GoalEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip75ZapGoals/GoalEvent.kt index a9e327cf5d..6aa94ed385 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip75ZapGoals/GoalEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip75ZapGoals/GoalEvent.kt @@ -40,7 +40,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.references.reference import com.vitorpamplona.quartz.nip23LongContent.tags.ImageTag import com.vitorpamplona.quartz.nip23LongContent.tags.SummaryTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip75ZapGoals.tags.AmountTag import com.vitorpamplona.quartz.nip75ZapGoals.tags.ClosedAtTag @@ -88,7 +87,6 @@ class GoalEvent( companion object { const val KIND = 9041 - const val ALT_DESCRIPTION = "Zap Goal" fun build( description: String, @@ -114,7 +112,6 @@ class GoalEvent( } linked(it.toETag()) } - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip78AppData/AppDataEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip78AppData/AppDataEvent.kt index af8a560efe..a25f472abc 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip78AppData/AppDataEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip78AppData/AppDataEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.DTag import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils /** @@ -52,7 +51,6 @@ class AppDataEvent( companion object { const val KIND = 78 - const val ALT = "Arbitrary app data" fun build( content: String, @@ -60,7 +58,6 @@ class AppDataEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, content, createdAt) { - alt(ALT) dTag?.let { addUnique(DTag.assemble(it)) } initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip78AppData/AppSpecificDataEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip78AppData/AppSpecificDataEvent.kt index 85c4d9e290..eba9fd265e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip78AppData/AppSpecificDataEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip78AppData/AppSpecificDataEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils class AppSpecificDataEvent( @@ -42,7 +41,6 @@ class AppSpecificDataEvent( companion object { const val KIND = 30078 - const val ALT = "Arbitrary app data" fun createAddress( pubKey: HexKey, @@ -60,7 +58,6 @@ class AppSpecificDataEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description, createdAt) { - alt(ALT) dTag(dTag) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip7DThreads/ThreadEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip7DThreads/ThreadEvent.kt index d0cef02576..94ffa12233 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip7DThreads/ThreadEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip7DThreads/ThreadEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip22Comments.RootScope -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -47,7 +46,6 @@ class ThreadEvent( companion object { const val KIND = 11 - const val ALT_DESCRIPTION = "Thread" fun build( content: String, @@ -55,7 +53,6 @@ class ThreadEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, content, createdAt) { - alt(ALT_DESCRIPTION) title(title) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip84Highlights/HighlightEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip84Highlights/HighlightEvent.kt index 8327bd7a5d..f1fdbe1e97 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip84Highlights/HighlightEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip84Highlights/HighlightEvent.kt @@ -46,7 +46,6 @@ import com.vitorpamplona.quartz.nip19Bech32.eventIds import com.vitorpamplona.quartz.nip19Bech32.pubKeyHints import com.vitorpamplona.quartz.nip19Bech32.pubKeys import com.vitorpamplona.quartz.nip22Comments.RootScope -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip84Highlights.tags.CommentTag import com.vitorpamplona.quartz.nip84Highlights.tags.ContextTag @@ -132,12 +131,11 @@ class HighlightEvent( companion object { const val KIND = 9802 - const val ALT = "Highlight/quote event" suspend fun create( msg: String, signer: NostrSigner, createdAt: Long = TimeUtils.now(), - ): HighlightEvent = signer.sign(createdAt, KIND, arrayOf(AltTag.assemble(ALT)), msg) + ): HighlightEvent = signer.sign(createdAt, KIND, emptyArray(), msg) } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/addressables/AddressableAssertionEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/addressables/AddressableAssertionEvent.kt index 4a113de32e..2ed3ef2fb6 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/addressables/AddressableAssertionEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/addressables/AddressableAssertionEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip85TrustedAssertions.tags.CommentCountTag import com.vitorpamplona.quartz.nip85TrustedAssertions.tags.QuoteCountTag import com.vitorpamplona.quartz.nip85TrustedAssertions.tags.ReactionCountTag @@ -63,7 +62,6 @@ class AddressableAssertionEvent( companion object { const val KIND = 30384 - const val ALT = "Addressable Event Assertion" fun build( targetEventAddress: String, @@ -71,7 +69,6 @@ class AddressableAssertionEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { dTag(targetEventAddress) - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/events/EventAssertionEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/events/EventAssertionEvent.kt index b0a0791b32..3874fb6ba0 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/events/EventAssertionEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/events/EventAssertionEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip85TrustedAssertions.tags.CommentCountTag import com.vitorpamplona.quartz.nip85TrustedAssertions.tags.QuoteCountTag import com.vitorpamplona.quartz.nip85TrustedAssertions.tags.ReactionCountTag @@ -63,7 +62,6 @@ class EventAssertionEvent( companion object { const val KIND = 30383 - const val ALT = "Event Assertion" fun build( targetEventId: HexKey, @@ -71,7 +69,6 @@ class EventAssertionEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { dTag(targetEventId) - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/externalIds/ExternalIdAssertionEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/externalIds/ExternalIdAssertionEvent.kt index 68d2f877b4..bb11b4784d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/externalIds/ExternalIdAssertionEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/externalIds/ExternalIdAssertionEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip85TrustedAssertions.tags.CommentCountTag import com.vitorpamplona.quartz.nip85TrustedAssertions.tags.ReactionCountTag import com.vitorpamplona.quartz.nip85TrustedAssertions.users.tags.RankTag @@ -51,7 +50,6 @@ class ExternalIdAssertionEvent( companion object { const val KIND = 30385 - const val ALT = "External Identifier Assertion" fun build( targetIdentifier: String, @@ -59,7 +57,6 @@ class ExternalIdAssertionEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { dTag(targetIdentifier) - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/list/TrustProviderListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/list/TrustProviderListEvent.kt index 0d255c1496..c901813730 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/list/TrustProviderListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/list/TrustProviderListEvent.kt @@ -25,12 +25,9 @@ import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.AltTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.removeParsing @@ -50,7 +47,6 @@ class TrustProviderListEvent( companion object { const val KIND = 10040 - const val ALT = "Trusted Service Providers" const val FIXED_D_TAG = "" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, FIXED_D_TAG) @@ -133,16 +129,7 @@ class TrustProviderListEvent( tags: TagArray, signer: NostrSigner, createdAt: Long = TimeUtils.now(), - ): TrustProviderListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } - - return signer.sign(createdAt, KIND, newTags, content) - } + ): TrustProviderListEvent = signer.sign(createdAt, KIND, tags, content) suspend fun create( publicProviders: List = emptyList(), @@ -162,7 +149,6 @@ class TrustProviderListEvent( description = PrivateTagsInContent.encryptNip44(privateProviders.map { it.toTagArray() }.toTypedArray(), signer), createdAt = createdAt, ) { - alt(ALT) serviceProviders(publicProviders) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/users/ContactCardEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/users/ContactCardEvent.kt index cb1c58b7b0..24b53cac48 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/users/ContactCardEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip85TrustedAssertions/users/ContactCardEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.core.tagArray import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent @@ -109,7 +108,6 @@ class ContactCardEvent( companion object { const val KIND = 30382 - const val ALT = "Contact Card" fun createAddress( owner: HexKey, @@ -132,7 +130,6 @@ class ContactCardEvent( ): ContactCardEvent { val publicTags = tagArray { - alt(ALT) dTag(targetUser) publicInitializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip87Ecash/cashu/CashuMintEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip87Ecash/cashu/CashuMintEvent.kt index 12edf19132..d3db502775 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip87Ecash/cashu/CashuMintEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip87Ecash/cashu/CashuMintEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip87Ecash.NetworkType import com.vitorpamplona.quartz.utils.TimeUtils @@ -48,7 +47,6 @@ class CashuMintEvent( companion object { const val KIND = 38172 - const val ALT_DESCRIPTION = "Cashu Mint Announcement" fun build( mintPubKey: String, @@ -59,7 +57,6 @@ class CashuMintEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, metadata, createdAt) { - alt(ALT_DESCRIPTION) dTag(mintPubKey) mintUrl(mintUrl) nuts(nuts) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip87Ecash/fedimint/FedimintEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip87Ecash/fedimint/FedimintEvent.kt index ba6f81130a..ceea8374c1 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip87Ecash/fedimint/FedimintEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip87Ecash/fedimint/FedimintEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip87Ecash.NetworkType import com.vitorpamplona.quartz.utils.TimeUtils @@ -48,7 +47,6 @@ class FedimintEvent( companion object { const val KIND = 38173 - const val ALT_DESCRIPTION = "Fedimint Announcement" fun build( federationId: String, @@ -59,7 +57,6 @@ class FedimintEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, metadata, createdAt) { - alt(ALT_DESCRIPTION) dTag(federationId) inviteCodes(inviteCodes) modules(modules) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip87Ecash/recommendation/MintRecommendationEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip87Ecash/recommendation/MintRecommendationEvent.kt index d586cf7d23..9060bf7bf8 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip87Ecash/recommendation/MintRecommendationEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip87Ecash/recommendation/MintRecommendationEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip87Ecash.cashu.CashuMintEvent import com.vitorpamplona.quartz.nip87Ecash.fedimint.FedimintEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -53,7 +52,6 @@ class MintRecommendationEvent( companion object { const val KIND = 38000 - const val ALT_DESCRIPTION = "Mint Recommendation" fun build( mintIdentifier: String, @@ -65,7 +63,6 @@ class MintRecommendationEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, review, createdAt) { - alt(ALT_DESCRIPTION) dTag(mintIdentifier) kTag(mintKind) mintUrls.forEach { mintUrl(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip88Polls/poll/PollEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip88Polls/poll/PollEvent.kt index e6f0976082..3cf63ff717 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip88Polls/poll/PollEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip88Polls/poll/PollEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip22Comments.RootScope -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip88Polls.poll.tags.OptionTag import com.vitorpamplona.quartz.nip88Polls.poll.tags.PollType @@ -62,7 +61,6 @@ class PollEvent( companion object { const val KIND = 1068 - const val ALT_DESCRIPTION = "Poll" fun build( description: String, @@ -73,7 +71,6 @@ class PollEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description, createdAt) { - alt(ALT_DESCRIPTION) poolType(pollType) options(options) relays(relays) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip88Polls/response/PollResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip88Polls/response/PollResponseEvent.kt index 9d579e2bb5..719512f9f8 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip88Polls/response/PollResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip88Polls/response/PollResponseEvent.kt @@ -30,7 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip22Comments.RootScope -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip88Polls.poll.PollEvent import com.vitorpamplona.quartz.nip88Polls.response.tags.PollTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -61,7 +60,6 @@ class PollResponseEvent( companion object { const val KIND = 1018 - const val ALT_DESCRIPTION = "Poll Response" fun build( poll: EventHintBundle, @@ -69,7 +67,6 @@ class PollResponseEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) poll(poll) notifyAuthor(poll) responses(responses) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/clientTag/EventExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/clientTag/EventExt.kt index ca48ffadab..e8c68efaf7 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/clientTag/EventExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/clientTag/EventExt.kt @@ -23,3 +23,6 @@ package com.vitorpamplona.quartz.nip89AppHandlers.clientTag import com.vitorpamplona.quartz.nip01Core.core.Event fun Event.client() = tags.client() + +/** True when this event was published by the client named [name] (NIP-89, case-insensitive). */ +fun Event.isClient(name: String) = tags.isClient(name) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/clientTag/TagArrayExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/clientTag/TagArrayExt.kt index 4ec759eaa3..f7ae9d439f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/clientTag/TagArrayExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/clientTag/TagArrayExt.kt @@ -23,3 +23,6 @@ package com.vitorpamplona.quartz.nip89AppHandlers.clientTag import com.vitorpamplona.quartz.nip01Core.core.TagArray fun TagArray.client() = this.mapNotNull(ClientTag::parse) + +/** True when any client tag (NIP-89) names [name] (case-insensitive). */ +fun TagArray.isClient(name: String) = this.any { ClientTag.isTag(it) && it[1].equals(name, ignoreCase = true) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/definition/AppDefinitionEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/definition/AppDefinitionEvent.kt index a250490e7f..78cf731091 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/definition/AppDefinitionEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/definition/AppDefinitionEvent.kt @@ -31,7 +31,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.kinds.kinds import com.vitorpamplona.quartz.nip01Core.tags.publishedAt.PublishedAtProvider import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri import com.vitorpamplona.quartz.nip23LongContent.tags.PublishedAtTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip89AppHandlers.PlatformType import com.vitorpamplona.quartz.nip89AppHandlers.definition.tags.PlatformLinkTag @@ -119,7 +118,6 @@ class AppDefinitionEvent( companion object { const val KIND = 31990 - const val ALT_DESCRIPTION = "App definition event" // ["web", "https://..../a/", "nevent"] class PlatformLink( @@ -141,7 +139,6 @@ class AppDefinitionEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, details.toJson(), createdAt) { dTag(dTag) - alt(ALT_DESCRIPTION) kinds(supportedKinds) links(links) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/recommendation/AppRecommendationEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/recommendation/AppRecommendationEvent.kt index d2c0792df0..cd4ea491d3 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/recommendation/AppRecommendationEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/recommendation/AppRecommendationEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.hints.AddressHintProvider import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.dTag.dTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip89AppHandlers.PlatformType import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent import com.vitorpamplona.quartz.nip89AppHandlers.recommendation.tags.RecommendationTag @@ -54,7 +53,6 @@ class AppRecommendationEvent( companion object { const val KIND = 31989 - const val ALT_DESCRIPTION = "App recommendations by the author" class AppRecommendationItem( val appDefinitionEvent: AppDefinitionEvent, @@ -72,7 +70,6 @@ class AppRecommendationEvent( appReferences.forEach { recommend(it.appDefinitionEvent.addressTag(), it.relayHint, it.platform.code) } - alt(ALT_DESCRIPTION) initializer() } @@ -84,7 +81,6 @@ class AppRecommendationEvent( ) = eventTemplate(KIND, "", createdAt) { dTag(supportedKind) recommend(recommendations) - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/NIP90ContentDiscoveryRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/NIP90ContentDiscoveryRequestEvent.kt index 48d820f572..d6df3c9589 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/NIP90ContentDiscoveryRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryRequest/NIP90ContentDiscoveryRequestEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParam import com.vitorpamplona.quartz.nip90Dvms.tags.inputs @@ -57,7 +56,6 @@ class NIP90ContentDiscoveryRequestEvent( companion object { const val KIND = 5300 - const val ALT = "NIP90 Content Discovery request" fun build( dvmPublicKey: HexKey, @@ -66,7 +64,6 @@ class NIP90ContentDiscoveryRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) dvmPubKey(dvmPublicKey) relays(relays) param("max_results", "200") diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryResponse/NIP90ContentDiscoveryResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryResponse/NIP90ContentDiscoveryResponseEvent.kt index 4ed27534b4..105a1d1fde 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryResponse/NIP90ContentDiscoveryResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentDiscoveryResponse/NIP90ContentDiscoveryResponseEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils @@ -70,13 +69,11 @@ class NIP90ContentDiscoveryResponseEvent( companion object { const val KIND = 6300 - const val ALT = "NIP90 Content Discovery reply" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentSearch/NIP90ContentSearchRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentSearch/NIP90ContentSearchRequestEvent.kt index f7093bfb5f..f2c6a7f069 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentSearch/NIP90ContentSearchRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentSearch/NIP90ContentSearchRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParam import com.vitorpamplona.quartz.nip90Dvms.tags.firstInputByType @@ -57,7 +56,6 @@ class NIP90ContentSearchRequestEvent( companion object { const val KIND = 5302 - const val ALT = "NIP90 Content Search request" fun build( searchQuery: String, @@ -68,7 +66,6 @@ class NIP90ContentSearchRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) inputText(searchQuery) users?.let { param("users", it) } since?.let { param("since", it.toString()) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentSearch/NIP90ContentSearchResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentSearch/NIP90ContentSearchResponseEvent.kt index 57e07e894e..894a70dc90 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentSearch/NIP90ContentSearchResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentSearch/NIP90ContentSearchResponseEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils @@ -70,13 +69,11 @@ class NIP90ContentSearchResponseEvent( companion object { const val KIND = 6302 - const val ALT = "NIP90 Content Search response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventCount/NIP90EventCountRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventCount/NIP90EventCountRequestEvent.kt index 7af5173577..504672ea10 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventCount/NIP90EventCountRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventCount/NIP90EventCountRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParamAll import com.vitorpamplona.quartz.nip90Dvms.tags.inputText @@ -52,7 +51,6 @@ class NIP90EventCountRequestEvent( companion object { const val KIND = 5400 - const val ALT = "NIP90 Event Count request" fun build( inputs: List = emptyList(), @@ -62,7 +60,6 @@ class NIP90EventCountRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, filterJson, createdAt) { - alt(ALT) inputs.forEach { inputText(it) } relays.forEach { param("relay", it) } groups.forEach { param("group", it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventCount/NIP90EventCountResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventCount/NIP90EventCountResponseEvent.kt index 8373cb998c..84f0d173d6 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventCount/NIP90EventCountResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventCount/NIP90EventCountResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -41,13 +40,11 @@ class NIP90EventCountResponseEvent( companion object { const val KIND = 6400 - const val ALT = "NIP90 Event Count response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPowDelegation/NIP90EventPowDelegationRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPowDelegation/NIP90EventPowDelegationRequestEvent.kt index c371a0d6c0..1f0d7570ae 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPowDelegation/NIP90EventPowDelegationRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPowDelegation/NIP90EventPowDelegationRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParam import com.vitorpamplona.quartz.nip90Dvms.tags.inputText @@ -50,7 +49,6 @@ class NIP90EventPowDelegationRequestEvent( companion object { const val KIND = 5970 - const val ALT = "NIP90 Event PoW Delegation request" fun build( eventJson: String, @@ -58,7 +56,6 @@ class NIP90EventPowDelegationRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) inputText(eventJson) param("pow", pow.toString()) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPowDelegation/NIP90EventPowDelegationResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPowDelegation/NIP90EventPowDelegationResponseEvent.kt index 306972d3f6..ab46d67d28 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPowDelegation/NIP90EventPowDelegationResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPowDelegation/NIP90EventPowDelegationResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -39,13 +38,11 @@ class NIP90EventPowDelegationResponseEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 6970 - const val ALT = "NIP90 Event PoW Delegation response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPublishSchedule/NIP90EventPublishScheduleRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPublishSchedule/NIP90EventPublishScheduleRequestEvent.kt index a82e27d51c..a6eab69fa8 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPublishSchedule/NIP90EventPublishScheduleRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPublishSchedule/NIP90EventPublishScheduleRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParamValues import com.vitorpamplona.quartz.nip90Dvms.tags.inputText @@ -50,7 +49,6 @@ class NIP90EventPublishScheduleRequestEvent( companion object { const val KIND = 5905 - const val ALT = "NIP90 Event Publish Schedule request" fun build( eventJson: String, @@ -58,7 +56,6 @@ class NIP90EventPublishScheduleRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) inputText(eventJson) if (relays.isNotEmpty()) { param("relays", *relays.toTypedArray()) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPublishSchedule/NIP90EventPublishScheduleResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPublishSchedule/NIP90EventPublishScheduleResponseEvent.kt index a5b29b16e8..1dfa2e5980 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPublishSchedule/NIP90EventPublishScheduleResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPublishSchedule/NIP90EventPublishScheduleResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -41,13 +40,11 @@ class NIP90EventPublishScheduleResponseEvent( companion object { const val KIND = 6905 - const val ALT = "NIP90 Event Publish Schedule response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventTimestamping/NIP90EventTimestampingRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventTimestamping/NIP90EventTimestampingRequestEvent.kt index 3686612a4b..4280ea87ca 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventTimestamping/NIP90EventTimestampingRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventTimestamping/NIP90EventTimestampingRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.firstInputByType import com.vitorpamplona.quartz.nip90Dvms.tags.inputEvent @@ -47,14 +46,12 @@ class NIP90EventTimestampingRequestEvent( companion object { const val KIND = 5900 - const val ALT = "NIP90 Event Timestamping request" fun build( eventId: HexKey, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) inputEvent(eventId) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventTimestamping/NIP90EventTimestampingResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventTimestamping/NIP90EventTimestampingResponseEvent.kt index b79d5ab557..604079190e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventTimestamping/NIP90EventTimestampingResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventTimestamping/NIP90EventTimestampingResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -41,13 +40,11 @@ class NIP90EventTimestampingResponseEvent( companion object { const val KIND = 6900 - const val ALT = "NIP90 Event Timestamping response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageGeneration/NIP90ImageGenerationRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageGeneration/NIP90ImageGenerationRequestEvent.kt index 4d613568ab..f71aba97e7 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageGeneration/NIP90ImageGenerationRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageGeneration/NIP90ImageGenerationRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParam import com.vitorpamplona.quartz.nip90Dvms.tags.firstInputByType @@ -62,7 +61,6 @@ class NIP90ImageGenerationRequestEvent( companion object { const val KIND = 5100 - const val ALT = "NIP90 Image Generation request" fun build( prompt: String, @@ -75,7 +73,6 @@ class NIP90ImageGenerationRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) sourceImageUrl?.let { inputUrl(it) } inputText(prompt) model?.let { param("model", it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageGeneration/NIP90ImageGenerationResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageGeneration/NIP90ImageGenerationResponseEvent.kt index 8ea2870f87..ef07dd5fee 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageGeneration/NIP90ImageGenerationResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageGeneration/NIP90ImageGenerationResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -39,13 +38,11 @@ class NIP90ImageGenerationResponseEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 6100 - const val ALT = "NIP90 Image Generation response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageToVideo/NIP90ImageToVideoRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageToVideo/NIP90ImageToVideoRequestEvent.kt index ab5720c980..98557b94d5 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageToVideo/NIP90ImageToVideoRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageToVideo/NIP90ImageToVideoRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.firstInputByType import com.vitorpamplona.quartz.nip90Dvms.tags.inputUrl @@ -47,14 +46,12 @@ class NIP90ImageToVideoRequestEvent( companion object { const val KIND = 5202 - const val ALT = "NIP90 Image-to-Video request" fun build( imageUrl: String, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) inputUrl(imageUrl) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageToVideo/NIP90ImageToVideoResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageToVideo/NIP90ImageToVideoResponseEvent.kt index 7e7a9b94f4..9e3c21edfa 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageToVideo/NIP90ImageToVideoResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageToVideo/NIP90ImageToVideoResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -39,13 +38,11 @@ class NIP90ImageToVideoResponseEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 6202 - const val ALT = "NIP90 Image-to-Video response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/malwareScanning/NIP90MalwareScanRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/malwareScanning/NIP90MalwareScanRequestEvent.kt index 489686c3ba..af90743b08 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/malwareScanning/NIP90MalwareScanRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/malwareScanning/NIP90MalwareScanRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.firstInputByType import com.vitorpamplona.quartz.nip90Dvms.tags.inputUrl @@ -47,14 +46,12 @@ class NIP90MalwareScanRequestEvent( companion object { const val KIND = 5500 - const val ALT = "NIP90 Malware Scan request" fun build( fileUrl: String, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) inputUrl(fileUrl) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/malwareScanning/NIP90MalwareScanResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/malwareScanning/NIP90MalwareScanResponseEvent.kt index 02dfa7c191..37aae8e6df 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/malwareScanning/NIP90MalwareScanResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/malwareScanning/NIP90MalwareScanResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -41,13 +40,11 @@ class NIP90MalwareScanResponseEvent( companion object { const val KIND = 6500 - const val ALT = "NIP90 Malware Scan response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/opReturn/NIP90OpReturnRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/opReturn/NIP90OpReturnRequestEvent.kt index f3fbca7f9e..2cf9def354 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/opReturn/NIP90OpReturnRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/opReturn/NIP90OpReturnRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.firstInputByType import com.vitorpamplona.quartz.nip90Dvms.tags.inputText @@ -47,7 +46,6 @@ class NIP90OpReturnRequestEvent( companion object { const val KIND = 5901 - const val ALT = "NIP90 OP_RETURN Creation request" const val MAX_OP_RETURN_BYTES = 80 fun build( @@ -55,7 +53,6 @@ class NIP90OpReturnRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) inputText(text) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/opReturn/NIP90OpReturnResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/opReturn/NIP90OpReturnResponseEvent.kt index db3e2ff039..9e9b8e986c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/opReturn/NIP90OpReturnResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/opReturn/NIP90OpReturnResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -41,13 +40,11 @@ class NIP90OpReturnResponseEvent( companion object { const val KIND = 6901 - const val ALT = "NIP90 OP_RETURN Creation response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/peopleSearch/NIP90PeopleSearchRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/peopleSearch/NIP90PeopleSearchRequestEvent.kt index a190815081..e204172a8d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/peopleSearch/NIP90PeopleSearchRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/peopleSearch/NIP90PeopleSearchRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParam import com.vitorpamplona.quartz.nip90Dvms.tags.firstInputByType @@ -51,7 +50,6 @@ class NIP90PeopleSearchRequestEvent( companion object { const val KIND = 5303 - const val ALT = "NIP90 People Search request" fun build( searchQuery: String, @@ -59,7 +57,6 @@ class NIP90PeopleSearchRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) inputText(searchQuery) maxResults?.let { param("max_results", it.toString()) } initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/peopleSearch/NIP90PeopleSearchResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/peopleSearch/NIP90PeopleSearchResponseEvent.kt index 4e8900353f..6156985d53 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/peopleSearch/NIP90PeopleSearchResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/peopleSearch/NIP90PeopleSearchResponseEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils @@ -70,13 +69,11 @@ class NIP90PeopleSearchResponseEvent( companion object { const val KIND = 6303 - const val ALT = "NIP90 People Search response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/NIP90StatusEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/NIP90StatusEvent.kt index 0b157e3fc5..c01eb4cc38 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/NIP90StatusEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/status/NIP90StatusEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -43,13 +42,11 @@ class NIP90StatusEvent( companion object { const val KIND = 7000 - const val ALT = "NIP90 Status update" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/summarization/NIP90SummarizationRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/summarization/NIP90SummarizationRequestEvent.kt index 907d5f300e..3e7cf4a0db 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/summarization/NIP90SummarizationRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/summarization/NIP90SummarizationRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParam import com.vitorpamplona.quartz.nip90Dvms.tags.inputEvent @@ -52,7 +51,6 @@ class NIP90SummarizationRequestEvent( companion object { const val KIND = 5001 - const val ALT = "NIP90 Summarization request" fun build( eventIds: List, @@ -61,7 +59,6 @@ class NIP90SummarizationRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) eventIds.forEach { inputEvent(it) } length?.let { param("length", it) } outputMimeType?.let { output(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/summarization/NIP90SummarizationResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/summarization/NIP90SummarizationResponseEvent.kt index f8acffd446..d4b97ca533 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/summarization/NIP90SummarizationResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/summarization/NIP90SummarizationResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -39,13 +38,11 @@ class NIP90SummarizationResponseEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 6001 - const val ALT = "NIP90 Summarization response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textExtraction/NIP90TextExtractionRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textExtraction/NIP90TextExtractionRequestEvent.kt index 940e22716a..c61c29b542 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textExtraction/NIP90TextExtractionRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textExtraction/NIP90TextExtractionRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParam import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParamValues @@ -57,7 +56,6 @@ class NIP90TextExtractionRequestEvent( companion object { const val KIND = 5000 - const val ALT = "NIP90 Text Extraction request" fun build( inputUrl: String, @@ -68,7 +66,6 @@ class NIP90TextExtractionRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) inputUrl(inputUrl) outputMimeType?.let { output(it) } if (rangeStart != null && rangeEnd != null) { diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textExtraction/NIP90TextExtractionResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textExtraction/NIP90TextExtractionResponseEvent.kt index 54c50b593d..ae808faa45 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textExtraction/NIP90TextExtractionResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textExtraction/NIP90TextExtractionResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -39,13 +38,11 @@ class NIP90TextExtractionResponseEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 6000 - const val ALT = "NIP90 Text Extraction response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textGeneration/NIP90TextGenerationRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textGeneration/NIP90TextGenerationRequestEvent.kt index 5d058c7399..52f4c28d93 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textGeneration/NIP90TextGenerationRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textGeneration/NIP90TextGenerationRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParam import com.vitorpamplona.quartz.nip90Dvms.tags.inputPrompt @@ -62,7 +61,6 @@ class NIP90TextGenerationRequestEvent( companion object { const val KIND = 5050 - const val ALT = "NIP90 Text Generation request" fun build( prompt: String, @@ -76,7 +74,6 @@ class NIP90TextGenerationRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) inputPrompt(prompt) model?.let { param("model", it) } maxTokens?.let { param("max_tokens", it.toString()) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textGeneration/NIP90TextGenerationResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textGeneration/NIP90TextGenerationResponseEvent.kt index d249d9c3ba..ded0df9d9b 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textGeneration/NIP90TextGenerationResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textGeneration/NIP90TextGenerationResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -39,13 +38,11 @@ class NIP90TextGenerationResponseEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 6050 - const val ALT = "NIP90 Text Generation response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textToSpeech/NIP90TextToSpeechRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textToSpeech/NIP90TextToSpeechRequestEvent.kt index 0a45650843..0700e56b69 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textToSpeech/NIP90TextToSpeechRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textToSpeech/NIP90TextToSpeechRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParam import com.vitorpamplona.quartz.nip90Dvms.tags.firstInputByType @@ -51,7 +50,6 @@ class NIP90TextToSpeechRequestEvent( companion object { const val KIND = 5250 - const val ALT = "NIP90 Text-to-Speech request" fun build( text: String, @@ -59,7 +57,6 @@ class NIP90TextToSpeechRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) inputText(text) language?.let { param("language", it) } initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textToSpeech/NIP90TextToSpeechResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textToSpeech/NIP90TextToSpeechResponseEvent.kt index b0d654c63f..01cbf1e0ca 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textToSpeech/NIP90TextToSpeechResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textToSpeech/NIP90TextToSpeechResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -39,13 +38,11 @@ class NIP90TextToSpeechResponseEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 6250 - const val ALT = "NIP90 Text-to-Speech response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/translation/NIP90TranslationRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/translation/NIP90TranslationRequestEvent.kt index ad76d18e0b..aed285ea54 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/translation/NIP90TranslationRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/translation/NIP90TranslationRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParam import com.vitorpamplona.quartz.nip90Dvms.tags.inputEvent @@ -48,7 +47,6 @@ class NIP90TranslationRequestEvent( companion object { const val KIND = 5002 - const val ALT = "NIP90 Translation request" fun build( eventIds: List, @@ -56,7 +54,6 @@ class NIP90TranslationRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) eventIds.forEach { inputEvent(it) } param("language", language) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/translation/NIP90TranslationResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/translation/NIP90TranslationResponseEvent.kt index a39fe56a51..b43ef64283 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/translation/NIP90TranslationResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/translation/NIP90TranslationResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -39,13 +38,11 @@ class NIP90TranslationResponseEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 6002 - const val ALT = "NIP90 Translation response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/userDiscoveryRequest/NIP90UserDiscoveryRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/userDiscoveryRequest/NIP90UserDiscoveryRequestEvent.kt index b06a1cd63c..be937e06fe 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/userDiscoveryRequest/NIP90UserDiscoveryRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/userDiscoveryRequest/NIP90UserDiscoveryRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParam import com.vitorpamplona.quartz.nip90Dvms.tags.inputs @@ -48,13 +47,11 @@ class NIP90UserDiscoveryRequestEvent( companion object { const val KIND = 5301 - const val ALT = "NIP90 User Discovery request" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/userDiscoveryResponse/NIP90UserDiscoveryResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/userDiscoveryResponse/NIP90UserDiscoveryResponseEvent.kt index 7e0f101439..ba220f40bd 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/userDiscoveryResponse/NIP90UserDiscoveryResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/userDiscoveryResponse/NIP90UserDiscoveryResponseEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.TimeUtils @@ -70,13 +69,11 @@ class NIP90UserDiscoveryResponseEvent( companion object { const val KIND = 6301 - const val ALT = "NIP90 User Discovery reply" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoConversion/NIP90VideoConversionRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoConversion/NIP90VideoConversionRequestEvent.kt index 6524e95507..ffc3adc0c5 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoConversion/NIP90VideoConversionRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoConversion/NIP90VideoConversionRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParamValues import com.vitorpamplona.quartz.nip90Dvms.tags.inputUrl @@ -54,7 +53,6 @@ class NIP90VideoConversionRequestEvent( companion object { const val KIND = 5200 - const val ALT = "NIP90 Video Conversion request" fun build( videoUrl: String, @@ -64,7 +62,6 @@ class NIP90VideoConversionRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) inputUrl(videoUrl) outputMimeType?.let { output(it) } if (rangeStart != null && rangeEnd != null) { diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoConversion/NIP90VideoConversionResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoConversion/NIP90VideoConversionResponseEvent.kt index 3c5e832251..ebd7a9031c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoConversion/NIP90VideoConversionResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoConversion/NIP90VideoConversionResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -39,13 +38,11 @@ class NIP90VideoConversionResponseEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 6200 - const val ALT = "NIP90 Video Conversion response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoTranslation/NIP90VideoTranslationRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoTranslation/NIP90VideoTranslationRequestEvent.kt index 8f32c372b7..859be0382c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoTranslation/NIP90VideoTranslationRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoTranslation/NIP90VideoTranslationRequestEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip90Dvms.tags.InputTag import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParam import com.vitorpamplona.quartz.nip90Dvms.tags.dvmParamValues @@ -59,7 +58,6 @@ class NIP90VideoTranslationRequestEvent( companion object { const val KIND = 5201 - const val ALT = "NIP90 Video Translation request" fun build( videoUrl: String, @@ -71,7 +69,6 @@ class NIP90VideoTranslationRequestEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) inputUrl(videoUrl) param("language", language) subtitle?.let { param("subtitle", it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoTranslation/NIP90VideoTranslationResponseEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoTranslation/NIP90VideoTranslationResponseEvent.kt index c9fb05efcb..cea768fdd5 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoTranslation/NIP90VideoTranslationResponseEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoTranslation/NIP90VideoTranslationResponseEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -39,13 +38,11 @@ class NIP90VideoTranslationResponseEvent( ) : Event(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 6201 - const val ALT = "NIP90 Video Translation response" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip94FileMetadata/FileHeaderEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip94FileMetadata/FileHeaderEvent.kt index ad9aa67433..5ff71a5190 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip94FileMetadata/FileHeaderEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip94FileMetadata/FileHeaderEvent.kt @@ -92,7 +92,6 @@ class FileHeaderEvent( companion object { const val KIND = 1063 - const val ALT_DESCRIPTION = "Verifiable file url" fun build( url: String, @@ -101,7 +100,9 @@ class FileHeaderEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, caption ?: "", createdAt) { url(url) - caption?.ifBlank { null }?.let { alt(caption) } ?: alt(ALT_DESCRIPTION) + // NIP-94 accessibility description of the file (kept; the deprecated + // generic NIP-31 boilerplate alt is not written). + caption?.ifBlank { null }?.let { alt(it) } initializer() } @@ -121,7 +122,9 @@ class FileHeaderEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, caption ?: "", createdAt) { url(url) - caption?.ifBlank { null }?.let { alt(caption) } ?: alt(ALT_DESCRIPTION) + // NIP-94 accessibility description of the file (kept; the deprecated + // generic NIP-31 boilerplate alt is not written). + caption?.ifBlank { null }?.let { alt(it) } hash?.let { hash(it) } size?.let { fileSize(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip96FileStorage/config/FileServersEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip96FileStorage/config/FileServersEvent.kt index a85f133178..3e112661b0 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip96FileStorage/config/FileServersEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip96FileStorage/config/FileServersEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip96FileStorage.config.tags.ServerTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -44,7 +43,6 @@ class FileServersEvent( companion object { const val KIND = 10096 - const val ALT_DESCRIPTOR = "File servers used by the author" fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) @@ -66,7 +64,6 @@ class FileServersEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTOR) servers(servers) initializer() } @@ -75,7 +72,6 @@ class FileServersEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTOR) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip99Classifieds/ClassifiedsEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip99Classifieds/ClassifiedsEvent.kt index b3c6101375..1f890a4d07 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip99Classifieds/ClassifiedsEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip99Classifieds/ClassifiedsEvent.kt @@ -33,7 +33,6 @@ import com.vitorpamplona.quartz.nip23LongContent.tags.ImageTag import com.vitorpamplona.quartz.nip23LongContent.tags.PublishedAtTag import com.vitorpamplona.quartz.nip23LongContent.tags.SummaryTag import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nip92IMeta.imetas import com.vitorpamplona.quartz.nip99Classifieds.tags.ConditionTag @@ -110,7 +109,6 @@ class ClassifiedsEvent( companion object { const val KIND = 30402 - const val ALT_DESCRIPTION = "Classifieds listing" val REQUIRED_FIELDS = setOf(TitleTag.TAG_NAME, PriceTag.TAG_NAME, ImageTag.TAG_NAME) @@ -136,7 +134,6 @@ class ClassifiedsEvent( location?.let { location(it) } images?.let { images(images) } - alt(ALT_DESCRIPTION) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA0VoiceMessages/BaseVoiceEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA0VoiceMessages/BaseVoiceEvent.kt index 4f24892902..ed0227e58c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA0VoiceMessages/BaseVoiceEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA0VoiceMessages/BaseVoiceEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip92IMeta.imetas import com.vitorpamplona.quartz.utils.TimeUtils @@ -45,11 +44,9 @@ open class BaseVoiceEvent( fun build( voiceMessage: AudioMeta, kind: Int, - alt: String, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(kind, voiceMessage.url, createdAt) { - alt(alt) audioIMeta(voiceMessage) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA0VoiceMessages/VoiceEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA0VoiceMessages/VoiceEvent.kt index 3af6a78c32..f39df32226 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA0VoiceMessages/VoiceEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA0VoiceMessages/VoiceEvent.kt @@ -36,7 +36,6 @@ class VoiceEvent( ) : BaseVoiceEvent(id, pubKey, createdAt, KIND, tags, content, sig) { companion object { const val KIND = 1222 - const val ALT_DESCRIPTION = "Voice message" fun build( url: String, @@ -50,6 +49,6 @@ class VoiceEvent( voiceMessage: AudioMeta, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, - ) = build(voiceMessage, KIND, ALT_DESCRIPTION, createdAt, initializer) + ) = build(voiceMessage, KIND, createdAt, initializer) } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA0VoiceMessages/VoiceReplyEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA0VoiceMessages/VoiceReplyEvent.kt index f4843f10ea..102522ae66 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA0VoiceMessages/VoiceReplyEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA0VoiceMessages/VoiceReplyEvent.kt @@ -57,7 +57,6 @@ class VoiceReplyEvent( companion object { const val KIND = 1244 - const val ALT_DESCRIPTION = "Voice reply" fun build( url: String, @@ -73,7 +72,7 @@ class VoiceReplyEvent( replyingTo: EventHintBundle, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, - ) = build(voiceMessage, KIND, ALT_DESCRIPTION, createdAt) { + ) = build(voiceMessage, KIND, createdAt) { replyEvent(replyingTo.event.id, replyingTo.relay, replyingTo.event.pubKey) replyKind(replyingTo.event.kind) replyAuthor(replyingTo.event.pubKey, replyingTo.authorHomeRelay) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA4PublicMessages/PublicMessageEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA4PublicMessages/PublicMessageEvent.kt index 0c3c440769..9753d5386d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA4PublicMessages/PublicMessageEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipA4PublicMessages/PublicMessageEvent.kt @@ -38,7 +38,6 @@ import com.vitorpamplona.quartz.nip19Bech32.eventHints import com.vitorpamplona.quartz.nip19Bech32.eventIds import com.vitorpamplona.quartz.nip19Bech32.pubKeyHints import com.vitorpamplona.quartz.nip19Bech32.pubKeys -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nipA4PublicMessages.tags.ReceiverTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -93,13 +92,11 @@ class PublicMessageEvent( companion object { const val KIND = 24 - const val ALT_DESCRIPTION = "Public Message" fun build( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) initializer() remove("e") // NIP-A4: e tags must not be used } @@ -110,7 +107,6 @@ class PublicMessageEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, msg, createdAt) { - alt(ALT_DESCRIPTION) toUser(to) initializer() remove("e") // NIP-A4: e tags must not be used @@ -122,7 +118,6 @@ class PublicMessageEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, msg, createdAt) { - alt(ALT_DESCRIPTION) toGroup(to) initializer() remove("e") // NIP-A4: e tags must not be used diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallAnswerEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallAnswerEvent.kt index 553ee5ad8c..472560a311 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallAnswerEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallAnswerEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTagIds -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nipACWebRtcCalls.tags.callId @Immutable @@ -49,7 +48,6 @@ class CallAnswerEvent( companion object { const val KIND = 25051 - const val ALT_DESCRIPTION = "WebRTC call answer" fun build( sdpAnswer: String, @@ -57,7 +55,6 @@ class CallAnswerEvent( callId: String, initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, sdpAnswer) { - alt(ALT_DESCRIPTION) pTag(callerPubKey) callId(callId) initializer() @@ -69,7 +66,6 @@ class CallAnswerEvent( callId: String, initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, sdpAnswer) { - alt(ALT_DESCRIPTION) pTagIds(memberPubKeys) callId(callId) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallHangupEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallHangupEvent.kt index 6b5ae36734..49d8c887ae 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallHangupEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallHangupEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTagIds -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nipACWebRtcCalls.tags.callId @Immutable @@ -49,7 +48,6 @@ class CallHangupEvent( companion object { const val KIND = 25053 - const val ALT_DESCRIPTION = "WebRTC call hangup" fun build( peerPubKey: HexKey, @@ -57,7 +55,6 @@ class CallHangupEvent( reason: String = "", initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, reason) { - alt(ALT_DESCRIPTION) pTag(peerPubKey) callId(callId) initializer() @@ -69,7 +66,6 @@ class CallHangupEvent( reason: String = "", initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, reason) { - alt(ALT_DESCRIPTION) pTagIds(memberPubKeys) callId(callId) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallIceCandidateEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallIceCandidateEvent.kt index 76ff088c98..a7f7bde812 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallIceCandidateEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallIceCandidateEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.people.pTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nipACWebRtcCalls.tags.callId import kotlinx.serialization.json.Json import kotlinx.serialization.json.int @@ -64,7 +63,6 @@ class CallIceCandidateEvent( companion object { const val KIND = 25052 - const val ALT_DESCRIPTION = "WebRTC ICE candidate" fun serializeCandidate( sdp: String, @@ -82,7 +80,6 @@ class CallIceCandidateEvent( callId: String, initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, candidateJson) { - alt(ALT_DESCRIPTION) pTag(peerPubKey) callId(callId) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallOfferEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallOfferEvent.kt index 4356f8b316..2a1caa7813 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallOfferEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallOfferEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTagIds -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nipACWebRtcCalls.tags.CallType import com.vitorpamplona.quartz.nipACWebRtcCalls.tags.CallTypeTag import com.vitorpamplona.quartz.nipACWebRtcCalls.tags.callId @@ -60,7 +59,6 @@ class CallOfferEvent( companion object { const val KIND = 25050 - const val ALT_DESCRIPTION = "WebRTC call offer" fun build( sdpOffer: String, @@ -69,7 +67,6 @@ class CallOfferEvent( type: CallType, initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, sdpOffer) { - alt(ALT_DESCRIPTION) pTag(calleePubKey) callId(callId) callType(type) @@ -83,7 +80,6 @@ class CallOfferEvent( type: CallType, initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, sdpOffer) { - alt(ALT_DESCRIPTION) pTagIds(calleePubKeys) callId(callId) callType(type) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallRejectEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallRejectEvent.kt index 664bf923dc..8d2b0b3483 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallRejectEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallRejectEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTagIds -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nipACWebRtcCalls.tags.callId @Immutable @@ -49,7 +48,6 @@ class CallRejectEvent( companion object { const val KIND = 25054 - const val ALT_DESCRIPTION = "WebRTC call rejection" fun build( callerPubKey: HexKey, @@ -57,7 +55,6 @@ class CallRejectEvent( reason: String = "", initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, reason) { - alt(ALT_DESCRIPTION) pTag(callerPubKey) callId(callId) initializer() @@ -69,7 +66,6 @@ class CallRejectEvent( reason: String = "", initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, reason) { - alt(ALT_DESCRIPTION) pTagIds(memberPubKeys) callId(callId) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallRenegotiateEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallRenegotiateEvent.kt index df39efc94e..e57c4bd455 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallRenegotiateEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/events/CallRenegotiateEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.people.PTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTag import com.vitorpamplona.quartz.nip01Core.tags.people.pTagIds -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nipACWebRtcCalls.tags.callId @Immutable @@ -49,7 +48,6 @@ class CallRenegotiateEvent( companion object { const val KIND = 25055 - const val ALT_DESCRIPTION = "WebRTC call renegotiation" fun build( sdpOffer: String, @@ -57,7 +55,6 @@ class CallRenegotiateEvent( callId: String, initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, sdpOffer) { - alt(ALT_DESCRIPTION) pTag(peerPubKey) callId(callId) initializer() @@ -69,7 +66,6 @@ class CallRenegotiateEvent( callId: String, initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, sdpOffer) { - alt(ALT_DESCRIPTION) pTagIds(memberPubKeys) callId(callId) initializer() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipB0WebBookmarks/WebBookmarkEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipB0WebBookmarks/WebBookmarkEvent.kt index 07272bee13..a5d09d2bdd 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipB0WebBookmarks/WebBookmarkEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipB0WebBookmarks/WebBookmarkEvent.kt @@ -31,7 +31,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags import com.vitorpamplona.quartz.nip22Comments.RootScope import com.vitorpamplona.quartz.nip23LongContent.tags.PublishedAtTag import com.vitorpamplona.quartz.nip23LongContent.tags.TitleTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -63,7 +62,6 @@ class WebBookmarkEvent( companion object { const val KIND = 39701 - const val ALT_DESCRIPTION = "Web Bookmark" fun urlToDTag(url: String): String = url @@ -80,7 +78,6 @@ class WebBookmarkEvent( initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, description, createdAt) { dTag(urlToDTag(url)) - alt(ALT_DESCRIPTION) bookmarkTitle?.let { title(it) } publishedAt(createdAt) hashtags(tags) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipB7Blossom/BlossomServersEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipB7Blossom/BlossomServersEvent.kt index 2b34a31a8a..702eeb321b 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipB7Blossom/BlossomServersEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipB7Blossom/BlossomServersEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -49,7 +48,6 @@ class BlossomServersEvent( companion object { const val KIND = 10063 - const val ALT = "File servers used by the author" fun createAddress(pubKey: HexKey): Address = Address(KIND, pubKey, FIXED_D_TAG) @@ -60,7 +58,6 @@ class BlossomServersEvent( fun createTagArray(servers: List): Array> = servers .map { arrayOf("server", it) } - .plusElement(AltTag.assemble(ALT)) .toTypedArray() suspend fun updateRelayList( diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipBCOnchainZaps/zap/OnchainZapEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipBCOnchainZaps/zap/OnchainZapEvent.kt index 2dfebe2a6c..4c7f660d42 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipBCOnchainZaps/zap/OnchainZapEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipBCOnchainZaps/zap/OnchainZapEvent.kt @@ -35,7 +35,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.aTag.toATag import com.vitorpamplona.quartz.nip01Core.tags.events.ETag import com.vitorpamplona.quartz.nip01Core.tags.events.toETag import com.vitorpamplona.quartz.nip01Core.tags.people.PTag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -103,9 +102,6 @@ class OnchainZapEvent( companion object { const val KIND = 8333 - /** NIP-31 human-readable fallback. Includes the amount, as in the NIP-BC example. */ - fun altDescription(amountInSats: Long) = "Onchain zap: $amountInSats sats" - /** * Build an onchain zap that targets a specific event. */ @@ -118,7 +114,6 @@ class OnchainZapEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, content, createdAt) { - alt(altDescription(amountInSats)) txid(txid) recipient(recipientPubKey) amountInSats(amountInSats) @@ -141,7 +136,6 @@ class OnchainZapEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, content, createdAt) { - alt(altDescription(amountInSats)) txid(txid) recipient(recipientPubKey) amountInSats(amountInSats) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipC0CodeSnippets/CodeSnippetEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipC0CodeSnippets/CodeSnippetEvent.kt index 9c07eeb531..96675a8330 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipC0CodeSnippets/CodeSnippetEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipC0CodeSnippets/CodeSnippetEvent.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip22Comments.RootScope -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -74,7 +73,6 @@ class CodeSnippetEvent( companion object { const val KIND = 1337 - const val ALT_DESCRIPTION = "Code snippet" fun build( code: String, @@ -89,7 +87,6 @@ class CodeSnippetEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, code, createdAt) { - alt(ALT_DESCRIPTION) language?.let { language(it) } extension?.let { extension(it) } name?.let { snippetName(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipC7Chats/ChatEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipC7Chats/ChatEvent.kt index 523b032fd1..50280faa69 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipC7Chats/ChatEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipC7Chats/ChatEvent.kt @@ -39,7 +39,6 @@ import com.vitorpamplona.quartz.nip19Bech32.eventIds import com.vitorpamplona.quartz.nip19Bech32.pubKeyHints import com.vitorpamplona.quartz.nip19Bech32.pubKeys import com.vitorpamplona.quartz.nip22Comments.RootScope -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.utils.TimeUtils @@ -88,14 +87,12 @@ class ChatEvent( companion object { const val KIND = 9 - const val ALT_DESCRIPTION = "Chat message" fun build( message: String, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, message, createdAt) { - alt(ALT_DESCRIPTION) initializer() } @@ -105,7 +102,6 @@ class ChatEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, message, createdAt) { - alt(ALT_DESCRIPTION) quote(QEventTag(replyTo.event.id, replyTo.relay, replyTo.event.pubKey)) initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/authored/AuthoredPodcastsEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/authored/AuthoredPodcastsEvent.kt index abf626b368..efa3c555df 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/authored/AuthoredPodcastsEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/authored/AuthoredPodcastsEvent.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.muteList.tags.UserTag import com.vitorpamplona.quartz.utils.TimeUtils @@ -61,7 +60,6 @@ class AuthoredPodcastsEvent( companion object { const val KIND = 10064 - const val ALT_DESCRIPTION = "List of authored podcasts" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, FIXED_D_TAG) @@ -72,7 +70,6 @@ class AuthoredPodcastsEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) podcasts.forEach { podcast(it) } initializer() } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/episode/PodcastEpisodeEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/episode/PodcastEpisodeEvent.kt index 107ed9435d..183f2702bf 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/episode/PodcastEpisodeEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/episode/PodcastEpisodeEvent.kt @@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nipF4Podcasts.episode.tags.AudioTag import com.vitorpamplona.quartz.nipF4Podcasts.episode.tags.DescriptionTag @@ -62,7 +61,6 @@ class PodcastEpisodeEvent( companion object { const val KIND = 54 - const val ALT_DESCRIPTION_PREFIX = "Podcast episode" fun build( title: String, @@ -73,8 +71,6 @@ class PodcastEpisodeEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, markdownContent, createdAt) { - alt("$ALT_DESCRIPTION_PREFIX: $title") - title(title) description(description) image?.let { image(it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/favorites/FavoritePodcastsListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/favorites/FavoritePodcastsListEvent.kt index e492348c9f..aaf72d3ab6 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/favorites/FavoritePodcastsListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/favorites/FavoritePodcastsListEvent.kt @@ -24,10 +24,8 @@ import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArray -import com.vitorpamplona.quartz.nip01Core.core.fastAny import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions -import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.muteList.tags.UserTag @@ -58,7 +56,6 @@ class FavoritePodcastsListEvent( companion object { const val KIND = 10054 - const val ALT = "Favorite podcasts list" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, "") @@ -157,14 +154,6 @@ class FavoritePodcastsListEvent( tags: TagArray, signer: NostrSigner, createdAt: Long = TimeUtils.now(), - ): FavoritePodcastsListEvent { - val newTags = - if (tags.fastAny(AltTag::match)) { - tags - } else { - tags + AltTag.assemble(ALT) - } - return signer.sign(createdAt, KIND, newTags, content) - } + ): FavoritePodcastsListEvent = signer.sign(createdAt, KIND, tags, content) } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/metadata/PodcastMetadataEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/metadata/PodcastMetadataEvent.kt index 8a9bdccabc..42874c0747 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/metadata/PodcastMetadataEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/metadata/PodcastMetadataEvent.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag -import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip50Search.SearchableEvent import com.vitorpamplona.quartz.nipF4Podcasts.metadata.tags.AuthorTag import com.vitorpamplona.quartz.nipF4Podcasts.metadata.tags.DescriptionTag @@ -76,7 +75,6 @@ class PodcastMetadataEvent( companion object { const val KIND = 10154 - const val ALT_DESCRIPTION = "Podcast metadata" fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, FIXED_D_TAG) @@ -91,8 +89,6 @@ class PodcastMetadataEvent( createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { - alt(ALT_DESCRIPTION) - title(title) image(image) description(description) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/EventFactory.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/EventFactory.kt index 9c66762853..c3871af281 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/EventFactory.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/EventFactory.kt @@ -36,6 +36,7 @@ import com.vitorpamplona.quartz.experimental.clink.offers.OfferEvent import com.vitorpamplona.quartz.experimental.edits.TextNoteModificationEvent import com.vitorpamplona.quartz.experimental.ephemChat.chat.EphemeralChatEvent import com.vitorpamplona.quartz.experimental.ephemChat.list.EphemeralChatListEvent +import com.vitorpamplona.quartz.experimental.fitness.workout.ExerciseTemplateEvent import com.vitorpamplona.quartz.experimental.fitness.workout.WorkoutRecordEvent import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryReadingStateEvent @@ -618,6 +619,7 @@ class EventFactory { WebBookmarkEvent.KIND -> WebBookmarkEvent(id, pubKey, createdAt, tags, content, sig) WikiNoteEvent.KIND -> WikiNoteEvent(id, pubKey, createdAt, tags, content, sig) WorkoutRecordEvent.KIND -> WorkoutRecordEvent(id, pubKey, createdAt, tags, content, sig) + ExerciseTemplateEvent.KIND -> ExerciseTemplateEvent(id, pubKey, createdAt, tags, content, sig) else -> factories[kind]?.build(id, pubKey, createdAt, tags, content, sig) ?: Event(id, pubKey, createdAt, kind, tags, content, sig) } as T diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UrlDetector.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UrlDetector.kt index 7915ec9ed8..cf2e8a5f4c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UrlDetector.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UrlDetector.kt @@ -649,8 +649,11 @@ class UrlDetector( // if the url is valid and greater then 0 if (state == ReadEndState.ValidUrl && buffer.isNotEmpty()) { var url = buffer.toString() - if (url.lastOrNull() in CANNOT_END_URLS_WITH) url = url.dropLast(1) - urlList.add(currentUrlMarker.createUrl(url)) + val last = url.lastOrNull() + if (last != null && last in CANNOT_END_URLS_WITH && !url.endsOnBalancedCloser(last)) { + url = url.dropLast(1) + } + if (url.isNotEmpty()) urlList.add(currentUrlMarker.createUrl(url)) } // clear out the buffer. @@ -667,6 +670,37 @@ class UrlDetector( return state == ReadEndState.ValidUrl } + /** + * Decides whether a trailing closing delimiter ([last]) should be kept as part of the URL. + * + * Closing parenthesis, braces and brackets are common inside real URLs (e.g. Wikipedia's + * `…/Bitcoin_(disambiguation)`), so we keep a trailing closer when the URL also contains its + * matching opener — i.e. the delimiters are balanced. When the closer is unbalanced it is + * almost always wrapping/sentence punctuation (e.g. `(see example.com)` or `http://test.com)`) + * and is stripped. Any opening delimiter or other punctuation is never balanced, so it falls + * through to the normal trailing strip. + */ + private fun String.endsOnBalancedCloser(last: Char): Boolean { + val opener = + when (last) { + ')' -> '(' + '}' -> '{' + ']' -> '[' + else -> return false + } + + var depth = 0 + for (c in this) { + if (c == opener) { + depth++ + } else if (c == last) { + depth-- + } + } + // depth >= 0 means every closer (including the trailing one) has a matching opener. + return depth >= 0 + } + companion object { val VALID_SCHEMES_NO_SLASHES: List = listOf( @@ -694,6 +728,7 @@ class UrlDetector( '!', ')', '}', + ']', '(', '{', '\u3002', @@ -711,6 +746,7 @@ class UrlDetector( ':', ')', '}', + ']', '(', '{', '\u3002', diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/experimental/fitness/WorkoutRecordEventTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/experimental/fitness/WorkoutRecordEventTest.kt index 581052ce34..3c69e15539 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/experimental/fitness/WorkoutRecordEventTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/experimental/fitness/WorkoutRecordEventTest.kt @@ -20,9 +20,11 @@ */ package com.vitorpamplona.quartz.experimental.fitness +import com.vitorpamplona.quartz.experimental.fitness.workout.ExerciseTemplateEvent import com.vitorpamplona.quartz.experimental.fitness.workout.WorkoutRecordEvent import com.vitorpamplona.quartz.experimental.fitness.workout.calories import com.vitorpamplona.quartz.experimental.fitness.workout.distance +import com.vitorpamplona.quartz.experimental.fitness.workout.slugToTitle import com.vitorpamplona.quartz.experimental.fitness.workout.source import com.vitorpamplona.quartz.experimental.fitness.workout.tags.DurationTag import com.vitorpamplona.quartz.experimental.fitness.workout.tags.ExerciseType @@ -134,6 +136,130 @@ class WorkoutRecordEventTest { assertNull(event.distance()) } + /** Tag layout as published by POWR (NIP-101e strength dialect: per-set `exercise` coordinates). */ + @Test + fun parsesPowrDialect() { + val coord = "33401:0bdd91e8a30d87d041eafd1871f17d426fa415c69a9a822eccad49017bac59e7:back-squat-bb" + val relay = "wss://relay.powr.build" + val event = + parse( + arrayOf( + arrayOf("title", "Novice Hypertrophy — Day 2"), + arrayOf("type", "strength"), + arrayOf("start", "1781969106"), + arrayOf("end", "1781972319"), + arrayOf("completed", "true"), + arrayOf("template", "33402:0bdd91e8a30d87d041eafd1871f17d426fa415c69a9a822eccad49017bac59e7:novice-hyp-day2-lower-a", relay), + arrayOf("exercise", coord, relay, "84", "8", "8", "normal", "1"), + arrayOf("exercise", coord, relay, "84", "8", "8", "normal", "2"), + arrayOf("exercise", coord, relay, "84", "8", "9", "normal", "3"), + arrayOf("exercise", "33401:0bdd91e8a30d87d041eafd1871f17d426fa415c69a9a822eccad49017bac59e7:seated-calf-raise-machine", relay, "", "8", "", "normal", "1"), + arrayOf("client", "POWR"), + ), + ) as WorkoutRecordEvent + + // The activity type now comes from the `type` tag, not the coordinate-form `exercise` tag. + assertEquals(ExerciseType.STRENGTH, event.workoutType()) + assertEquals(ExerciseType.STRENGTH, event.activityType()) + assertNull(event.exercise()) // must not surface "33401:..." as a verb + assertNull(event.exerciseType()) + + assertEquals("Novice Hypertrophy — Day 2", event.title()) + assertEquals(1781969106L, event.workoutStart()) + assertEquals(1781972319L, event.workoutEnd()) + assertEquals(true, event.workoutCompleted()) + assertEquals("POWR", event.client()) + + // No `duration` tag: derived from start/end. + assertEquals(1781972319L - 1781969106L, event.effectiveDurationSeconds()) + + val sets = event.exerciseSets() + assertEquals(4, sets.size) + assertEquals(84.0, sets[0].weightKg) + assertEquals(8, sets[0].reps) + assertEquals(8.0, sets[0].rpe) + assertEquals("normal", sets[0].setType) + assertEquals(1, sets[0].setNumber) + assertEquals("back-squat-bb", sets[0].dTag()) + // Bodyweight / machine set leaves weight empty. + assertNull(sets[3].weightKg) + assertEquals(8, sets[3].reps) + + val groups = event.exerciseGroups() + assertEquals(2, groups.size) + assertEquals("Back Squat Bb", groups[0].displayName()) + assertEquals(3, groups[0].sets.size) + assertEquals(84.0 * 8 * 3, groups[0].totalVolumeKg()) // 3 sets of 8 reps @ 84 kg (the 9 is RPE) + assertEquals(84.0, groups[0].topWeightKg()) + assertEquals("Seated Calf Raise Machine", groups[1].displayName()) + assertNull(groups[1].totalVolumeKg()) // no weights logged + } + + @Test + fun exposesPowrTemplateReferencesAsHints() { + val backSquat = "33401:0bdd91e8a30d87d041eafd1871f17d426fa415c69a9a822eccad49017bac59e7:back-squat-bb" + val deadlift = "33401:0bdd91e8a30d87d041eafd1871f17d426fa415c69a9a822eccad49017bac59e7:deadlift-bb" + val template = "33402:0bdd91e8a30d87d041eafd1871f17d426fa415c69a9a822eccad49017bac59e7:novice-hyp-day2-lower-a" + val relay = "wss://relay.powr.build" + val event = + parse( + arrayOf( + arrayOf("type", "strength"), + arrayOf("template", template, relay), + arrayOf("exercise", backSquat, relay, "84", "8", "8", "normal", "1"), + arrayOf("exercise", backSquat, relay, "84", "8", "8", "normal", "2"), + arrayOf("exercise", deadlift, relay, "100", "5", "8", "normal", "1"), + ), + ) as WorkoutRecordEvent + + // Each referenced template is exposed once for fetching (deduped), incl. the 33402 template. + val linked = event.linkedAddressIds() + assertEquals(setOf(backSquat, deadlift, template), linked.toSet()) + assertEquals(3, linked.size) + + // Relay hints let Amethyst fetch the templates from where POWR published them. + val hints = event.addressHints() + assertEquals(setOf(backSquat, deadlift, template), hints.map { it.addressId }.toSet()) + assertTrue(hints.all { it.relay.url == "wss://relay.powr.build/" }) + } + + @Test + fun parsesExerciseTemplate() { + val event: Event = + EventFactory.create( + id = "a".repeat(64), + pubKey = "b".repeat(64), + createdAt = 1718000000L, + kind = ExerciseTemplateEvent.KIND, + tags = + arrayOf( + arrayOf("d", "back-squat-bb"), + arrayOf("title", "Back Squat (Barbell)"), + arrayOf("format", "weight", "reps", "rpe", "set_type"), + arrayOf("format_units", "kg", "count", "0-10", "enum"), + arrayOf("equipment", "barbell"), + arrayOf("difficulty", "intermediate"), + ), + content = "Keep a neutral spine.", + sig = "c".repeat(128), + ) + + assertTrue(event is ExerciseTemplateEvent) + assertEquals("back-squat-bb", event.dTag()) + assertEquals("Back Squat (Barbell)", event.title()) + assertEquals(listOf("weight", "reps", "rpe", "set_type"), event.format()) + assertEquals(listOf("kg", "count", "0-10", "enum"), event.formatUnits()) + assertEquals("barbell", event.equipment()) + assertEquals("intermediate", event.difficulty()) + } + + @Test + fun slugToTitlePrettifiesDTags() { + assertEquals("Back Squat Bb", slugToTitle("back-squat-bb")) + assertEquals("Seated Calf Raise Machine", slugToTitle("seated-calf-raise-machine")) + assertEquals("Deadlift", slugToTitle("deadlift")) + } + @Test fun durationFormatsAsPaddedTime() { assertEquals("00:31:30", DurationTag.formatTime(31 * 60 + 30L)) diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/experimental/roadstr/RoadEventTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/experimental/roadstr/RoadEventTest.kt index fd66eeb1d2..6a19958d20 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/experimental/roadstr/RoadEventTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/experimental/roadstr/RoadEventTest.kt @@ -152,7 +152,6 @@ class RoadEventTest { assertEquals("48.8566140", template.tags.first { it[0] == "lat" }[1]) assertEquals("2.3522219", template.tags.first { it[0] == "lon" }[1]) assertEquals((createdAt + RoadEventReportEvent.RELAY_TTL_SECONDS).toString(), template.tags.first { it[0] == "expiration" }[1]) - assertEquals("Roadstr: speed_camera report", template.tags.first { it[0] == "alt" }[1]) } @Test @@ -161,7 +160,6 @@ class RoadEventTest { assertEquals(reportId, template.tags.first { it[0] == "e" }[1]) assertEquals("still_there", template.tags.first { it[0] == "status" }[1]) - assertEquals("Roadstr: event confirmed", template.tags.first { it[0] == "alt" }[1]) assertTrue(template.tags.none { it[0] == "g" || it[0] == "lat" || it[0] == "lon" }) } diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/metadata/UpdateMetadataTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/metadata/UpdateMetadataTest.kt index 86aa586878..ac7e123165 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/metadata/UpdateMetadataTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/metadata/UpdateMetadataTest.kt @@ -53,16 +53,15 @@ class UpdateMetadataTest { val expected = MetadataEvent( - id = "490d7439e530423f2540d4f2bdb73a0a2935f3df9e1f2a6f699a140c7db311fe", + id = "b7a00acbc8e07b1a555eb0b50b515b54525f129f612b6dc8e3225a2184e79e03", pubKey = "70a9b3c312a6b83e476739bd29d60ca700da1d5b982cbca87b5f3d27d4038d67", createdAt = 1740669816, tags = arrayOf( - arrayOf("alt", "User profile for Vitor"), arrayOf("name", "Vitor"), ), content = "{\"name\":\"Vitor\"}", - sig = "977a6152199f17d103d8d56736ed1b7767054464cf9423d017c01c8cdd2344698f0a5e13da8dff98d01bb1f798837e3b6271e1fd1cac861bb90686f622ae6ef4", + sig = "fcb319f3f4ac616d14186a018b40d554f4614bfdddc15079be7027d2059d6cd76d12f0f2ac4fd0ca3694b95ec66b786d6503e350249e9d35d2caa0c39e77fc0a", ) assertEquals(expected, test) @@ -90,12 +89,11 @@ class UpdateMetadataTest { val expected = MetadataEvent( - id = "2b2761d66db4a83d5fb7a98cafb8414e9b0c238ceb67d729bedacc1a092d516f", + id = "e09f5a9f0005bc427ac0c1714c7c239ecb7f2454c8b29c2c5046477c5d945c6c", pubKey = "70a9b3c312a6b83e476739bd29d60ca700da1d5b982cbca87b5f3d27d4038d67", createdAt = 1740669816, tags = arrayOf( - arrayOf("alt", "User profile for Vitor"), arrayOf("name", "Vitor"), arrayOf("display_name", "Vitor Pamplona"), arrayOf("picture", "https://vitorpamplona.com/images/me_300.jpg"), @@ -109,19 +107,18 @@ class UpdateMetadataTest { arrayOf("i", "github:vitorpamplona", "cf19e2d1d7f8dac6348ad37b35ec8421"), ), content = "{\"name\":\"Vitor\",\"display_name\":\"Vitor Pamplona\",\"picture\":\"https://vitorpamplona.com/images/me_300.jpg\",\"banner\":\"https://pbs.twimg.com/profile_banners/15064756/1414451651/1080x360\",\"website\":\"https://vitorpamplona.com\",\"pronouns\":\"he/him\",\"about\":\"Nostr's Chief Android Officer - #Amethyst\",\"nip05\":\"_@vitorpamplona.com\",\"lud16\":\"vitor@vitorpamplona.com\",\"lud06\":\"TEST\"}", - sig = "0a8c78eb0c5e0ba46e4781cc445fb7b6d275b434cead9231bd19b4f95671e3ab872264e50d4456d6036a84cc81e517bfa24229571519aabefcbce431e0c7163e", + sig = "dddbe96bd6217bb3fce33f6766cc989b300d7e867aa57bdcfc7c9ad915e165ecc76c193770f215728e7e1f59d667a16365f081d1089be27938f40e69c682e623", ) assertEquals(expected, test) val expected2 = MetadataEvent( - id = "2e1e57fae4e4baddac025ea0b49afc093f2aa27610a05e584184ed26b29d7590", + id = "58c85c5a5183fcb017be943f83f92dc714b5595078f009afa0b5241ee27e8946", pubKey = "70a9b3c312a6b83e476739bd29d60ca700da1d5b982cbca87b5f3d27d4038d67", createdAt = 1740669817, tags = arrayOf( - arrayOf("alt", "User profile for 2 Vitor"), arrayOf("name", "2 Vitor"), arrayOf("display_name", "2 Vitor Pamplona"), arrayOf("picture", "2 https://vitorpamplona.com/images/me_300.jpg"), @@ -135,7 +132,7 @@ class UpdateMetadataTest { arrayOf("i", "github:vitorpamplona", "2cf19e2d1d7f8dac6348ad37b35ec8421"), ), content = "{\"name\":\"2 Vitor\",\"display_name\":\"2 Vitor Pamplona\",\"picture\":\"2 https://vitorpamplona.com/images/me_300.jpg\",\"banner\":\"2 https://pbs.twimg.com/profile_banners/15064756/1414451651/1080x360\",\"website\":\"2 https://vitorpamplona.com\",\"pronouns\":\"2 he/him\",\"about\":\"2 Nostr's Chief Android Officer - #Amethyst\",\"nip05\":\"2 _@vitorpamplona.com\",\"lud16\":\"2 vitor@vitorpamplona.com\",\"lud06\":\"2 TEST\"}", - sig = "a25483bc0fcc79ccd337e3ff846351097109fc13f1cd1c9cc15f7f2ad46417aeb7c05c1524aeadbab93036fc0743c8c310a5b2b7b482e1808649b12a3ee29d49", + sig = "162b7a369bb84070c20a2ed5733a5c4519b3c4d1b0c89042448fe16d3f201e42ed60eb544fa8f83c8b0eed73a4dc51a39267c29e3b0d2c05b713c81157662db0", ) val test2 = @@ -161,18 +158,17 @@ class UpdateMetadataTest { val expected3 = MetadataEvent( - id = "94879b9a27fecf1337ede32013006ec4dfd5a3286a1e819abddfa1c3c132f008", + id = "75488fae3320aebf9af573d5a43b406c3eb93511e484e2db0a348408c0cce42d", pubKey = "70a9b3c312a6b83e476739bd29d60ca700da1d5b982cbca87b5f3d27d4038d67", createdAt = 1740669817, tags = arrayOf( - arrayOf("alt", "User profile for 2 Vitor"), arrayOf("name", "2 Vitor"), arrayOf("picture", "2 https://vitorpamplona.com/images/me_300.jpg"), arrayOf("banner", "2 https://pbs.twimg.com/profile_banners/15064756/1414451651/1080x360"), ), content = "{\"name\":\"2 Vitor\",\"picture\":\"2 https://vitorpamplona.com/images/me_300.jpg\",\"banner\":\"2 https://pbs.twimg.com/profile_banners/15064756/1414451651/1080x360\"}", - sig = "729ee02364b4d429b6a66400ec850e80424602e3981ff2ad8a14d61bdee04f76ec68ddc4a0f38b0527f0218f7fa67668012a5c0f3c8ef943517b504040caa07e", + sig = "775f6a90c7152632b10c4d20779d9648fd8fec45966add84ef721e58d355ce5c5e1f48b81f334c1b31236c6afe076f51e191f1cf58819c62b6fd64cae04ef01a", ) val test3 = diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip10Notes/AltTagSurrogateTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip10Notes/AltTagSurrogateTest.kt deleted file mode 100644 index 848c6094c9..0000000000 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip10Notes/AltTagSurrogateTest.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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.quartz.nip10Notes - -import com.vitorpamplona.quartz.nip31Alts.AltTag -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertTrue - -class AltTagSurrogateTest { - // The summarizer truncates the note to 50 UTF-16 units for the NIP-31 "alt" - // tag. In this note the 50th unit falls between the two halves of the - // saluting-face emoji (🫡, U+1FAE1 = surrogate pair D83E DEE1), so a naive - // take(50) used to leave a lone high surrogate at the end of the alt tag. - // - // A lone surrogate is unencodable as UTF-8: it is kept in memory while the - // event id is hashed (so the signature is over that id), but it is replaced - // by '?' the moment the event is serialized to the relay. Relays therefore - // recompute a different id and reject the event as having an invalid id. - private val note = - "I had to toggle a setting in fit 👍 That's slick 🫡\n" + - "https://haven.downisontheup.ca/b598bd967080491578db15cb861ebacdfd056a6ba9e0701190444b183380933b.jpg" - - private fun altOf(note: String): String = TextNoteEvent.build(note).tags.firstNotNullOfOrNull(AltTag::parse)!! - - @Test - fun altTagHasNoLoneSurrogate() { - val alt = altOf(note) - val loneSurrogate = - alt.indices.any { i -> - val c = alt[i] - when { - c.isHighSurrogate() -> i + 1 >= alt.length || !alt[i + 1].isLowSurrogate() - c.isLowSurrogate() -> i == 0 || !alt[i - 1].isHighSurrogate() - else -> false - } - } - assertTrue(!loneSurrogate, "alt tag must not contain a lone surrogate: <$alt>") - } - - @Test - fun altTagSurvivesUtf8WireRoundTrip() { - // Models the UTF-8 encode the relay transport performs. A lone surrogate - // would be replaced (and the round-trip would differ), which is exactly - // what corrupted the event id. - val alt = altOf(note) - assertEquals(alt, alt.encodeToByteArray().decodeToString()) - } -} diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip30CustomEmoji/EmojiPackEventBuildTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip30CustomEmoji/EmojiPackEventBuildTest.kt index bf8f04c8e7..cd149c97ea 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip30CustomEmoji/EmojiPackEventBuildTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip30CustomEmoji/EmojiPackEventBuildTest.kt @@ -25,11 +25,12 @@ import com.vitorpamplona.quartz.nip30CustomEmoji.pack.description import com.vitorpamplona.quartz.nip30CustomEmoji.pack.image import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertFalse import kotlin.test.assertTrue class EmojiPackEventBuildTest { @Test - fun buildIncludesTitleDTagAltAndEmojis() { + fun buildIncludesTitleDTagAndEmojis() { val template = EmojiPackEvent.build(name = "My Pack", dTag = "my-pack") { description("A test pack") @@ -49,7 +50,7 @@ class EmojiPackEventBuildTest { assertEquals("A test pack", tagsByName["description"]!!.first()[1]) assertTrue(tagsByName.containsKey("image")) assertEquals("https://example.com/cover.jpg", tagsByName["image"]!!.first()[1]) - assertTrue(tagsByName.containsKey("alt")) + assertFalse(tagsByName.containsKey("alt")) assertTrue(tagsByName.containsKey("emoji")) assertEquals("smile", tagsByName["emoji"]!!.first()[1]) assertEquals("https://example.com/smile.png", tagsByName["emoji"]!!.first()[2]) diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/meetingSpaces/MeetingSpaceEventBuildTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/meetingSpaces/MeetingSpaceEventBuildTest.kt index 1b643f5ba8..85acb24e8d 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/meetingSpaces/MeetingSpaceEventBuildTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/meetingSpaces/MeetingSpaceEventBuildTest.kt @@ -58,7 +58,6 @@ class MeetingSpaceEventBuildTest { assertEquals("https://api.example.com/hall", byName["streaming"]?.single()?.get(1)) assertEquals("The big room", byName["summary"]?.single()?.get(1)) assertEquals("https://example.com/hall.png", byName["image"]?.single()?.get(1)) - assertEquals(MeetingSpaceEvent.ALT, byName["alt"]?.single()?.get(1)) val hostTag = byName["p"]?.single() assertNotNull(hostTag) @@ -93,7 +92,6 @@ class MeetingSpaceEventBuildTest { assertEquals("planned", byName["status"]?.single()?.get(1)) assertEquals("10", byName["current_participants"]?.single()?.get(1)) assertEquals("100", byName["total_participants"]?.single()?.get(1)) - assertEquals(MeetingRoomEvent.ALT, byName["alt"]?.single()?.get(1)) val aTag = byName["a"]?.single() assertNotNull(aTag) diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/streaming/LiveActivitiesEventBuildTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/streaming/LiveActivitiesEventBuildTest.kt index 83731fc9f4..cc3cc61aa4 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/streaming/LiveActivitiesEventBuildTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip53LiveActivities/streaming/LiveActivitiesEventBuildTest.kt @@ -61,7 +61,6 @@ class LiveActivitiesEventBuildTest { assertEquals("live", tagsByName["status"]?.single()?.get(1)) assertEquals("42", tagsByName["current_participants"]?.single()?.get(1)) assertEquals("100", tagsByName["total_participants"]?.single()?.get(1)) - assertEquals(LiveActivitiesEvent.ALT, tagsByName["alt"]?.single()?.get(1)) // Per NIP-53, role lives at index 3 of the p-tag; a missing relay must be // represented as an empty string placeholder, not dropped. diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip64Chess/ChessGameEventTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip64Chess/ChessGameEventTest.kt index a52602ca6d..0528130e61 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip64Chess/ChessGameEventTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip64Chess/ChessGameEventTest.kt @@ -202,11 +202,6 @@ class ChessGameEventTest { assertEquals(formattedPGN, testEvent.pgn()) } - @Test - fun `default alt text is Chess Game`() { - assertEquals("Chess Game", ChessGameEvent.ALT_DESCRIPTION) - } - @Test fun `event inherits from Event base class`() { val testEvent = diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/clientTag/IsClientTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/clientTag/IsClientTest.kt new file mode 100644 index 0000000000..6c366541b4 --- /dev/null +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip89AppHandlers/clientTag/IsClientTest.kt @@ -0,0 +1,63 @@ +/* + * 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.quartz.nip89AppHandlers.clientTag + +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class IsClientTest { + @Test + fun matchesClientTagByName() { + val tags = arrayOf(arrayOf("client", "Amethyst")) + assertTrue(tags.isClient("Amethyst")) + } + + @Test + fun matchesIgnoringCase() { + val tags = arrayOf(arrayOf("client", "amethyst")) + assertTrue(tags.isClient("Amethyst")) + } + + @Test + fun matchesWithAddressAndRelayHint() { + val tags = arrayOf(arrayOf("client", "Amethyst", "31990:abc123:amethyst", "wss://relay.example.com")) + assertTrue(tags.isClient("Amethyst")) + } + + @Test + fun doesNotMatchDifferentClient() { + val tags = arrayOf(arrayOf("client", "OtherClient")) + assertFalse(tags.isClient("Amethyst")) + } + + @Test + fun doesNotMatchWhenNoClientTag() { + val tags = arrayOf(arrayOf("e", "abc"), arrayOf("p", "def")) + assertFalse(tags.isClient("Amethyst")) + } + + @Test + fun doesNotMatchEmptyClientName() { + val tags = arrayOf(arrayOf("client", "")) + assertFalse(tags.isClient("Amethyst")) + } +} diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipA4PublicMessages/PublicMessageEventTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipA4PublicMessages/PublicMessageEventTest.kt index 8fd9bcbfab..b2202b0185 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipA4PublicMessages/PublicMessageEventTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipA4PublicMessages/PublicMessageEventTest.kt @@ -44,11 +44,6 @@ class PublicMessageEventTest { assertEquals(24, PublicMessageEvent.KIND) } - @Test - fun `verify alt description`() { - assertEquals("Public Message", PublicMessageEvent.ALT_DESCRIPTION) - } - @Test fun `build with single receiver`() { val receiver = ReceiverTag(receiverPubKey, null) @@ -58,7 +53,6 @@ class PublicMessageEventTest { assertEquals(24, event.kind) assertEquals("Hello!", event.content) assertTrue(event.tags.any { it[0] == "p" && it[1] == receiverPubKey }) - assertTrue(event.tags.any { it[0] == "alt" && it[1] == "Public Message" }) } @Test diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/NipACStateMachineTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/NipACStateMachineTest.kt index c6a0b87ac5..028134d773 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/NipACStateMachineTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipACWebRtcCalls/NipACStateMachineTest.kt @@ -81,9 +81,6 @@ class NipACStateMachineTest { val callTypeTag = template.tags.firstOrNull { it[0] == "call-type" } assertNotNull(callTypeTag, "Call offer MUST include call-type tag") assertEquals("video", callTypeTag[1]) - - val altTag = template.tags.firstOrNull { it[0] == "alt" } - assertNotNull(altTag, "Call offer MUST include alt tag (NIP-31)") } @Test @@ -94,7 +91,6 @@ class NipACStateMachineTest { assertNotNull(template.tags.firstOrNull { it[0] == "p" }, "Call answer MUST include p tag") assertNotNull(template.tags.firstOrNull { it[0] == "call-id" }, "Call answer MUST include call-id tag") - assertNotNull(template.tags.firstOrNull { it[0] == "alt" }, "Call answer MUST include alt tag") } @Test @@ -113,7 +109,6 @@ class NipACStateMachineTest { assertNotNull(template.tags.firstOrNull { it[0] == "p" }) assertNotNull(template.tags.firstOrNull { it[0] == "call-id" }) - assertNotNull(template.tags.firstOrNull { it[0] == "alt" }) } @Test diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipBCOnchainZaps/zap/OnchainZapEventTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipBCOnchainZaps/zap/OnchainZapEventTest.kt index 6919e20b53..598e3821ec 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipBCOnchainZaps/zap/OnchainZapEventTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipBCOnchainZaps/zap/OnchainZapEventTest.kt @@ -45,7 +45,6 @@ class OnchainZapEventTest { val tags = template.tags // Required NIP-BC tags, exact values. - assertEquals(listOf("alt", "Onchain zap: 25000 sats"), tags.tag("alt")?.toList()) assertEquals(listOf("i", "bitcoin:tx:$txid"), tags.tag("i")?.toList()) assertEquals(listOf("p", recipient), tags.tag("p")?.toList()) assertEquals(listOf("amount", "25000"), tags.tag("amount")?.toList()) @@ -75,7 +74,6 @@ class OnchainZapEventTest { assertEquals(listOf("i", "bitcoin:tx:$txid"), tags.tag("i")?.toList()) assertEquals(listOf("p", recipient), tags.tag("p")?.toList()) assertEquals(listOf("amount", "21000"), tags.tag("amount")?.toList()) - assertEquals("Onchain zap: 21000 sats", tags.tag("alt")?.get(1)) // The zapped event is referenced by an `e` tag and its kind by a `k` tag. val eTag = tags.tag("e") diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/FavoritePodcastsListEventTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/FavoritePodcastsListEventTest.kt index 98a3570f3e..529e51a24c 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/FavoritePodcastsListEventTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/FavoritePodcastsListEventTest.kt @@ -195,17 +195,4 @@ class FavoritePodcastsListEventTest { assertEquals(listOf(podcast2), second.publicFavorites().map { it.pubKey }) } - - @Test - fun `alt tag is always present`() = - runTest { - val event = - FavoritePodcastsListEvent.create( - publicFavorites = listOf(UserTag(podcast1)), - signer = signer, - createdAt = 1_700_000_000, - ) - - assertTrue(event.tags.any { it[0] == "alt" && it[1] == FavoritePodcastsListEvent.ALT }) - } } diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/PodcastEpisodeEventTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/PodcastEpisodeEventTest.kt index e841e19c7a..4de0180f55 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/PodcastEpisodeEventTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/PodcastEpisodeEventTest.kt @@ -27,7 +27,6 @@ import com.vitorpamplona.quartz.utils.nsecToKeyPair import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNull -import kotlin.test.assertTrue class PodcastEpisodeEventTest { private val signer = @@ -98,19 +97,4 @@ class PodcastEpisodeEventTest { assertEquals("audio/opus", audios[1].mediaType) assertNull(audios[2].mediaType) } - - @Test - fun `alt tag includes title`() { - val template = - PodcastEpisodeEvent.build( - title = "Ep Title", - description = "x", - audios = listOf(AudioTag("https://example.com/x.mp3")), - ) - val event = signer.sign(template) - - val alt = event.tags.first { it[0] == "alt" } - assertTrue(alt[1].endsWith("Ep Title")) - assertTrue(alt[1].startsWith(PodcastEpisodeEvent.ALT_DESCRIPTION_PREFIX)) - } } diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/PodcastMetadataEventTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/PodcastMetadataEventTest.kt index 1d9bd5bf91..728ab884ab 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/PodcastMetadataEventTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipF4Podcasts/PodcastMetadataEventTest.kt @@ -106,19 +106,6 @@ class PodcastMetadataEventTest { assertNull(authors[0].role) } - @Test - fun `alt tag is emitted`() { - val template = - PodcastMetadataEvent.build( - title = "Show", - image = "https://example.com/cover.png", - description = "Desc", - ) - val event = signer.sign(template) - - assertTrue(event.tags.any { it[0] == "alt" && it[1] == PodcastMetadataEvent.ALT_DESCRIPTION }) - } - @Test fun `is replaceable with empty d-tag`() { val template = diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UriDetectionTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UriDetectionTest.kt index ae161e89cb..76ffc005e8 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UriDetectionTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UriDetectionTest.kt @@ -839,6 +839,49 @@ class UriDetectionTest { } } + @Test + fun testBalancedClosingDelimitersAreKept() { + // Wikipedia-style urls whose path legitimately ends in a balanced ")". + runTest( + "https://en.wikipedia.org/wiki/Bitcoin_(disambiguation)", + "https://en.wikipedia.org/wiki/Bitcoin_(disambiguation)", + ) + // also exercises a comma without surrounding spaces inside the path. + runTest( + "https://memory-alpha.fandom.com/wiki/Scorpion,_Part_II_(episode)", + "https://memory-alpha.fandom.com/wiki/Scorpion,_Part_II_(episode)", + ) + + // a balanced closer is kept even when followed by sentence punctuation/words. + runTest( + "See https://en.wikipedia.org/wiki/Bitcoin_(disambiguation).", + "https://en.wikipedia.org/wiki/Bitcoin_(disambiguation)", + ) + runTest( + "read https://en.wikipedia.org/wiki/Bitcoin_(disambiguation) now", + "https://en.wikipedia.org/wiki/Bitcoin_(disambiguation)", + ) + + // balanced braces/brackets inside the path are kept as well. + runTest("https://example.com/a[b]c", "https://example.com/a[b]c") + runTest("https://example.com/a{b}c", "https://example.com/a{b}c") + + // commas without surrounding spaces stay part of the url. + runTest("https://example.com/a,b,c", "https://example.com/a,b,c") + } + + @Test + fun testUnbalancedClosingDelimitersAreStripped() { + // a closer that wraps the url (no matching opener inside it) is still removed. + runTest("(see example.com)", "example.com") + runTest("look [example.com]", "example.com") + runTest("note {example.com}", "example.com") + runTest("https://example.com/path)", "https://example.com/path") + + // a trailing comma is sentence punctuation and is still removed. + runTest("visit example.com,", "example.com") + } + private fun runTest( text: String, vararg expected: String?,