mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-05 19:28:25 +00:00
fix(strings): move the cordn and backup strings to commonsUI, and write the rule down
The 2026-09-22 move left Android res/ with only the ~190 strings a platform
API reads synchronously. The cordn UI and the backup-conflict review then
added 447 keys back to it. All of them move with tools/strings-migrate
(1,131 elements across the locales that translate them), and the 18 files
that read them now use Res.string/Res.plurals.
The parts that were not a rename:
- stringRes(context, ...) in the suspend attachment/voice senders becomes
loadStringRes; adminFailureText becomes suspend (its only caller is already
inside scope.launch).
- The backup review held labels as @StringRes Int (DiffGroup.label, the
ReviewRow *Res fields, eventTypeName/Explainer, the tile/hero/lane params).
They are StringResource / PluralStringResource now.
- rememberPresentation resolved labels inside remember {} through
LocalResources. Compose resources have no blocking accessor, so the 16
labels presentationOf writes into item text are resolved in composition
into a map, and that map is the remember key.
- androidx pluralStringResource -> the compose-resources one.
The rule is now in .claude/CLAUDE.md ("Strings"), commonsUI/ARCHITECTURE.md
and the android-expert and find-missing-translations skills: new strings go
in commonsUI composeResources, Android-only screens included.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UjQQN9CgWHVtNCSWqnKoqY
This commit is contained in:
@@ -285,6 +285,48 @@ Quartz uses expect/actual for platform-specific implementations (e.g. crypto
|
||||
backed by `secp256k1-kmp-jni-android` on Android and `secp256k1-kmp-jni-jvm` on
|
||||
JVM). See `/kotlin-multiplatform` for the expect/actual and source-set patterns.
|
||||
|
||||
## Strings
|
||||
|
||||
**MANDATORY: every new user-visible string goes in `commonsUI` Compose resources**,
|
||||
`commonsUI/src/commonMain/composeResources/values/strings.xml` — **never** in
|
||||
`amethyst/src/main/res/values/strings.xml`, even for an Android-only screen. A
|
||||
screen cannot move to `commonsUI` (or be rendered by Desktop) while its labels
|
||||
live in Android `res/`, and every key added there has to be migrated back out
|
||||
later. (The 2026-09-22 move emptied Android `res/` down to ~190 keys; the next two
|
||||
features put 447 back.)
|
||||
|
||||
- Reference it as `Res.string.my_key` / `Res.plurals.my_key`, importing
|
||||
`com.vitorpamplona.amethyst.commons.resources.Res` **and** the per-key accessor
|
||||
`com.vitorpamplona.amethyst.commons.resources.my_key` (Compose resources generates
|
||||
each key as an extension property).
|
||||
- Read it with `stringRes(Res.string.x)` / `pluralStringRes(Res.plurals.x, n, …)`
|
||||
in composition — the app-side `ui.stringRes` overloads delegate to the
|
||||
commonsUI bridge (`commons/ui/StringRes.kt`), so one import serves both kinds.
|
||||
- Outside composition there is **no blocking accessor**: use `loadStringRes(…)`
|
||||
from a coroutine (or make the function `suspend`), or resolve the label in
|
||||
composition and pass it down as a `String`. A `runBlocking` bridge is ruled out.
|
||||
- Hold a string reference as `StringResource` / `PluralStringResource`, not a
|
||||
`@StringRes Int`.
|
||||
- Format arguments must be positional (`%1$s`, `%2$d`) — compose-resources does
|
||||
not format bare `%s`/`%d`.
|
||||
- Escaping is not Android's: write `'` and `"` bare (no `\'`), and never wrap a
|
||||
value in quotes to keep its whitespace. `.claude/hooks/compose_escaping_check.py`
|
||||
checks this before a push.
|
||||
|
||||
The **only** strings that stay in Android `res/` are the ones a platform API
|
||||
reads synchronously under a deadline, where a `suspend` read cannot run: a
|
||||
foreground service's `startForeground` notification, a notification channel
|
||||
created during service startup, PiP `RemoteAction`s, napplet capability labels
|
||||
read in the sandbox process, and `AndroidManifest.xml` / `res/xml` references.
|
||||
Most of those are *copies* of a key that also lives in `commonsUI`. See
|
||||
`commons/plans/2026-09-22-strings-to-compose-resources.md` ("the
|
||||
synchronous-platform tier"). If you think a new string belongs in that tier,
|
||||
say why in the PR.
|
||||
|
||||
To move keys that already landed in Android `res/`, use
|
||||
`tools/strings-migrate/migrate.py <keys…>`. It moves every locale byte-for-byte,
|
||||
so Crowdin sees a pure move. Then repoint `R.string.x` → `Res.string.x`.
|
||||
|
||||
## Icons
|
||||
|
||||
The Material Symbols font bundled at
|
||||
|
||||
@@ -875,18 +875,33 @@ fun ProfileScreen(
|
||||
|
||||
### 3. Resource Access
|
||||
|
||||
**Strings do not go in `amethyst/src/main/res`.** New user-visible strings live in
|
||||
`commonsUI/src/commonMain/composeResources/values/strings.xml` and are read as
|
||||
`Res.string.x`, even on an Android-only screen. See "Strings" in `.claude/CLAUDE.md`
|
||||
for the rule and the small platform tier that is the only exception.
|
||||
|
||||
```kotlin
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.button_clicked
|
||||
import com.vitorpamplona.amethyst.commons.resources.button_label
|
||||
import com.vitorpamplona.amethyst.commons.ui.loadStringRes
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
|
||||
@Composable
|
||||
fun LocalizedButton() {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
val message = context.getString(R.string.button_clicked)
|
||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
|
||||
// No blocking accessor outside composition: read it from a coroutine,
|
||||
// or resolve it in composition and capture the String.
|
||||
scope.launch {
|
||||
Toast.makeText(context, loadStringRes(Res.string.button_clicked), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text(stringResource(R.string.button_label))
|
||||
Text(stringRes(Res.string.button_label))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -26,6 +26,13 @@ There are two separate `strings.xml` trees, each with its own default `values/`
|
||||
| **amethyst** (Android app) | `amethyst/src/main/res/values/strings.xml` | `amethyst/src/main/res/values-<locale>/strings.xml` |
|
||||
| **commonsUI** (KMP Compose resources, shared by Android + Desktop) | `commonsUI/src/commonMain/composeResources/values/strings.xml` | `commonsUI/src/commonMain/composeResources/values-<locale>/strings.xml` |
|
||||
|
||||
**New keys go in the `commonsUI` tree, always.** The amethyst tree is frozen at
|
||||
the small synchronous-platform tier (foreground-service and notification-channel
|
||||
text, PiP actions, napplet capability labels, manifest references). If you find
|
||||
a new feature key in it, it belongs in `commonsUI`. Move it with
|
||||
`tools/strings-migrate/migrate.py` rather than translating it where it is. See
|
||||
"Strings" in `.claude/CLAUDE.md`.
|
||||
|
||||
The `commonsUI` tree appeared when shared event-renderer composables were extracted out of `amethyst/` into `commons/` — now `commonsUI/` since the UI split (Compose Multiplatform `stringResource`). It is **not** a copy of the amethyst tree — the vast majority of its keys are commons-only; only a small handful overlap. Every diff/count/translate command below works on either tree by swapping the base path — **run the whole technique once per tree** and report them separately (each maps to its own Crowdin file, so the counts should reconcile against two different Crowdin UI numbers).
|
||||
|
||||
**Locale-qualifier caveat:** `commons` uses the same region-qualified locale dirs as amethyst for our four targets (`values-cs`, `values-de-rDE`, `values-sv-rSE`, `values-pt-rBR`), but the *full* set of locale dirs differs between trees. Enumerate `values-*` under each tree's own base rather than assuming they match.
|
||||
|
||||
+87
-44
@@ -43,17 +43,57 @@ 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.res.pluralStringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
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.backups.BackupEventType
|
||||
import com.vitorpamplona.amethyst.commons.model.backups.ReplaceableBackupConflict
|
||||
import com.vitorpamplona.amethyst.commons.model.navigation.Route
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_accept
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_and_added
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_and_blocked
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_and_followed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_and_joined
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_and_muted
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_app_settings
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_concord_emptied
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_concord_rewritten
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_dm_relays_lost
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_feeds_removed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_follows_dropped
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_hashtags_unfollowed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_indexer_relays_lost
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_key_package_relays_lost
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_leave_chats
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_leave_communities
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_leave_groups
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_leave_rooms
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_mutes_visible
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_nip65_lost
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_nutzap_key_removed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_nutzap_key_replaced
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_nutzap_mints_removed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_offers_removed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_payment_targets_removed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_places_unfollowed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_private_outbox_lost
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_profile_lost_fields
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_relay_feeds_lost
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_search_relays_lost
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_trust_services_changed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_trusted_lost
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_unblocked
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_wallet_emptied
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_card_wallet_rewritten
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_count_added
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_count_changed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_count_removed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_changed_by_other_app
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText
|
||||
import com.vitorpamplona.amethyst.ui.note.timeAgoNoDot
|
||||
@@ -79,6 +119,9 @@ import com.vitorpamplona.quartz.nip72ModCommunities.follow.CommunityListDiff
|
||||
import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataDiff
|
||||
import com.vitorpamplona.quartz.nip85TrustedAssertions.list.TrustProviderListDiff
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListDiff
|
||||
import org.jetbrains.compose.resources.PluralStringResource
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.pluralStringResource
|
||||
|
||||
/**
|
||||
* Cards at the top of Home's feed, one per open [ReplaceableBackupConflict]: the user
|
||||
@@ -125,34 +168,34 @@ private fun headlineOf(
|
||||
when (diff) {
|
||||
// Counted, not "shrank": a version that drops 3 follows and adds 100 still raises
|
||||
// a conflict, and calling that a shrink contradicts the card's own bar.
|
||||
is ContactListDiff -> plural(R.plurals.backup_card_follows_dropped, diff.follows.removed.size)
|
||||
is MuteListDiff -> plural(R.plurals.backup_card_mutes_visible, diff.publicMutes.removed.size)
|
||||
is MetadataDiff -> plural(R.plurals.backup_card_profile_lost_fields, counts.removed)
|
||||
is AdvertisedRelayListDiff -> plural(R.plurals.backup_card_nip65_lost, diff.relays.removed.size)
|
||||
is ContactListDiff -> plural(Res.plurals.backup_card_follows_dropped, diff.follows.removed.size)
|
||||
is MuteListDiff -> plural(Res.plurals.backup_card_mutes_visible, diff.publicMutes.removed.size)
|
||||
is MetadataDiff -> plural(Res.plurals.backup_card_profile_lost_fields, counts.removed)
|
||||
is AdvertisedRelayListDiff -> plural(Res.plurals.backup_card_nip65_lost, diff.relays.removed.size)
|
||||
is RelayListDiff -> relayListHeadline(conflict.eventType, diff.relays.removed.size)
|
||||
is ChannelListDiff -> plural(R.plurals.backup_card_leave_chats, diff.channels.removed.size)
|
||||
is CommunityListDiff -> plural(R.plurals.backup_card_leave_communities, diff.communities.removed.size)
|
||||
is EphemeralChatListDiff -> plural(R.plurals.backup_card_leave_rooms, diff.rooms.removed.size)
|
||||
is SimpleGroupListDiff -> plural(R.plurals.backup_card_leave_groups, diff.groups.removed.size)
|
||||
is FavoriteAlgoFeedsListDiff -> plural(R.plurals.backup_card_feeds_removed, diff.feeds.removed.size)
|
||||
is HashtagListDiff -> plural(R.plurals.backup_card_hashtags_unfollowed, diff.hashtags.removed.size)
|
||||
is GeohashListDiff -> plural(R.plurals.backup_card_places_unfollowed, diff.geohashes.removed.size)
|
||||
is TrustProviderListDiff -> plural(R.plurals.backup_card_trust_services_changed, diff.providers.removed.size + diff.providers.changed.size)
|
||||
is ChannelListDiff -> plural(Res.plurals.backup_card_leave_chats, diff.channels.removed.size)
|
||||
is CommunityListDiff -> plural(Res.plurals.backup_card_leave_communities, diff.communities.removed.size)
|
||||
is EphemeralChatListDiff -> plural(Res.plurals.backup_card_leave_rooms, diff.rooms.removed.size)
|
||||
is SimpleGroupListDiff -> plural(Res.plurals.backup_card_leave_groups, diff.groups.removed.size)
|
||||
is FavoriteAlgoFeedsListDiff -> plural(Res.plurals.backup_card_feeds_removed, diff.feeds.removed.size)
|
||||
is HashtagListDiff -> plural(Res.plurals.backup_card_hashtags_unfollowed, diff.hashtags.removed.size)
|
||||
is GeohashListDiff -> plural(Res.plurals.backup_card_places_unfollowed, diff.geohashes.removed.size)
|
||||
is TrustProviderListDiff -> plural(Res.plurals.backup_card_trust_services_changed, diff.providers.removed.size + diff.providers.changed.size)
|
||||
is NutzapInfoDiff ->
|
||||
when {
|
||||
diff.p2pkPubkey?.after == null && diff.p2pkPubkey != null -> stringRes(R.string.backup_card_nutzap_key_removed)
|
||||
diff.p2pkPubkey != null -> stringRes(R.string.backup_card_nutzap_key_replaced)
|
||||
else -> plural(R.plurals.backup_card_nutzap_mints_removed, diff.mints.removed.size)
|
||||
diff.p2pkPubkey?.after == null && diff.p2pkPubkey != null -> stringRes(Res.string.backup_card_nutzap_key_removed)
|
||||
diff.p2pkPubkey != null -> stringRes(Res.string.backup_card_nutzap_key_replaced)
|
||||
else -> plural(Res.plurals.backup_card_nutzap_mints_removed, diff.mints.removed.size)
|
||||
}
|
||||
is PaymentTargetsDiff -> plural(R.plurals.backup_card_payment_targets_removed, diff.targets.removed.size)
|
||||
is Bolt12OfferListDiff -> plural(R.plurals.backup_card_offers_removed, diff.offers.removed.size)
|
||||
is CashuWalletDiff -> encryptedHeadline(R.string.backup_card_wallet_emptied, R.string.backup_card_wallet_rewritten, diff.wallet)
|
||||
is ConcordCommunityListDiff -> encryptedHeadline(R.string.backup_card_concord_emptied, R.string.backup_card_concord_rewritten, diff.communities)
|
||||
is AppSpecificDataDiff -> stringRes(R.string.backup_card_app_settings)
|
||||
is PaymentTargetsDiff -> plural(Res.plurals.backup_card_payment_targets_removed, diff.targets.removed.size)
|
||||
is Bolt12OfferListDiff -> plural(Res.plurals.backup_card_offers_removed, diff.offers.removed.size)
|
||||
is CashuWalletDiff -> encryptedHeadline(Res.string.backup_card_wallet_emptied, Res.string.backup_card_wallet_rewritten, diff.wallet)
|
||||
is ConcordCommunityListDiff -> encryptedHeadline(Res.string.backup_card_concord_emptied, Res.string.backup_card_concord_rewritten, diff.communities)
|
||||
is AppSpecificDataDiff -> stringRes(Res.string.backup_card_app_settings)
|
||||
else -> null
|
||||
}
|
||||
// A headline counting removed items reads wrong when only encrypted items were lost.
|
||||
if (specific.isNullOrEmpty()) return stringRes(R.string.backup_conflict_title, stringRes(eventTypeName(conflict.eventType)))
|
||||
if (specific.isNullOrEmpty()) return stringRes(Res.string.backup_conflict_title, stringRes(eventTypeName(conflict.eventType)))
|
||||
// Headlines lead with the loss; what the other app added to the same list is said too,
|
||||
// so a list that dropped 3 and gained 40 doesn't read as if it only shrank. The wording
|
||||
// follows the headline's: following people, muting, joining chats, blocking relays.
|
||||
@@ -160,11 +203,11 @@ private fun headlineOf(
|
||||
if (added <= 0) return specific
|
||||
val tail =
|
||||
when {
|
||||
diff is ContactListDiff -> R.plurals.backup_card_and_followed
|
||||
diff is MuteListDiff -> R.plurals.backup_card_and_muted
|
||||
diff is ChannelListDiff || diff is CommunityListDiff || diff is EphemeralChatListDiff || diff is SimpleGroupListDiff -> R.plurals.backup_card_and_joined
|
||||
conflict.eventType == BackupEventType.BLOCKED_RELAYS -> R.plurals.backup_card_and_blocked
|
||||
else -> R.plurals.backup_card_and_added
|
||||
diff is ContactListDiff -> Res.plurals.backup_card_and_followed
|
||||
diff is MuteListDiff -> Res.plurals.backup_card_and_muted
|
||||
diff is ChannelListDiff || diff is CommunityListDiff || diff is EphemeralChatListDiff || diff is SimpleGroupListDiff -> Res.plurals.backup_card_and_joined
|
||||
conflict.eventType == BackupEventType.BLOCKED_RELAYS -> Res.plurals.backup_card_and_blocked
|
||||
else -> Res.plurals.backup_card_and_added
|
||||
}
|
||||
return pluralStringResource(tail, added, specific, added)
|
||||
}
|
||||
@@ -208,7 +251,7 @@ private fun relayListHasHeadline(type: BackupEventType): Boolean =
|
||||
/** The count's plural, or "" when nothing of that kind was removed. */
|
||||
@Composable
|
||||
private fun plural(
|
||||
id: Int,
|
||||
id: PluralStringResource,
|
||||
count: Int,
|
||||
): String = if (count > 0) pluralStringResource(id, count, count) else ""
|
||||
|
||||
@@ -218,21 +261,21 @@ private fun relayListHeadline(
|
||||
removed: Int,
|
||||
): String =
|
||||
when (type) {
|
||||
BackupEventType.DM_RELAYS -> plural(R.plurals.backup_card_dm_relays_lost, removed)
|
||||
BackupEventType.KEY_PACKAGE_RELAYS -> plural(R.plurals.backup_card_key_package_relays_lost, removed)
|
||||
BackupEventType.SEARCH_RELAYS -> plural(R.plurals.backup_card_search_relays_lost, removed)
|
||||
BackupEventType.INDEXER_RELAYS -> plural(R.plurals.backup_card_indexer_relays_lost, removed)
|
||||
BackupEventType.RELAY_FEEDS -> plural(R.plurals.backup_card_relay_feeds_lost, removed)
|
||||
BackupEventType.PRIVATE_OUTBOX_RELAYS -> plural(R.plurals.backup_card_private_outbox_lost, removed)
|
||||
BackupEventType.TRUSTED_RELAYS -> plural(R.plurals.backup_card_trusted_lost, removed)
|
||||
BackupEventType.BLOCKED_RELAYS -> plural(R.plurals.backup_card_unblocked, removed)
|
||||
BackupEventType.DM_RELAYS -> plural(Res.plurals.backup_card_dm_relays_lost, removed)
|
||||
BackupEventType.KEY_PACKAGE_RELAYS -> plural(Res.plurals.backup_card_key_package_relays_lost, removed)
|
||||
BackupEventType.SEARCH_RELAYS -> plural(Res.plurals.backup_card_search_relays_lost, removed)
|
||||
BackupEventType.INDEXER_RELAYS -> plural(Res.plurals.backup_card_indexer_relays_lost, removed)
|
||||
BackupEventType.RELAY_FEEDS -> plural(Res.plurals.backup_card_relay_feeds_lost, removed)
|
||||
BackupEventType.PRIVATE_OUTBOX_RELAYS -> plural(Res.plurals.backup_card_private_outbox_lost, removed)
|
||||
BackupEventType.TRUSTED_RELAYS -> plural(Res.plurals.backup_card_trusted_lost, removed)
|
||||
BackupEventType.BLOCKED_RELAYS -> plural(Res.plurals.backup_card_unblocked, removed)
|
||||
else -> ""
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun encryptedHeadline(
|
||||
emptied: Int,
|
||||
rewritten: Int,
|
||||
emptied: StringResource,
|
||||
rewritten: StringResource,
|
||||
change: ContentChange,
|
||||
): String = if (change == ContentChange.CLEARED) stringRes(emptied) else stringRes(rewritten)
|
||||
|
||||
@@ -262,7 +305,7 @@ private fun LeadConflictCard(
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text(headlineOf(conflict, counts), style = MaterialTheme.typography.titleSmall, fontWeight = FontWeight.Bold, maxLines = 3, overflow = TextOverflow.Ellipsis)
|
||||
Text(
|
||||
stringRes(R.string.backup_review_changed_by_other_app, timeAgoNoDot(conflict.cause.createdAt)),
|
||||
stringRes(Res.string.backup_review_changed_by_other_app, timeAgoNoDot(conflict.cause.createdAt)),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.placeholderText,
|
||||
)
|
||||
@@ -296,9 +339,9 @@ private fun LeadConflictCard(
|
||||
private fun CountChips(counts: ConflictCounts) {
|
||||
val tones = conflictTones()
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
if (counts.removed > 0) StatusTag(stringRes(R.string.backup_conflict_count_removed, counts.removed.toString()), tones.removed)
|
||||
if (counts.added > 0) StatusTag(stringRes(R.string.backup_conflict_count_added, counts.added.toString()), tones.added)
|
||||
if (counts.changed > 0) StatusTag(stringRes(R.string.backup_conflict_count_changed, counts.changed.toString()), tones.changed)
|
||||
if (counts.removed > 0) StatusTag(stringRes(Res.string.backup_conflict_count_removed, counts.removed.toString()), tones.removed)
|
||||
if (counts.added > 0) StatusTag(stringRes(Res.string.backup_conflict_count_added, counts.added.toString()), tones.added)
|
||||
if (counts.changed > 0) StatusTag(stringRes(Res.string.backup_conflict_count_changed, counts.changed.toString()), tones.changed)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,6 +385,6 @@ private fun AcceptButton(onAccept: () -> Unit) {
|
||||
modifier = Modifier.height(36.dp),
|
||||
contentPadding = PaddingValues(horizontal = 14.dp),
|
||||
) {
|
||||
Text(stringRes(R.string.backup_card_accept), fontWeight = FontWeight.SemiBold)
|
||||
Text(stringRes(Res.string.backup_card_accept), fontWeight = FontWeight.SemiBold)
|
||||
}
|
||||
}
|
||||
|
||||
+129
-68
@@ -62,7 +62,6 @@ import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
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.backups.ReplaceableBackupConflict
|
||||
@@ -70,6 +69,67 @@ import com.vitorpamplona.amethyst.commons.model.cache.LocalCache
|
||||
import com.vitorpamplona.amethyst.commons.model.navigation.Route
|
||||
import com.vitorpamplona.amethyst.commons.model.navigation.routeFor
|
||||
import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_hashtag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_mint
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_nutzap_key
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_person
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_profile_field
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_thread
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_word
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_about
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_banner
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_birthday
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_bot
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_clink_offer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_display_name
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_lud06
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_lud16
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_name
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_nip05
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_picture
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_pronouns
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_website
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_demoted_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_dropped_count
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_dropped_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_gone
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_inbox
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_inbox_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_joined
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_kept_count
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_key_removed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_key_replaced
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_key_warning
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_left
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_left_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_names_and_more
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_new
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_new_count
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_new_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_newly_muted
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_not_set
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_nothing_here
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_outbox
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_outbox_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_private_added_body
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_private_added_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_private_changed_body
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_private_changed_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_private_wiped_body
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_private_wiped_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_renamed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_renamed_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_saved
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_search_people
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_tab_dropped
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_tab_edited
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_tab_new
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_units_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_unmuted
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_unmuted_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_was_named
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_words_and_hashtags
|
||||
import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.commons.ui.screen.LocalDisplaySettings
|
||||
@@ -111,6 +171,7 @@ import com.vitorpamplona.quartz.nip61Nutzaps.info.tags.NutzapMintTag
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListDiff
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip65RelayList.tags.AdvertisedRelayType
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
|
||||
private const val GRID_COLUMNS = 4
|
||||
private const val PEOPLE_PREVIEW = 6
|
||||
@@ -168,7 +229,7 @@ private fun LazyListScope.followListItems(
|
||||
item(key = "follow-hero", contentType = "hero") {
|
||||
val tones = conflictTones()
|
||||
Column(Pad.padding(top = 8.dp), verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
HeroCounts(stringRes(R.string.backup_review_saved), saved, stringRes(R.string.backup_review_new), new)
|
||||
HeroCounts(stringRes(Res.string.backup_review_saved), saved, stringRes(Res.string.backup_review_new), new)
|
||||
SplitBar(
|
||||
listOf(
|
||||
BarSegment(saved - dropped, tones.kept),
|
||||
@@ -177,9 +238,9 @@ private fun LazyListScope.followListItems(
|
||||
),
|
||||
)
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(14.dp)) {
|
||||
LegendItem(tones.kept, stringRes(R.string.backup_review_kept_count, (saved - dropped).toString()))
|
||||
LegendItem(tones.removed, stringRes(R.string.backup_review_dropped_count, dropped.toString()))
|
||||
LegendItem(tones.added, stringRes(R.string.backup_review_new_count, gained.toString()))
|
||||
LegendItem(tones.kept, stringRes(Res.string.backup_review_kept_count, (saved - dropped).toString()))
|
||||
LegendItem(tones.removed, stringRes(Res.string.backup_review_dropped_count, dropped.toString()))
|
||||
LegendItem(tones.added, stringRes(Res.string.backup_review_new_count, gained.toString()))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,9 +249,9 @@ private fun LazyListScope.followListItems(
|
||||
ReviewTabs(
|
||||
labels =
|
||||
listOf(
|
||||
stringRes(R.string.backup_review_tab_dropped, dropped.toString()),
|
||||
stringRes(R.string.backup_review_tab_new, gained.toString()),
|
||||
stringRes(R.string.backup_review_tab_edited, edited.toString()),
|
||||
stringRes(Res.string.backup_review_tab_dropped, dropped.toString()),
|
||||
stringRes(Res.string.backup_review_tab_new, gained.toString()),
|
||||
stringRes(Res.string.backup_review_tab_edited, edited.toString()),
|
||||
),
|
||||
selected = ui.tab,
|
||||
onSelect = {
|
||||
@@ -223,7 +284,7 @@ private fun LazyListScope.followListItems(
|
||||
|
||||
if (filtered.isEmpty()) {
|
||||
item(key = "follow-empty", contentType = "note") {
|
||||
DetailText(stringRes(R.string.backup_review_nothing_here), Pad.padding(vertical = 24.dp))
|
||||
DetailText(stringRes(Res.string.backup_review_nothing_here), Pad.padding(vertical = 24.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -359,7 +420,7 @@ private fun PeopleSearch(
|
||||
singleLine = true,
|
||||
shape = RoundedCornerShape(14.dp),
|
||||
leadingIcon = { Icon(symbol = MaterialSymbols.Search, contentDescription = null) },
|
||||
placeholder = { Text(stringRes(R.string.backup_review_search_people, count.toString())) },
|
||||
placeholder = { Text(stringRes(Res.string.backup_review_search_people, count.toString())) },
|
||||
)
|
||||
}
|
||||
|
||||
@@ -388,15 +449,15 @@ private fun LazyListScope.muteListItems(
|
||||
Icon(symbol = MaterialSymbols.Shield, contentDescription = null, tint = tones.removed, modifier = Modifier.size(44.dp))
|
||||
Column {
|
||||
Text(
|
||||
stringRes(R.string.backup_review_unmuted, removed.size.toString()),
|
||||
stringRes(Res.string.backup_review_unmuted, removed.size.toString()),
|
||||
fontSize = 30.sp,
|
||||
lineHeight = 32.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = tones.removed,
|
||||
)
|
||||
Text(stringRes(R.string.backup_review_unmuted_explainer), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.placeholderText)
|
||||
Text(stringRes(Res.string.backup_review_unmuted_explainer), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.placeholderText)
|
||||
if (added.isNotEmpty()) {
|
||||
Text(stringRes(R.string.backup_review_newly_muted, added.size.toString()), style = MaterialTheme.typography.bodySmall, color = tones.added)
|
||||
Text(stringRes(Res.string.backup_review_newly_muted, added.size.toString()), style = MaterialTheme.typography.bodySmall, color = tones.added)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -406,17 +467,17 @@ private fun LazyListScope.muteListItems(
|
||||
item(key = "mute-tiles", contentType = "tiles") {
|
||||
val tones = conflictTones()
|
||||
Row(Pad.padding(top = 12.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
StatTile("−${people.size}", stringRes(R.string.backup_entry_person), tones.removed, Modifier.weight(1f))
|
||||
StatTile("−${words.size}", stringRes(R.string.backup_entry_word), tones.removed, Modifier.weight(1f))
|
||||
StatTile("−${hashtags.size}", stringRes(R.string.backup_entry_hashtag), tones.removed, Modifier.weight(1f))
|
||||
StatTile("−${threads.size}", stringRes(R.string.backup_entry_thread), tones.removed, Modifier.weight(1f))
|
||||
StatTile("−${people.size}", stringRes(Res.string.backup_entry_person), tones.removed, Modifier.weight(1f))
|
||||
StatTile("−${words.size}", stringRes(Res.string.backup_entry_word), tones.removed, Modifier.weight(1f))
|
||||
StatTile("−${hashtags.size}", stringRes(Res.string.backup_entry_hashtag), tones.removed, Modifier.weight(1f))
|
||||
StatTile("−${threads.size}", stringRes(Res.string.backup_entry_thread), tones.removed, Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
|
||||
if (people.isNotEmpty()) {
|
||||
item(key = "mute-people", contentType = "facepile") {
|
||||
Column(Pad.padding(top = 18.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
SectionCaption(stringRes(R.string.backup_entry_person))
|
||||
SectionCaption(stringRes(Res.string.backup_entry_person))
|
||||
FacePile(people, accountViewModel) { ui.showAllPeople = !ui.showAllPeople }
|
||||
}
|
||||
}
|
||||
@@ -427,7 +488,7 @@ private fun LazyListScope.muteListItems(
|
||||
item(key = "mute-words", contentType = "pills") {
|
||||
val tones = conflictTones()
|
||||
Column(Pad.padding(top = 18.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
SectionCaption(stringRes(R.string.backup_review_words_and_hashtags))
|
||||
SectionCaption(stringRes(Res.string.backup_review_words_and_hashtags))
|
||||
FlowRow(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
(words.map { "\"$it\"" } + hashtags).forEach { StruckPill(it, tones.removed) }
|
||||
}
|
||||
@@ -436,7 +497,7 @@ private fun LazyListScope.muteListItems(
|
||||
}
|
||||
|
||||
if (threads.isNotEmpty()) {
|
||||
item(key = "mute-threads-caption", contentType = "caption") { SectionCaption(stringRes(R.string.backup_entry_thread), Pad.padding(top = 18.dp)) }
|
||||
item(key = "mute-threads-caption", contentType = "caption") { SectionCaption(stringRes(Res.string.backup_entry_thread), Pad.padding(top = 18.dp)) }
|
||||
items(threads, key = { "mute-thread-$it" }, contentType = { "note" }) { id ->
|
||||
LoadNote(id) { note ->
|
||||
if (note != null) {
|
||||
@@ -463,7 +524,7 @@ private fun FacePile(
|
||||
val names = people.take(2).map { observedName(it, accountViewModel) }
|
||||
val summary =
|
||||
if (people.size > 2) {
|
||||
stringRes(R.string.backup_review_names_and_more, names.joinToString(", "), (people.size - 2).toString())
|
||||
stringRes(Res.string.backup_review_names_and_more, names.joinToString(", "), (people.size - 2).toString())
|
||||
} else {
|
||||
names.joinToString(", ")
|
||||
}
|
||||
@@ -564,9 +625,9 @@ internal fun PrivateItemsCard(
|
||||
val tones = conflictTones()
|
||||
val (title, body) =
|
||||
when (change) {
|
||||
ContentChange.CLEARED -> R.string.backup_review_private_wiped_title to R.string.backup_review_private_wiped_body
|
||||
ContentChange.ADDED -> R.string.backup_review_private_added_title to R.string.backup_review_private_added_body
|
||||
else -> R.string.backup_review_private_changed_title to R.string.backup_review_private_changed_body
|
||||
ContentChange.CLEARED -> Res.string.backup_review_private_wiped_title to Res.string.backup_review_private_wiped_body
|
||||
ContentChange.ADDED -> Res.string.backup_review_private_added_title to Res.string.backup_review_private_added_body
|
||||
else -> Res.string.backup_review_private_changed_title to Res.string.backup_review_private_changed_body
|
||||
}
|
||||
Row(
|
||||
modifier
|
||||
@@ -592,28 +653,28 @@ internal fun PrivateItemsCard(
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
private class ProfileField(
|
||||
val labelRes: Int,
|
||||
val labelRes: StringResource,
|
||||
val change: ValueChange<String>,
|
||||
val isImage: Boolean = false,
|
||||
)
|
||||
|
||||
private fun profileFields(diff: MetadataDiff): List<ProfileField> =
|
||||
listOfNotNull(
|
||||
diff.picture?.let { ProfileField(R.string.backup_profile_field_picture, it, isImage = true) },
|
||||
diff.banner?.let { ProfileField(R.string.backup_profile_field_banner, it, isImage = true) },
|
||||
diff.name?.let { ProfileField(R.string.backup_profile_field_name, it) },
|
||||
diff.displayName?.let { ProfileField(R.string.backup_profile_field_display_name, it) },
|
||||
diff.about?.let { ProfileField(R.string.backup_profile_field_about, it) },
|
||||
diff.nip05?.let { ProfileField(R.string.backup_profile_field_nip05, it) },
|
||||
diff.website?.let { ProfileField(R.string.backup_profile_field_website, it) },
|
||||
diff.lud16?.let { ProfileField(R.string.backup_profile_field_lud16, it) },
|
||||
diff.lud06?.let { ProfileField(R.string.backup_profile_field_lud06, it) },
|
||||
diff.clinkOffer?.let { ProfileField(R.string.backup_profile_field_clink_offer, it) },
|
||||
diff.pronouns?.let { ProfileField(R.string.backup_profile_field_pronouns, it) },
|
||||
diff.bot?.let { ProfileField(R.string.backup_profile_field_bot, ValueChange(it.before?.toString(), it.after?.toString())) },
|
||||
diff.picture?.let { ProfileField(Res.string.backup_profile_field_picture, it, isImage = true) },
|
||||
diff.banner?.let { ProfileField(Res.string.backup_profile_field_banner, it, isImage = true) },
|
||||
diff.name?.let { ProfileField(Res.string.backup_profile_field_name, it) },
|
||||
diff.displayName?.let { ProfileField(Res.string.backup_profile_field_display_name, it) },
|
||||
diff.about?.let { ProfileField(Res.string.backup_profile_field_about, it) },
|
||||
diff.nip05?.let { ProfileField(Res.string.backup_profile_field_nip05, it) },
|
||||
diff.website?.let { ProfileField(Res.string.backup_profile_field_website, it) },
|
||||
diff.lud16?.let { ProfileField(Res.string.backup_profile_field_lud16, it) },
|
||||
diff.lud06?.let { ProfileField(Res.string.backup_profile_field_lud06, it) },
|
||||
diff.clinkOffer?.let { ProfileField(Res.string.backup_profile_field_clink_offer, it) },
|
||||
diff.pronouns?.let { ProfileField(Res.string.backup_profile_field_pronouns, it) },
|
||||
diff.bot?.let { ProfileField(Res.string.backup_profile_field_bot, ValueChange(it.before?.toString(), it.after?.toString())) },
|
||||
diff.birthday?.let {
|
||||
ProfileField(
|
||||
R.string.backup_profile_field_birthday,
|
||||
Res.string.backup_profile_field_birthday,
|
||||
ValueChange(
|
||||
it.before?.let { b -> listOfNotNull(b.year, b.month, b.day).joinToString("-") },
|
||||
it.after?.let { a -> listOfNotNull(a.year, a.month, a.day).joinToString("-") },
|
||||
@@ -636,8 +697,8 @@ private fun LazyListScope.profileItems(
|
||||
item(key = "profile-cards", contentType = "profile-cards") {
|
||||
val tones = conflictTones()
|
||||
Row(Pad.padding(top = 8.dp), horizontalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
MiniProfileCard(saved, pubKey, stringRes(R.string.backup_review_saved), MaterialTheme.colorScheme.outlineVariant, accountViewModel, Modifier.weight(1f))
|
||||
MiniProfileCard(incoming, pubKey, stringRes(R.string.backup_review_new), tones.removed.copy(alpha = 0.5f), accountViewModel, Modifier.weight(1f))
|
||||
MiniProfileCard(saved, pubKey, stringRes(Res.string.backup_review_saved), MaterialTheme.colorScheme.outlineVariant, accountViewModel, Modifier.weight(1f))
|
||||
MiniProfileCard(incoming, pubKey, stringRes(Res.string.backup_review_new), tones.removed.copy(alpha = 0.5f), accountViewModel, Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,7 +717,7 @@ private fun LazyListScope.profileItems(
|
||||
}
|
||||
}
|
||||
// Linked identities and fields this app doesn't model use the generic sections.
|
||||
genericDiffItems(buildRows(presentation, skipGroups = setOf(R.string.backup_entry_profile_field)), accountViewModel, nav)
|
||||
genericDiffItems(buildRows(presentation, skipGroups = setOf(Res.string.backup_entry_profile_field)), accountViewModel, nav)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -735,10 +796,10 @@ private fun FlowRowDiff(
|
||||
FlowRow(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(6.dp), itemVerticalAlignment = Alignment.CenterVertically) {
|
||||
if (before != null) DiffChip(clip(before), tones.removed, struck = true)
|
||||
when {
|
||||
after == null -> StatusTag(stringRes(R.string.backup_review_gone), tones.removed)
|
||||
after == null -> StatusTag(stringRes(Res.string.backup_review_gone), tones.removed)
|
||||
before == null -> {
|
||||
DiffChip(clip(after), tones.added, struck = false)
|
||||
StatusTag(stringRes(R.string.backup_review_new_tag), tones.added)
|
||||
StatusTag(stringRes(Res.string.backup_review_new_tag), tones.added)
|
||||
}
|
||||
else -> {
|
||||
Text("→", color = MaterialTheme.colorScheme.placeholderText)
|
||||
@@ -779,7 +840,7 @@ private fun ImageThumb(
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
if (url == null) {
|
||||
Text(stringRes(R.string.backup_review_not_set), style = MaterialTheme.typography.labelSmall, color = color)
|
||||
Text(stringRes(Res.string.backup_review_not_set), style = MaterialTheme.typography.labelSmall, color = color)
|
||||
} else {
|
||||
MyAsyncImage(
|
||||
imageUrl = url,
|
||||
@@ -843,14 +904,14 @@ private fun LazyListScope.nip65Items(
|
||||
val outbox = lane(saved, new, writes)
|
||||
val inbox = lane(saved, new, reads)
|
||||
|
||||
laneItems("outbox", stringRes = R.string.backup_review_outbox, subRes = R.string.backup_review_outbox_explainer, rows = outbox, nav = nav)
|
||||
laneItems("inbox", stringRes = R.string.backup_review_inbox, subRes = R.string.backup_review_inbox_explainer, rows = inbox, nav = nav)
|
||||
laneItems("outbox", stringRes = Res.string.backup_review_outbox, subRes = Res.string.backup_review_outbox_explainer, rows = outbox, nav = nav)
|
||||
laneItems("inbox", stringRes = Res.string.backup_review_inbox, subRes = Res.string.backup_review_inbox_explainer, rows = inbox, nav = nav)
|
||||
}
|
||||
|
||||
private fun LazyListScope.laneItems(
|
||||
key: String,
|
||||
stringRes: Int,
|
||||
subRes: Int,
|
||||
stringRes: StringResource,
|
||||
subRes: StringResource,
|
||||
rows: List<LaneRow>,
|
||||
nav: INav,
|
||||
) {
|
||||
@@ -873,9 +934,9 @@ private fun LaneRelayRow(
|
||||
val (color, tag) =
|
||||
when (row.state) {
|
||||
LaneState.KEPT -> tones.kept to null
|
||||
LaneState.DROPPED -> tones.removed to R.string.backup_review_dropped_tag
|
||||
LaneState.ADDED -> tones.added to R.string.backup_review_new_tag
|
||||
LaneState.DEMOTED -> tones.changed to R.string.backup_review_demoted_tag
|
||||
LaneState.DROPPED -> tones.removed to Res.string.backup_review_dropped_tag
|
||||
LaneState.ADDED -> tones.added to Res.string.backup_review_new_tag
|
||||
LaneState.DEMOTED -> tones.changed to Res.string.backup_review_demoted_tag
|
||||
}
|
||||
Row(
|
||||
Pad
|
||||
@@ -933,12 +994,12 @@ private fun LazyListScope.nutzapItems(
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Icon(symbol = MaterialSymbols.Key, contentDescription = null, tint = tones.changed)
|
||||
Text(stringRes(if (key.after == null) R.string.backup_review_key_removed else R.string.backup_review_key_replaced), style = MaterialTheme.typography.titleSmall)
|
||||
Text(stringRes(if (key.after == null) Res.string.backup_review_key_removed else Res.string.backup_review_key_replaced), style = MaterialTheme.typography.titleSmall)
|
||||
}
|
||||
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically) {
|
||||
KeyColumn(key.before, stringRes(R.string.backup_review_saved), tones.kept)
|
||||
KeyColumn(key.before, stringRes(Res.string.backup_review_saved), tones.kept)
|
||||
Text("→", fontSize = 24.sp, color = MaterialTheme.colorScheme.placeholderText, modifier = Modifier.padding(horizontal = 18.dp))
|
||||
KeyColumn(key.after, stringRes(R.string.backup_review_new), tones.changed)
|
||||
KeyColumn(key.after, stringRes(Res.string.backup_review_new), tones.changed)
|
||||
}
|
||||
if (key.after != null) {
|
||||
Row(
|
||||
@@ -950,7 +1011,7 @@ private fun LazyListScope.nutzapItems(
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
Icon(symbol = MaterialSymbols.Warning, contentDescription = null, tint = tones.changed, modifier = Modifier.size(18.dp))
|
||||
Text(stringRes(R.string.backup_review_key_warning), style = MaterialTheme.typography.bodySmall, color = tones.changed)
|
||||
Text(stringRes(Res.string.backup_review_key_warning), style = MaterialTheme.typography.bodySmall, color = tones.changed)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -976,10 +1037,10 @@ private fun LazyListScope.nutzapItems(
|
||||
} + diff.mints.added.map { Triple(it.mintUrl, it.units.joinToString(), LaneState.ADDED) }
|
||||
|
||||
if (mintRows.isNotEmpty()) {
|
||||
item(key = "nutzap-mints", contentType = "caption") { SectionCaption(stringRes(R.string.backup_entry_mint), Pad.padding(top = 18.dp, bottom = 6.dp)) }
|
||||
item(key = "nutzap-mints", contentType = "caption") { SectionCaption(stringRes(Res.string.backup_entry_mint), Pad.padding(top = 18.dp, bottom = 6.dp)) }
|
||||
items(mintRows, key = { "mint-" + it.first }, contentType = { "mint" }) { (url, units, state) -> MintRow(url, units, state) }
|
||||
}
|
||||
genericDiffItems(buildRows(presentation, skipGroups = setOf(R.string.backup_entry_mint, R.string.backup_entry_nutzap_key)), accountViewModel, nav)
|
||||
genericDiffItems(buildRows(presentation, skipGroups = setOf(Res.string.backup_entry_mint, Res.string.backup_entry_nutzap_key)), accountViewModel, nav)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -993,7 +1054,7 @@ private fun KeyColumn(
|
||||
KeyFingerprint(hex, color)
|
||||
} else {
|
||||
Box(Modifier.size(96.dp).clip(RoundedCornerShape(18.dp)).border(2.dp, color, RoundedCornerShape(18.dp)), contentAlignment = Alignment.Center) {
|
||||
Text(stringRes(R.string.backup_review_not_set), style = MaterialTheme.typography.labelSmall, color = color)
|
||||
Text(stringRes(Res.string.backup_review_not_set), style = MaterialTheme.typography.labelSmall, color = color)
|
||||
}
|
||||
}
|
||||
StatusTag(label, color)
|
||||
@@ -1010,9 +1071,9 @@ private fun MintRow(
|
||||
val (color, tag) =
|
||||
when (state) {
|
||||
LaneState.KEPT -> MaterialTheme.colorScheme.onSurface to null
|
||||
LaneState.DROPPED -> tones.removed to R.string.backup_review_dropped_tag
|
||||
LaneState.ADDED -> tones.added to R.string.backup_review_new_tag
|
||||
LaneState.DEMOTED -> tones.changed to R.string.backup_review_units_tag
|
||||
LaneState.DROPPED -> tones.removed to Res.string.backup_review_dropped_tag
|
||||
LaneState.ADDED -> tones.added to Res.string.backup_review_new_tag
|
||||
LaneState.DEMOTED -> tones.changed to Res.string.backup_review_units_tag
|
||||
}
|
||||
Row(
|
||||
Pad
|
||||
@@ -1083,21 +1144,21 @@ private fun LazyListScope.groupItems(
|
||||
StatTile(
|
||||
diff.groups.removed.size
|
||||
.toString(),
|
||||
stringRes(R.string.backup_review_left),
|
||||
stringRes(Res.string.backup_review_left),
|
||||
tones.removed,
|
||||
Modifier.weight(1f),
|
||||
)
|
||||
StatTile(
|
||||
diff.groups.added.size
|
||||
.toString(),
|
||||
stringRes(R.string.backup_review_joined),
|
||||
stringRes(Res.string.backup_review_joined),
|
||||
tones.added,
|
||||
Modifier.weight(1f),
|
||||
)
|
||||
StatTile(
|
||||
diff.groups.changed.size
|
||||
.toString(),
|
||||
stringRes(R.string.backup_review_renamed),
|
||||
stringRes(Res.string.backup_review_renamed),
|
||||
tones.changed,
|
||||
Modifier.weight(1f),
|
||||
)
|
||||
@@ -1165,7 +1226,7 @@ private fun GroupTileContent(
|
||||
Column {
|
||||
Text(name, style = MaterialTheme.typography.titleSmall, maxLines = 1, overflow = TextOverflow.Ellipsis)
|
||||
Text(
|
||||
tile.oldName?.let { stringRes(R.string.backup_review_was_named, it) } ?: tile.group.relayUrl
|
||||
tile.oldName?.let { stringRes(Res.string.backup_review_was_named, it) } ?: tile.group.relayUrl
|
||||
.removePrefix("wss://")
|
||||
.removeSuffix("/"),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
@@ -1176,9 +1237,9 @@ private fun GroupTileContent(
|
||||
}
|
||||
}
|
||||
when (tile.state) {
|
||||
LaneState.DROPPED -> StatusTag(stringRes(R.string.backup_review_left_tag), tones.removed, Modifier.align(Alignment.TopEnd))
|
||||
LaneState.ADDED -> StatusTag(stringRes(R.string.backup_review_new_tag), tones.added, Modifier.align(Alignment.TopEnd))
|
||||
LaneState.DEMOTED -> StatusTag(stringRes(R.string.backup_review_renamed_tag), tones.changed, Modifier.align(Alignment.TopEnd))
|
||||
LaneState.DROPPED -> StatusTag(stringRes(Res.string.backup_review_left_tag), tones.removed, Modifier.align(Alignment.TopEnd))
|
||||
LaneState.ADDED -> StatusTag(stringRes(Res.string.backup_review_new_tag), tones.added, Modifier.align(Alignment.TopEnd))
|
||||
LaneState.DEMOTED -> StatusTag(stringRes(Res.string.backup_review_renamed_tag), tones.changed, Modifier.align(Alignment.TopEnd))
|
||||
LaneState.KEPT -> {}
|
||||
}
|
||||
}
|
||||
|
||||
+102
-54
@@ -48,13 +48,11 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.pluralStringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbol
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
@@ -63,6 +61,53 @@ import com.vitorpamplona.amethyst.commons.model.backups.ReplaceableBackupConflic
|
||||
import com.vitorpamplona.amethyst.commons.model.cache.LocalCache
|
||||
import com.vitorpamplona.amethyst.commons.model.navigation.Route
|
||||
import com.vitorpamplona.amethyst.commons.model.navigation.routeFor
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_allowed_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_concord_body
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_demoted_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_dropped_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_encrypted_added
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_encrypted_changed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_encrypted_cleared
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_feed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_hashtags_you_follow
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_joined
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_kept
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_left
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_left_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_listed_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_moved_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_new
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_new_count_caption
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_new_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_newly_blocked
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_no_longer_blocked
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_offer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_offers_gone
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_payment_targets_gone
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_payments_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_places_gone
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_places_you_follow
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_receiving_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_saved
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_searching_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_service
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_service_followers
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_service_rank
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_service_topics
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_services_changed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_services_changed_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_still_blocked
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_storing_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_topics_gone
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_trust_warning
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_trusted_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_unblocked
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_unblocked_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_untrusted_tag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_wallet_body
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_communities
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_public_chats
|
||||
import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.commons.ui.screen.LocalDisplaySettings
|
||||
@@ -118,6 +163,9 @@ import com.vitorpamplona.quartz.nip85TrustedAssertions.list.TrustProviderListEve
|
||||
import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListDiff
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import org.jetbrains.compose.resources.PluralStringResource
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.pluralStringResource
|
||||
|
||||
/**
|
||||
* Per-event layouts for the account's other lists: each relay list framed by what it is
|
||||
@@ -142,8 +190,8 @@ internal fun LazyListScope.listDiffItems(
|
||||
is TrustProviderListDiff -> trustProviderItems(diff, conflict, accountViewModel, nav)
|
||||
is PaymentTargetsDiff -> paymentTargetItems(diff, conflict)
|
||||
is Bolt12OfferListDiff -> offerItems(diff, conflict)
|
||||
is CashuWalletDiff -> encryptedOnlyItems(MaterialSymbols.AccountBalanceWallet, diff.wallet, R.string.backup_review_wallet_body)
|
||||
is ConcordCommunityListDiff -> encryptedOnlyItems(MaterialSymbols.Groups, diff.communities, R.string.backup_review_concord_body)
|
||||
is CashuWalletDiff -> encryptedOnlyItems(MaterialSymbols.AccountBalanceWallet, diff.wallet, Res.string.backup_review_wallet_body)
|
||||
is ConcordCommunityListDiff -> encryptedOnlyItems(MaterialSymbols.Groups, diff.communities, Res.string.backup_review_concord_body)
|
||||
else -> return false
|
||||
}
|
||||
return true
|
||||
@@ -193,15 +241,15 @@ private fun fateColor(fate: ItemFate): Color {
|
||||
|
||||
private fun <T> LazyListScope.countTiles(
|
||||
items: List<Pair<T, ItemFate>>,
|
||||
removedCaption: Int,
|
||||
addedCaption: Int,
|
||||
removedCaption: StringResource,
|
||||
addedCaption: StringResource,
|
||||
) {
|
||||
item(key = "count-tiles", contentType = "tiles") {
|
||||
val tones = conflictTones()
|
||||
Row(Pad.padding(top = 8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
StatTile(items.count { it.second == ItemFate.DROPPED }.toString(), stringRes(removedCaption), tones.removed, Modifier.weight(1f))
|
||||
StatTile(items.count { it.second == ItemFate.ADDED }.toString(), stringRes(addedCaption), tones.added, Modifier.weight(1f))
|
||||
StatTile(items.count { it.second == ItemFate.KEPT || it.second == ItemFate.CHANGED }.toString(), stringRes(R.string.backup_review_kept), tones.kept, Modifier.weight(1f))
|
||||
StatTile(items.count { it.second == ItemFate.KEPT || it.second == ItemFate.CHANGED }.toString(), stringRes(Res.string.backup_review_kept), tones.kept, Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,20 +266,20 @@ private fun LazyListScope.privateItemsCard(change: ContentChange) {
|
||||
/** How a relay list's rows are presented: its icon and what a kept or dropped relay is called. */
|
||||
private class RelayFraming(
|
||||
val icon: MaterialSymbol,
|
||||
val keptTag: Int,
|
||||
val droppedTag: Int = R.string.backup_review_dropped_tag,
|
||||
val keptTag: StringResource,
|
||||
val droppedTag: StringResource = Res.string.backup_review_dropped_tag,
|
||||
)
|
||||
|
||||
private fun framingOf(type: BackupEventType): RelayFraming =
|
||||
when (type) {
|
||||
BackupEventType.DM_RELAYS -> RelayFraming(MaterialSymbols.Mail, R.string.backup_review_receiving_tag)
|
||||
BackupEventType.KEY_PACKAGE_RELAYS -> RelayFraming(MaterialSymbols.Key, R.string.backup_review_listed_tag)
|
||||
BackupEventType.SEARCH_RELAYS -> RelayFraming(MaterialSymbols.Search, R.string.backup_review_searching_tag)
|
||||
BackupEventType.INDEXER_RELAYS -> RelayFraming(MaterialSymbols.Dns, R.string.backup_review_listed_tag)
|
||||
BackupEventType.RELAY_FEEDS -> RelayFraming(MaterialSymbols.CellTower, R.string.backup_review_listed_tag)
|
||||
BackupEventType.PRIVATE_OUTBOX_RELAYS -> RelayFraming(MaterialSymbols.Lock, R.string.backup_review_storing_tag)
|
||||
BackupEventType.TRUSTED_RELAYS -> RelayFraming(MaterialSymbols.Shield, R.string.backup_review_trusted_tag, R.string.backup_review_untrusted_tag)
|
||||
else -> RelayFraming(MaterialSymbols.Dns, R.string.backup_review_listed_tag)
|
||||
BackupEventType.DM_RELAYS -> RelayFraming(MaterialSymbols.Mail, Res.string.backup_review_receiving_tag)
|
||||
BackupEventType.KEY_PACKAGE_RELAYS -> RelayFraming(MaterialSymbols.Key, Res.string.backup_review_listed_tag)
|
||||
BackupEventType.SEARCH_RELAYS -> RelayFraming(MaterialSymbols.Search, Res.string.backup_review_searching_tag)
|
||||
BackupEventType.INDEXER_RELAYS -> RelayFraming(MaterialSymbols.Dns, Res.string.backup_review_listed_tag)
|
||||
BackupEventType.RELAY_FEEDS -> RelayFraming(MaterialSymbols.CellTower, Res.string.backup_review_listed_tag)
|
||||
BackupEventType.PRIVATE_OUTBOX_RELAYS -> RelayFraming(MaterialSymbols.Lock, Res.string.backup_review_storing_tag)
|
||||
BackupEventType.TRUSTED_RELAYS -> RelayFraming(MaterialSymbols.Shield, Res.string.backup_review_trusted_tag, Res.string.backup_review_untrusted_tag)
|
||||
else -> RelayFraming(MaterialSymbols.Dns, Res.string.backup_review_listed_tag)
|
||||
}
|
||||
|
||||
private fun savedRelaysOf(event: Event): List<NormalizedRelayUrl> =
|
||||
@@ -277,8 +325,8 @@ private fun RelayFateRow(
|
||||
when (fate) {
|
||||
ItemFate.KEPT -> framing.keptTag
|
||||
ItemFate.DROPPED -> framing.droppedTag
|
||||
ItemFate.ADDED -> R.string.backup_review_new_tag
|
||||
ItemFate.CHANGED -> R.string.backup_review_demoted_tag
|
||||
ItemFate.ADDED -> Res.string.backup_review_new_tag
|
||||
ItemFate.CHANGED -> Res.string.backup_review_demoted_tag
|
||||
}
|
||||
Row(
|
||||
Pad
|
||||
@@ -320,14 +368,14 @@ private fun LazyListScope.blockedRelayItems(
|
||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
Icon(symbol = MaterialSymbols.LockOpen, contentDescription = null, tint = tones.changed, modifier = Modifier.size(44.dp))
|
||||
Column {
|
||||
Text(stringRes(R.string.backup_review_unblocked, unblocked.size.toString()), fontSize = 30.sp, lineHeight = 32.sp, fontWeight = FontWeight.Bold, color = tones.changed)
|
||||
Text(stringRes(R.string.backup_review_unblocked_explainer), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.placeholderText)
|
||||
Text(stringRes(Res.string.backup_review_unblocked, unblocked.size.toString()), fontSize = 30.sp, lineHeight = 32.sp, fontWeight = FontWeight.Bold, color = tones.changed)
|
||||
Text(stringRes(Res.string.backup_review_unblocked_explainer), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.placeholderText)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unblocked.isNotEmpty()) {
|
||||
item(key = "unblocked-caption", contentType = "caption") { SectionCaption(stringRes(R.string.backup_review_no_longer_blocked), Pad.padding(top = 18.dp)) }
|
||||
item(key = "unblocked-caption", contentType = "caption") { SectionCaption(stringRes(Res.string.backup_review_no_longer_blocked), Pad.padding(top = 18.dp)) }
|
||||
items(unblocked, key = { "unblocked-" + it.url }, contentType = { "relay-row" }) { url ->
|
||||
val tones = conflictTones()
|
||||
Row(
|
||||
@@ -346,12 +394,12 @@ private fun LazyListScope.blockedRelayItems(
|
||||
Icon(symbol = MaterialSymbols.LockOpen, contentDescription = null, tint = tones.changed, modifier = Modifier.size(18.dp))
|
||||
}
|
||||
Text(url.url.removePrefix("wss://").removeSuffix("/"), modifier = Modifier.weight(1f), style = MaterialTheme.typography.bodyMedium, fontWeight = FontWeight.SemiBold, maxLines = 1, overflow = TextOverflow.Ellipsis)
|
||||
StatusTag(stringRes(R.string.backup_review_allowed_tag), tones.changed)
|
||||
StatusTag(stringRes(Res.string.backup_review_allowed_tag), tones.changed)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newlyBlocked.isNotEmpty()) {
|
||||
item(key = "newly-blocked-caption", contentType = "caption") { SectionCaption(stringRes(R.string.backup_review_newly_blocked), Pad.padding(top = 18.dp)) }
|
||||
item(key = "newly-blocked-caption", contentType = "caption") { SectionCaption(stringRes(Res.string.backup_review_newly_blocked), Pad.padding(top = 18.dp)) }
|
||||
items(newlyBlocked, key = { "newly-blocked-" + it.url }, contentType = { "relay-row" }) { url ->
|
||||
RelayFateRow(url, ItemFate.ADDED, framingOf(BackupEventType.BLOCKED_RELAYS), nav)
|
||||
}
|
||||
@@ -359,7 +407,7 @@ private fun LazyListScope.blockedRelayItems(
|
||||
if (stillBlocked.isNotEmpty()) {
|
||||
item(key = "still-blocked", contentType = "chips") {
|
||||
Column(Pad.padding(top = 18.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
SectionCaption(stringRes(R.string.backup_review_still_blocked))
|
||||
SectionCaption(stringRes(Res.string.backup_review_still_blocked))
|
||||
FlowRow(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
stillBlocked.forEach { url ->
|
||||
Row(
|
||||
@@ -392,7 +440,7 @@ private fun <T> LazyListScope.spaceGrid(
|
||||
key: (T) -> String,
|
||||
content: @Composable (T, ItemFate, Modifier) -> Unit,
|
||||
) {
|
||||
countTiles(items, R.string.backup_review_left, R.string.backup_review_joined)
|
||||
countTiles(items, Res.string.backup_review_left, Res.string.backup_review_joined)
|
||||
items(items.chunked(2), key = { keyPrefix + key(it.first().first) }, contentType = { "space-row" }) { row ->
|
||||
Row(Pad.padding(top = 10.dp).fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
row.forEach { (item, fate) -> content(item, fate, Modifier.weight(1f)) }
|
||||
@@ -436,9 +484,9 @@ private fun SpaceTile(
|
||||
}
|
||||
val tag =
|
||||
when (fate) {
|
||||
ItemFate.DROPPED -> R.string.backup_review_left_tag to tones.removed
|
||||
ItemFate.ADDED -> R.string.backup_review_new_tag to tones.added
|
||||
ItemFate.CHANGED -> R.string.backup_review_moved_tag to tones.changed
|
||||
ItemFate.DROPPED -> Res.string.backup_review_left_tag to tones.removed
|
||||
ItemFate.ADDED -> Res.string.backup_review_new_tag to tones.added
|
||||
ItemFate.CHANGED -> Res.string.backup_review_moved_tag to tones.changed
|
||||
ItemFate.KEPT -> null
|
||||
}
|
||||
tag?.let { (res, color) -> StatusTag(stringRes(res), color, Modifier.align(Alignment.TopEnd)) }
|
||||
@@ -459,7 +507,7 @@ private fun LazyListScope.publicChatItems(
|
||||
val current = state?.channel ?: channel
|
||||
SpaceTile(
|
||||
name = current.toBestDisplayName(),
|
||||
subtitle = stringRes(R.string.backup_type_public_chats),
|
||||
subtitle = stringRes(Res.string.backup_type_public_chats),
|
||||
robot = tag.eventId,
|
||||
picture = channel.profilePicture(),
|
||||
fate = fate,
|
||||
@@ -525,7 +573,7 @@ private fun AddressableSpaceTile(
|
||||
}
|
||||
SpaceTile(
|
||||
name = name ?: address.dTag.ifBlank { address.toValue().toShortDisplay() },
|
||||
subtitle = stringRes(if (address.kind == AppDefinitionEvent.KIND) R.string.backup_review_feed else R.string.backup_type_communities),
|
||||
subtitle = stringRes(if (address.kind == AppDefinitionEvent.KIND) Res.string.backup_review_feed else Res.string.backup_type_communities),
|
||||
robot = address.toValue(),
|
||||
picture = picture,
|
||||
fate = fate,
|
||||
@@ -543,7 +591,7 @@ private fun LazyListScope.ephemeralRoomItems(
|
||||
) {
|
||||
val saved = (conflict.saved as? EphemeralChatListEvent)?.publicRooms().orEmpty()
|
||||
val rooms = fates(saved, diff.rooms) { it }
|
||||
countTiles(rooms, R.string.backup_review_left, R.string.backup_review_joined)
|
||||
countTiles(rooms, Res.string.backup_review_left, Res.string.backup_review_joined)
|
||||
items(rooms, key = { "room-" + it.first.toKey() }, contentType = { "room-row" }) { (room, fate) -> RoomRow(room, fate, nav) }
|
||||
privateItemsCard(diff.privateItems)
|
||||
}
|
||||
@@ -582,8 +630,8 @@ private fun RoomRow(
|
||||
)
|
||||
}
|
||||
when (fate) {
|
||||
ItemFate.DROPPED -> StatusTag(stringRes(R.string.backup_review_left_tag), color)
|
||||
ItemFate.ADDED -> StatusTag(stringRes(R.string.backup_review_new_tag), color)
|
||||
ItemFate.DROPPED -> StatusTag(stringRes(Res.string.backup_review_left_tag), color)
|
||||
ItemFate.ADDED -> StatusTag(stringRes(Res.string.backup_review_new_tag), color)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@@ -602,11 +650,11 @@ private fun LazyListScope.topicItems(
|
||||
nav: INav,
|
||||
) {
|
||||
val topics = fates(saved, diff) { it.lowercase() }
|
||||
countTiles(topics, if (isPlace) R.string.backup_review_places_gone else R.string.backup_review_topics_gone, R.string.backup_review_new_count_caption)
|
||||
countTiles(topics, if (isPlace) Res.string.backup_review_places_gone else Res.string.backup_review_topics_gone, Res.string.backup_review_new_count_caption)
|
||||
item(key = "topic-cloud", contentType = "cloud") {
|
||||
val tones = conflictTones()
|
||||
Column(Pad.padding(top = 18.dp), verticalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
SectionCaption(stringRes(if (isPlace) R.string.backup_review_places_you_follow else R.string.backup_review_hashtags_you_follow))
|
||||
SectionCaption(stringRes(if (isPlace) Res.string.backup_review_places_you_follow else Res.string.backup_review_hashtags_you_follow))
|
||||
FlowRow(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp), itemVerticalAlignment = Alignment.CenterVertically) {
|
||||
topics.forEach { (topic, fate) ->
|
||||
val color = fateColor(fate)
|
||||
@@ -706,15 +754,15 @@ private fun LazyListScope.trustProviderItems(
|
||||
Icon(symbol = MaterialSymbols.Group, contentDescription = null, tint = tones.changed)
|
||||
}
|
||||
Column {
|
||||
Text(stringRes(R.string.backup_review_services_changed, affected.toString(), services.size.toString()), fontSize = 24.sp, lineHeight = 28.sp, fontWeight = FontWeight.Bold)
|
||||
Text(stringRes(R.string.backup_review_services_changed_explainer), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.placeholderText)
|
||||
Text(stringRes(Res.string.backup_review_services_changed, affected.toString(), services.size.toString()), fontSize = 24.sp, lineHeight = 28.sp, fontWeight = FontWeight.Bold)
|
||||
Text(stringRes(Res.string.backup_review_services_changed_explainer), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.placeholderText)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
item(key = "trust-header", contentType = "table-header") {
|
||||
Row(Pad.padding(top = 16.dp, bottom = 4.dp).padding(horizontal = 12.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
listOf(R.string.backup_review_service, R.string.backup_review_saved, R.string.backup_review_new).forEachIndexed { index, res ->
|
||||
listOf(Res.string.backup_review_service, Res.string.backup_review_saved, Res.string.backup_review_new).forEachIndexed { index, res ->
|
||||
Text(stringRes(res).uppercase(), Modifier.weight(if (index == 0) 1.1f else 1f), style = MaterialTheme.typography.labelSmall, fontWeight = FontWeight.Bold, color = MaterialTheme.colorScheme.placeholderText)
|
||||
}
|
||||
}
|
||||
@@ -732,7 +780,7 @@ private fun LazyListScope.trustProviderItems(
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
Icon(symbol = MaterialSymbols.Warning, contentDescription = null, tint = tones.changed, modifier = Modifier.size(18.dp))
|
||||
Text(stringRes(R.string.backup_review_trust_warning), style = MaterialTheme.typography.bodySmall, color = tones.changed)
|
||||
Text(stringRes(Res.string.backup_review_trust_warning), style = MaterialTheme.typography.bodySmall, color = tones.changed)
|
||||
}
|
||||
}
|
||||
privateItemsCard(diff.privateItems)
|
||||
@@ -771,9 +819,9 @@ private fun ServiceTableRow(
|
||||
@Composable
|
||||
private fun serviceLabel(type: String): String =
|
||||
when (type) {
|
||||
"rank" -> stringRes(R.string.backup_review_service_rank)
|
||||
"followers" -> stringRes(R.string.backup_review_service_followers)
|
||||
"t" -> stringRes(R.string.backup_review_service_topics)
|
||||
"rank" -> stringRes(Res.string.backup_review_service_rank)
|
||||
"followers" -> stringRes(Res.string.backup_review_service_followers)
|
||||
"t" -> stringRes(Res.string.backup_review_service_topics)
|
||||
else -> type.replace('_', ' ').replaceFirstChar { it.uppercase() }
|
||||
}
|
||||
|
||||
@@ -826,7 +874,7 @@ private fun LazyListScope.paymentTargetItems(
|
||||
) {
|
||||
val saved = (conflict.saved as? PaymentTargetsEvent)?.paymentTargets().orEmpty()
|
||||
val targets = fates(saved, diff.targets) { it }
|
||||
moneyHero(targets.count { it.second == ItemFate.DROPPED }, R.plurals.backup_review_payment_targets_gone)
|
||||
moneyHero(targets.count { it.second == ItemFate.DROPPED }, Res.plurals.backup_review_payment_targets_gone)
|
||||
items(targets, key = { "target-" + it.first.type + ":" + it.first.authority }, contentType = { "money-row" }) { (target, fate) -> PaymentTargetRow(target, fate) }
|
||||
}
|
||||
|
||||
@@ -836,15 +884,15 @@ private fun LazyListScope.offerItems(
|
||||
) {
|
||||
val saved = (conflict.saved as? Bolt12OfferListEvent)?.offers().orEmpty()
|
||||
val offers = fates(saved, diff.offers) { it }
|
||||
moneyHero(offers.count { it.second == ItemFate.DROPPED }, R.plurals.backup_review_offers_gone)
|
||||
moneyHero(offers.count { it.second == ItemFate.DROPPED }, Res.plurals.backup_review_offers_gone)
|
||||
items(offers, key = { "offer-" + it.first }, contentType = { "money-row" }) { (offer, fate) ->
|
||||
MoneyRow(stringRes(R.string.backup_review_offer), offer.toShortDisplay(prefixSize = 4), fate)
|
||||
MoneyRow(stringRes(Res.string.backup_review_offer), offer.toShortDisplay(prefixSize = 4), fate)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyListScope.moneyHero(
|
||||
dropped: Int,
|
||||
headline: Int,
|
||||
headline: PluralStringResource,
|
||||
) {
|
||||
item(key = "money-hero", contentType = "hero") {
|
||||
val tones = conflictTones()
|
||||
@@ -856,7 +904,7 @@ private fun LazyListScope.moneyHero(
|
||||
}
|
||||
Column {
|
||||
Text(pluralStringResource(headline, dropped, dropped), fontSize = 24.sp, lineHeight = 28.sp, fontWeight = FontWeight.Bold, color = color)
|
||||
Text(stringRes(R.string.backup_review_payments_explainer), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.placeholderText)
|
||||
Text(stringRes(Res.string.backup_review_payments_explainer), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.placeholderText)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -902,8 +950,8 @@ private fun MoneyRow(
|
||||
)
|
||||
}
|
||||
when (fate) {
|
||||
ItemFate.DROPPED -> StatusTag(stringRes(R.string.backup_review_dropped_tag), color)
|
||||
ItemFate.ADDED -> StatusTag(stringRes(R.string.backup_review_new_tag), color)
|
||||
ItemFate.DROPPED -> StatusTag(stringRes(Res.string.backup_review_dropped_tag), color)
|
||||
ItemFate.ADDED -> StatusTag(stringRes(Res.string.backup_review_new_tag), color)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@@ -916,15 +964,15 @@ private fun MoneyRow(
|
||||
private fun LazyListScope.encryptedOnlyItems(
|
||||
icon: MaterialSymbol,
|
||||
change: ContentChange,
|
||||
body: Int,
|
||||
body: StringResource,
|
||||
) {
|
||||
item(key = "encrypted-hero", contentType = "hero") {
|
||||
val tones = conflictTones()
|
||||
val (color, headline) =
|
||||
when (change) {
|
||||
ContentChange.CLEARED -> tones.removed to R.string.backup_review_encrypted_cleared
|
||||
ContentChange.ADDED -> tones.added to R.string.backup_review_encrypted_added
|
||||
else -> tones.changed to R.string.backup_review_encrypted_changed
|
||||
ContentChange.CLEARED -> tones.removed to Res.string.backup_review_encrypted_cleared
|
||||
ContentChange.ADDED -> tones.added to Res.string.backup_review_encrypted_added
|
||||
else -> tones.changed to Res.string.backup_review_encrypted_changed
|
||||
}
|
||||
Column(Pad.padding(top = 8.dp), verticalArrangement = Arrangement.spacedBy(14.dp)) {
|
||||
TintedPanel(color.copy(alpha = 0.12f)) {
|
||||
|
||||
+221
-107
@@ -23,9 +23,98 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.backups
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalResources
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.model.backups.BackupEventType
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_relay_read_only
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_relay_read_write
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_relay_write_only
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_algo_feed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_chat_room
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_community
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_hashtag
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_identity_claim
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_location
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_mint
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_nutzap_key
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_offer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_other
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_payment_target
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_person
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_profile_field
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_public_chat
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_relay
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_relay_group
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_thread
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_trust_provider
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_entry_word
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_about
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_banner
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_birthday
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_bot
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_clink_offer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_display_name
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_lud06
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_lud16
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_name
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_nip05
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_picture
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_pronouns
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_profile_field_website
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_app_settings
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_app_settings_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_blocked_relays
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_blocked_relays_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_bolt12_offers
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_bolt12_offers_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_cashu_wallet
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_cashu_wallet_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_communities
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_communities_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_concord_communities
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_concord_communities_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_dm_relays
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_dm_relays_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_ephemeral_chats
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_ephemeral_chats_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_favorite_algo_feeds
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_favorite_algo_feeds_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_follow_list
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_follow_list_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_geohashes
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_geohashes_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_hashtags
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_hashtags_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_indexer_relays
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_indexer_relays_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_key_package_relays
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_key_package_relays_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_mute_list
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_mute_list_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_nutzap_info
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_nutzap_info_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_other
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_other_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_outbox_inbox_relays
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_outbox_inbox_relays_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_payment_targets
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_payment_targets_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_private_outbox_relays
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_private_outbox_relays_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_profile
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_profile_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_public_chats
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_public_chats_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_relay_feeds
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_relay_feeds_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_relay_groups
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_relay_groups_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_search_relays
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_search_relays_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_trust_providers
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_trust_providers_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_trusted_relays
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_type_trusted_relays_explainer
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.concord.cord02Community.ConcordCommunityListDiff
|
||||
import com.vitorpamplona.quartz.experimental.ephemChat.chat.RoomId
|
||||
import com.vitorpamplona.quartz.experimental.ephemChat.list.EphemeralChatListDiff
|
||||
@@ -61,6 +150,7 @@ import com.vitorpamplona.quartz.nip72ModCommunities.follow.CommunityListDiff
|
||||
import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataDiff
|
||||
import com.vitorpamplona.quartz.nip85TrustedAssertions.list.TrustProviderListDiff
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListDiff
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
|
||||
private const val MAX_VALUE_LENGTH = 80
|
||||
|
||||
@@ -168,7 +258,7 @@ sealed interface ReviewItem {
|
||||
/** One labelled group of differences (people, relays, profile fields…) of a conflict. */
|
||||
@Immutable
|
||||
class DiffGroup(
|
||||
val label: Int,
|
||||
val label: StringResource,
|
||||
val removed: List<ReviewItem>,
|
||||
val added: List<ReviewItem>,
|
||||
val changed: List<ReviewItem>,
|
||||
@@ -189,7 +279,7 @@ class DiffPresentation(
|
||||
|
||||
/** A group from a [ListDiff] of an event's parsed items. */
|
||||
private fun <T> listGroup(
|
||||
label: Int,
|
||||
label: StringResource,
|
||||
diff: ListDiff<T>,
|
||||
item: (T) -> ReviewItem,
|
||||
change: (ItemChange<T>) -> ReviewItem,
|
||||
@@ -197,7 +287,7 @@ private fun <T> listGroup(
|
||||
|
||||
/** A group whose items can't change, only be added or removed (hashtags, plain relays…). */
|
||||
private fun <T> listGroup(
|
||||
label: Int,
|
||||
label: StringResource,
|
||||
diff: ListDiff<T>,
|
||||
item: (T) -> ReviewItem,
|
||||
) = listGroup(label, diff, item) { item(it.after) }
|
||||
@@ -212,7 +302,7 @@ private inline fun <reified T> ListDiff<*>.only() =
|
||||
|
||||
/** A group from single-valued fields: a field set only after is added, only before is removed. */
|
||||
private fun fieldGroup(
|
||||
label: Int,
|
||||
label: StringResource,
|
||||
fields: List<Pair<String, ValueChange<String>?>>,
|
||||
): DiffGroup {
|
||||
val removed = mutableListOf<ReviewItem>()
|
||||
@@ -242,14 +332,38 @@ private fun arrow(
|
||||
*/
|
||||
@Composable
|
||||
fun rememberPresentation(diff: EventDiff): DiffPresentation {
|
||||
val resources = LocalResources.current
|
||||
return remember(diff, resources) { presentationOf(diff) { resources.getString(it) } }
|
||||
// Compose resources resolve only in composition (or suspended), so the few labels
|
||||
// [presentationOf] writes into item text are resolved here and handed in. The map
|
||||
// compares by value, so a recomposition with the same locale keeps the cached result.
|
||||
val labels = PRESENTATION_LABELS.associateWith { stringRes(it) }
|
||||
return remember(diff, labels) { presentationOf(diff) { labels.getValue(it) } }
|
||||
}
|
||||
|
||||
/** Every label [presentationOf] resolves through its `str` parameter. */
|
||||
private val PRESENTATION_LABELS =
|
||||
listOf(
|
||||
Res.string.backup_profile_field_name,
|
||||
Res.string.backup_profile_field_display_name,
|
||||
Res.string.backup_profile_field_about,
|
||||
Res.string.backup_profile_field_picture,
|
||||
Res.string.backup_profile_field_banner,
|
||||
Res.string.backup_profile_field_website,
|
||||
Res.string.backup_profile_field_nip05,
|
||||
Res.string.backup_profile_field_lud16,
|
||||
Res.string.backup_profile_field_lud06,
|
||||
Res.string.backup_profile_field_clink_offer,
|
||||
Res.string.backup_profile_field_pronouns,
|
||||
Res.string.backup_profile_field_birthday,
|
||||
Res.string.backup_profile_field_bot,
|
||||
Res.string.backup_conflict_relay_read_write,
|
||||
Res.string.backup_conflict_relay_read_only,
|
||||
Res.string.backup_conflict_relay_write_only,
|
||||
)
|
||||
|
||||
/** Turns each event's own diff into typed, labelled groups. [str] resolves the labels. */
|
||||
fun presentationOf(
|
||||
diff: EventDiff,
|
||||
str: (Int) -> String,
|
||||
str: (StringResource) -> String,
|
||||
): DiffPresentation {
|
||||
val (groups, content) =
|
||||
when (diff) {
|
||||
@@ -258,31 +372,31 @@ fun presentationOf(
|
||||
val bot = diff.bot?.let { ValueChange(it.before?.toString(), it.after?.toString()) }
|
||||
listOf(
|
||||
fieldGroup(
|
||||
R.string.backup_entry_profile_field,
|
||||
Res.string.backup_entry_profile_field,
|
||||
listOf(
|
||||
str(R.string.backup_profile_field_name) to diff.name,
|
||||
str(R.string.backup_profile_field_display_name) to diff.displayName,
|
||||
str(R.string.backup_profile_field_about) to diff.about,
|
||||
str(R.string.backup_profile_field_picture) to diff.picture,
|
||||
str(R.string.backup_profile_field_banner) to diff.banner,
|
||||
str(R.string.backup_profile_field_website) to diff.website,
|
||||
str(R.string.backup_profile_field_nip05) to diff.nip05,
|
||||
str(R.string.backup_profile_field_lud16) to diff.lud16,
|
||||
str(R.string.backup_profile_field_lud06) to diff.lud06,
|
||||
str(R.string.backup_profile_field_clink_offer) to diff.clinkOffer,
|
||||
str(R.string.backup_profile_field_pronouns) to diff.pronouns,
|
||||
str(R.string.backup_profile_field_birthday) to birthday,
|
||||
str(R.string.backup_profile_field_bot) to bot,
|
||||
str(Res.string.backup_profile_field_name) to diff.name,
|
||||
str(Res.string.backup_profile_field_display_name) to diff.displayName,
|
||||
str(Res.string.backup_profile_field_about) to diff.about,
|
||||
str(Res.string.backup_profile_field_picture) to diff.picture,
|
||||
str(Res.string.backup_profile_field_banner) to diff.banner,
|
||||
str(Res.string.backup_profile_field_website) to diff.website,
|
||||
str(Res.string.backup_profile_field_nip05) to diff.nip05,
|
||||
str(Res.string.backup_profile_field_lud16) to diff.lud16,
|
||||
str(Res.string.backup_profile_field_lud06) to diff.lud06,
|
||||
str(Res.string.backup_profile_field_clink_offer) to diff.clinkOffer,
|
||||
str(Res.string.backup_profile_field_pronouns) to diff.pronouns,
|
||||
str(Res.string.backup_profile_field_birthday) to birthday,
|
||||
str(Res.string.backup_profile_field_bot) to bot,
|
||||
),
|
||||
),
|
||||
listGroup(
|
||||
R.string.backup_entry_identity_claim,
|
||||
Res.string.backup_entry_identity_claim,
|
||||
diff.identityClaims,
|
||||
{ ReviewItem.Text(it.platformIdentity()) },
|
||||
{ ReviewItem.Text(it.after.platformIdentity(), arrow(it.before.proof, it.after.proof)) },
|
||||
),
|
||||
listGroup(
|
||||
R.string.backup_entry_other,
|
||||
Res.string.backup_entry_other,
|
||||
diff.otherFields,
|
||||
{ ReviewItem.Text(it.first, clip(it.second)) },
|
||||
{ ReviewItem.Text(it.after.first, clip(it.before.second) + " → " + clip(it.after.second)) },
|
||||
@@ -292,7 +406,7 @@ fun presentationOf(
|
||||
is ContactListDiff ->
|
||||
listOf(
|
||||
listGroup(
|
||||
R.string.backup_entry_person,
|
||||
Res.string.backup_entry_person,
|
||||
diff.follows,
|
||||
{ ReviewItem.Person(it.pubKey, it.petname) },
|
||||
{
|
||||
@@ -308,32 +422,32 @@ fun presentationOf(
|
||||
) to ContentChange.NONE
|
||||
is MuteListDiff ->
|
||||
listOf(
|
||||
listGroup(R.string.backup_entry_person, diff.publicMutes.only<UserTag>(), { ReviewItem.Person(it.pubKey) }),
|
||||
listGroup(R.string.backup_entry_word, diff.publicMutes.only<WordTag>(), { ReviewItem.Text("\"" + it.word + "\"") }),
|
||||
listGroup(R.string.backup_entry_hashtag, diff.publicMutes.only<HashtagTag>(), { ReviewItem.Text("#" + it.hashtag) }),
|
||||
listGroup(R.string.backup_entry_thread, diff.publicMutes.only<EventTag>(), { ReviewItem.Thread(it.eventId) }),
|
||||
listGroup(Res.string.backup_entry_person, diff.publicMutes.only<UserTag>(), { ReviewItem.Person(it.pubKey) }),
|
||||
listGroup(Res.string.backup_entry_word, diff.publicMutes.only<WordTag>(), { ReviewItem.Text("\"" + it.word + "\"") }),
|
||||
listGroup(Res.string.backup_entry_hashtag, diff.publicMutes.only<HashtagTag>(), { ReviewItem.Text("#" + it.hashtag) }),
|
||||
listGroup(Res.string.backup_entry_thread, diff.publicMutes.only<EventTag>(), { ReviewItem.Thread(it.eventId) }),
|
||||
) to diff.privateItems
|
||||
is AdvertisedRelayListDiff -> {
|
||||
val types =
|
||||
mapOf(
|
||||
AdvertisedRelayType.BOTH to str(R.string.backup_conflict_relay_read_write),
|
||||
AdvertisedRelayType.READ to str(R.string.backup_conflict_relay_read_only),
|
||||
AdvertisedRelayType.WRITE to str(R.string.backup_conflict_relay_write_only),
|
||||
AdvertisedRelayType.BOTH to str(Res.string.backup_conflict_relay_read_write),
|
||||
AdvertisedRelayType.READ to str(Res.string.backup_conflict_relay_read_only),
|
||||
AdvertisedRelayType.WRITE to str(Res.string.backup_conflict_relay_write_only),
|
||||
)
|
||||
listOf(
|
||||
listGroup(
|
||||
R.string.backup_entry_relay,
|
||||
Res.string.backup_entry_relay,
|
||||
diff.relays,
|
||||
{ ReviewItem.Relay(it.relayUrl, types[it.type]) },
|
||||
{ ReviewItem.Relay(it.after.relayUrl, arrow(types[it.before.type], types[it.after.type])) },
|
||||
),
|
||||
) to ContentChange.NONE
|
||||
}
|
||||
is RelayListDiff -> listOf(listGroup(R.string.backup_entry_relay, diff.relays, { ReviewItem.Relay(it) })) to diff.privateRelays
|
||||
is RelayListDiff -> listOf(listGroup(Res.string.backup_entry_relay, diff.relays, { ReviewItem.Relay(it) })) to diff.privateRelays
|
||||
is ChannelListDiff ->
|
||||
listOf(
|
||||
listGroup(
|
||||
R.string.backup_entry_public_chat,
|
||||
Res.string.backup_entry_public_chat,
|
||||
diff.channels,
|
||||
{ ReviewItem.PublicChat(it.eventId) },
|
||||
{ ReviewItem.PublicChat(it.after.eventId, arrow(it.before.relay?.url, it.after.relay?.url)) },
|
||||
@@ -342,28 +456,28 @@ fun presentationOf(
|
||||
is CommunityListDiff ->
|
||||
listOf(
|
||||
listGroup(
|
||||
R.string.backup_entry_community,
|
||||
Res.string.backup_entry_community,
|
||||
diff.communities,
|
||||
{ ReviewItem.Addressable(it.address) },
|
||||
{ ReviewItem.Addressable(it.after.address, arrow(it.before.relayHint?.url, it.after.relayHint?.url)) },
|
||||
),
|
||||
) to diff.privateItems
|
||||
is HashtagListDiff -> listOf(listGroup(R.string.backup_entry_hashtag, diff.hashtags, { ReviewItem.Text("#$it") })) to diff.privateItems
|
||||
is GeohashListDiff -> listOf(listGroup(R.string.backup_entry_location, diff.geohashes, { ReviewItem.Text(it) })) to diff.privateItems
|
||||
is HashtagListDiff -> listOf(listGroup(Res.string.backup_entry_hashtag, diff.hashtags, { ReviewItem.Text("#$it") })) to diff.privateItems
|
||||
is GeohashListDiff -> listOf(listGroup(Res.string.backup_entry_location, diff.geohashes, { ReviewItem.Text(it) })) to diff.privateItems
|
||||
is FavoriteAlgoFeedsListDiff ->
|
||||
listOf(
|
||||
listGroup(
|
||||
R.string.backup_entry_algo_feed,
|
||||
Res.string.backup_entry_algo_feed,
|
||||
diff.feeds,
|
||||
{ ReviewItem.Addressable(it.address) },
|
||||
{ ReviewItem.Addressable(it.after.address, arrow(it.before.relayHint?.url, it.after.relayHint?.url)) },
|
||||
),
|
||||
) to diff.privateItems
|
||||
is EphemeralChatListDiff -> listOf(listGroup(R.string.backup_entry_chat_room, diff.rooms, { ReviewItem.ChatRoom(it) })) to diff.privateItems
|
||||
is EphemeralChatListDiff -> listOf(listGroup(Res.string.backup_entry_chat_room, diff.rooms, { ReviewItem.ChatRoom(it) })) to diff.privateItems
|
||||
is SimpleGroupListDiff ->
|
||||
listOf(
|
||||
listGroup(
|
||||
R.string.backup_entry_relay_group,
|
||||
Res.string.backup_entry_relay_group,
|
||||
diff.groups,
|
||||
{ ReviewItem.Text(it.name ?: it.groupId, it.relayUrl) },
|
||||
{ ReviewItem.Text(it.after.name ?: it.after.groupId, arrow(it.before.name, it.after.name)) },
|
||||
@@ -372,7 +486,7 @@ fun presentationOf(
|
||||
is TrustProviderListDiff ->
|
||||
listOf(
|
||||
listGroup(
|
||||
R.string.backup_entry_trust_provider,
|
||||
Res.string.backup_entry_trust_provider,
|
||||
diff.providers,
|
||||
{ ReviewItem.Person(it.pubkey, it.service.type) },
|
||||
{ ReviewItem.Person(it.after.pubkey, it.after.service.type + ": " + arrow(it.before.relayUrl.url, it.after.relayUrl.url)) },
|
||||
@@ -381,19 +495,19 @@ fun presentationOf(
|
||||
is NutzapInfoDiff ->
|
||||
listOf(
|
||||
listGroup(
|
||||
R.string.backup_entry_mint,
|
||||
Res.string.backup_entry_mint,
|
||||
diff.mints,
|
||||
{ ReviewItem.Text(it.mintUrl, it.units.joinToString().ifEmpty { null }) },
|
||||
{ ReviewItem.Text(it.after.mintUrl, arrow(it.before.units.joinToString(), it.after.units.joinToString())) },
|
||||
),
|
||||
listGroup(R.string.backup_entry_relay, diff.relays, { ReviewItem.Relay(it) }),
|
||||
listGroup(Res.string.backup_entry_relay, diff.relays, { ReviewItem.Relay(it) }),
|
||||
nutzapKeyGroup(diff.p2pkPubkey),
|
||||
) to ContentChange.NONE
|
||||
is PaymentTargetsDiff ->
|
||||
listOf(
|
||||
listGroup(R.string.backup_entry_payment_target, diff.targets, { ReviewItem.Text(it.type, clip(it.authority)) }),
|
||||
listGroup(Res.string.backup_entry_payment_target, diff.targets, { ReviewItem.Text(it.type, clip(it.authority)) }),
|
||||
) to ContentChange.NONE
|
||||
is Bolt12OfferListDiff -> listOf(listGroup(R.string.backup_entry_offer, diff.offers, { ReviewItem.Text(clip(it)) })) to ContentChange.NONE
|
||||
is Bolt12OfferListDiff -> listOf(listGroup(Res.string.backup_entry_offer, diff.offers, { ReviewItem.Text(clip(it)) })) to ContentChange.NONE
|
||||
is CashuWalletDiff -> emptyList<DiffGroup>() to diff.wallet
|
||||
is ConcordCommunityListDiff -> emptyList<DiffGroup>() to diff.communities
|
||||
is AppSpecificDataDiff -> emptyList<DiffGroup>() to diff.data
|
||||
@@ -404,13 +518,13 @@ fun presentationOf(
|
||||
|
||||
private fun nutzapKeyGroup(change: ValueChange<HexKey>?): DiffGroup {
|
||||
val none = emptyList<ReviewItem>()
|
||||
if (change == null) return DiffGroup(R.string.backup_entry_nutzap_key, none, none, none)
|
||||
if (change == null) return DiffGroup(Res.string.backup_entry_nutzap_key, none, none, none)
|
||||
val before = change.before
|
||||
val after = change.after
|
||||
return when {
|
||||
before != null && after == null -> DiffGroup(R.string.backup_entry_nutzap_key, listOf(ReviewItem.Text(before)), none, none)
|
||||
before == null && after != null -> DiffGroup(R.string.backup_entry_nutzap_key, none, listOf(ReviewItem.Text(after)), none)
|
||||
else -> DiffGroup(R.string.backup_entry_nutzap_key, none, none, listOf(ReviewItem.Text(arrow(before, after))))
|
||||
before != null && after == null -> DiffGroup(Res.string.backup_entry_nutzap_key, listOf(ReviewItem.Text(before)), none, none)
|
||||
before == null && after != null -> DiffGroup(Res.string.backup_entry_nutzap_key, none, listOf(ReviewItem.Text(after)), none)
|
||||
else -> DiffGroup(Res.string.backup_entry_nutzap_key, none, none, listOf(ReviewItem.Text(arrow(before, after))))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,64 +536,64 @@ fun clip(text: String?): String {
|
||||
return if (oneLine.length > MAX_VALUE_LENGTH) oneLine.take(MAX_VALUE_LENGTH) + "…" else oneLine
|
||||
}
|
||||
|
||||
fun eventTypeName(type: BackupEventType): Int =
|
||||
fun eventTypeName(type: BackupEventType): StringResource =
|
||||
when (type) {
|
||||
BackupEventType.PROFILE -> R.string.backup_type_profile
|
||||
BackupEventType.FOLLOW_LIST -> R.string.backup_type_follow_list
|
||||
BackupEventType.MUTE_LIST -> R.string.backup_type_mute_list
|
||||
BackupEventType.OUTBOX_INBOX_RELAYS -> R.string.backup_type_outbox_inbox_relays
|
||||
BackupEventType.DM_RELAYS -> R.string.backup_type_dm_relays
|
||||
BackupEventType.KEY_PACKAGE_RELAYS -> R.string.backup_type_key_package_relays
|
||||
BackupEventType.SEARCH_RELAYS -> R.string.backup_type_search_relays
|
||||
BackupEventType.INDEXER_RELAYS -> R.string.backup_type_indexer_relays
|
||||
BackupEventType.RELAY_FEEDS -> R.string.backup_type_relay_feeds
|
||||
BackupEventType.BLOCKED_RELAYS -> R.string.backup_type_blocked_relays
|
||||
BackupEventType.TRUSTED_RELAYS -> R.string.backup_type_trusted_relays
|
||||
BackupEventType.PRIVATE_OUTBOX_RELAYS -> R.string.backup_type_private_outbox_relays
|
||||
BackupEventType.APP_SETTINGS -> R.string.backup_type_app_settings
|
||||
BackupEventType.PUBLIC_CHATS -> R.string.backup_type_public_chats
|
||||
BackupEventType.COMMUNITIES -> R.string.backup_type_communities
|
||||
BackupEventType.HASHTAGS -> R.string.backup_type_hashtags
|
||||
BackupEventType.GEOHASHES -> R.string.backup_type_geohashes
|
||||
BackupEventType.FAVORITE_ALGO_FEEDS -> R.string.backup_type_favorite_algo_feeds
|
||||
BackupEventType.EPHEMERAL_CHATS -> R.string.backup_type_ephemeral_chats
|
||||
BackupEventType.RELAY_GROUPS -> R.string.backup_type_relay_groups
|
||||
BackupEventType.CONCORD_COMMUNITIES -> R.string.backup_type_concord_communities
|
||||
BackupEventType.TRUST_PROVIDERS -> R.string.backup_type_trust_providers
|
||||
BackupEventType.CASHU_WALLET -> R.string.backup_type_cashu_wallet
|
||||
BackupEventType.NUTZAP_INFO -> R.string.backup_type_nutzap_info
|
||||
BackupEventType.PAYMENT_TARGETS -> R.string.backup_type_payment_targets
|
||||
BackupEventType.BOLT12_OFFERS -> R.string.backup_type_bolt12_offers
|
||||
BackupEventType.OTHER -> R.string.backup_type_other
|
||||
BackupEventType.PROFILE -> Res.string.backup_type_profile
|
||||
BackupEventType.FOLLOW_LIST -> Res.string.backup_type_follow_list
|
||||
BackupEventType.MUTE_LIST -> Res.string.backup_type_mute_list
|
||||
BackupEventType.OUTBOX_INBOX_RELAYS -> Res.string.backup_type_outbox_inbox_relays
|
||||
BackupEventType.DM_RELAYS -> Res.string.backup_type_dm_relays
|
||||
BackupEventType.KEY_PACKAGE_RELAYS -> Res.string.backup_type_key_package_relays
|
||||
BackupEventType.SEARCH_RELAYS -> Res.string.backup_type_search_relays
|
||||
BackupEventType.INDEXER_RELAYS -> Res.string.backup_type_indexer_relays
|
||||
BackupEventType.RELAY_FEEDS -> Res.string.backup_type_relay_feeds
|
||||
BackupEventType.BLOCKED_RELAYS -> Res.string.backup_type_blocked_relays
|
||||
BackupEventType.TRUSTED_RELAYS -> Res.string.backup_type_trusted_relays
|
||||
BackupEventType.PRIVATE_OUTBOX_RELAYS -> Res.string.backup_type_private_outbox_relays
|
||||
BackupEventType.APP_SETTINGS -> Res.string.backup_type_app_settings
|
||||
BackupEventType.PUBLIC_CHATS -> Res.string.backup_type_public_chats
|
||||
BackupEventType.COMMUNITIES -> Res.string.backup_type_communities
|
||||
BackupEventType.HASHTAGS -> Res.string.backup_type_hashtags
|
||||
BackupEventType.GEOHASHES -> Res.string.backup_type_geohashes
|
||||
BackupEventType.FAVORITE_ALGO_FEEDS -> Res.string.backup_type_favorite_algo_feeds
|
||||
BackupEventType.EPHEMERAL_CHATS -> Res.string.backup_type_ephemeral_chats
|
||||
BackupEventType.RELAY_GROUPS -> Res.string.backup_type_relay_groups
|
||||
BackupEventType.CONCORD_COMMUNITIES -> Res.string.backup_type_concord_communities
|
||||
BackupEventType.TRUST_PROVIDERS -> Res.string.backup_type_trust_providers
|
||||
BackupEventType.CASHU_WALLET -> Res.string.backup_type_cashu_wallet
|
||||
BackupEventType.NUTZAP_INFO -> Res.string.backup_type_nutzap_info
|
||||
BackupEventType.PAYMENT_TARGETS -> Res.string.backup_type_payment_targets
|
||||
BackupEventType.BOLT12_OFFERS -> Res.string.backup_type_bolt12_offers
|
||||
BackupEventType.OTHER -> Res.string.backup_type_other
|
||||
}
|
||||
|
||||
fun eventTypeExplainer(type: BackupEventType): Int =
|
||||
fun eventTypeExplainer(type: BackupEventType): StringResource =
|
||||
when (type) {
|
||||
BackupEventType.PROFILE -> R.string.backup_type_profile_explainer
|
||||
BackupEventType.FOLLOW_LIST -> R.string.backup_type_follow_list_explainer
|
||||
BackupEventType.MUTE_LIST -> R.string.backup_type_mute_list_explainer
|
||||
BackupEventType.OUTBOX_INBOX_RELAYS -> R.string.backup_type_outbox_inbox_relays_explainer
|
||||
BackupEventType.DM_RELAYS -> R.string.backup_type_dm_relays_explainer
|
||||
BackupEventType.KEY_PACKAGE_RELAYS -> R.string.backup_type_key_package_relays_explainer
|
||||
BackupEventType.SEARCH_RELAYS -> R.string.backup_type_search_relays_explainer
|
||||
BackupEventType.INDEXER_RELAYS -> R.string.backup_type_indexer_relays_explainer
|
||||
BackupEventType.RELAY_FEEDS -> R.string.backup_type_relay_feeds_explainer
|
||||
BackupEventType.BLOCKED_RELAYS -> R.string.backup_type_blocked_relays_explainer
|
||||
BackupEventType.TRUSTED_RELAYS -> R.string.backup_type_trusted_relays_explainer
|
||||
BackupEventType.PRIVATE_OUTBOX_RELAYS -> R.string.backup_type_private_outbox_relays_explainer
|
||||
BackupEventType.APP_SETTINGS -> R.string.backup_type_app_settings_explainer
|
||||
BackupEventType.PUBLIC_CHATS -> R.string.backup_type_public_chats_explainer
|
||||
BackupEventType.COMMUNITIES -> R.string.backup_type_communities_explainer
|
||||
BackupEventType.HASHTAGS -> R.string.backup_type_hashtags_explainer
|
||||
BackupEventType.GEOHASHES -> R.string.backup_type_geohashes_explainer
|
||||
BackupEventType.FAVORITE_ALGO_FEEDS -> R.string.backup_type_favorite_algo_feeds_explainer
|
||||
BackupEventType.EPHEMERAL_CHATS -> R.string.backup_type_ephemeral_chats_explainer
|
||||
BackupEventType.RELAY_GROUPS -> R.string.backup_type_relay_groups_explainer
|
||||
BackupEventType.CONCORD_COMMUNITIES -> R.string.backup_type_concord_communities_explainer
|
||||
BackupEventType.TRUST_PROVIDERS -> R.string.backup_type_trust_providers_explainer
|
||||
BackupEventType.CASHU_WALLET -> R.string.backup_type_cashu_wallet_explainer
|
||||
BackupEventType.NUTZAP_INFO -> R.string.backup_type_nutzap_info_explainer
|
||||
BackupEventType.PAYMENT_TARGETS -> R.string.backup_type_payment_targets_explainer
|
||||
BackupEventType.BOLT12_OFFERS -> R.string.backup_type_bolt12_offers_explainer
|
||||
BackupEventType.OTHER -> R.string.backup_type_other_explainer
|
||||
BackupEventType.PROFILE -> Res.string.backup_type_profile_explainer
|
||||
BackupEventType.FOLLOW_LIST -> Res.string.backup_type_follow_list_explainer
|
||||
BackupEventType.MUTE_LIST -> Res.string.backup_type_mute_list_explainer
|
||||
BackupEventType.OUTBOX_INBOX_RELAYS -> Res.string.backup_type_outbox_inbox_relays_explainer
|
||||
BackupEventType.DM_RELAYS -> Res.string.backup_type_dm_relays_explainer
|
||||
BackupEventType.KEY_PACKAGE_RELAYS -> Res.string.backup_type_key_package_relays_explainer
|
||||
BackupEventType.SEARCH_RELAYS -> Res.string.backup_type_search_relays_explainer
|
||||
BackupEventType.INDEXER_RELAYS -> Res.string.backup_type_indexer_relays_explainer
|
||||
BackupEventType.RELAY_FEEDS -> Res.string.backup_type_relay_feeds_explainer
|
||||
BackupEventType.BLOCKED_RELAYS -> Res.string.backup_type_blocked_relays_explainer
|
||||
BackupEventType.TRUSTED_RELAYS -> Res.string.backup_type_trusted_relays_explainer
|
||||
BackupEventType.PRIVATE_OUTBOX_RELAYS -> Res.string.backup_type_private_outbox_relays_explainer
|
||||
BackupEventType.APP_SETTINGS -> Res.string.backup_type_app_settings_explainer
|
||||
BackupEventType.PUBLIC_CHATS -> Res.string.backup_type_public_chats_explainer
|
||||
BackupEventType.COMMUNITIES -> Res.string.backup_type_communities_explainer
|
||||
BackupEventType.HASHTAGS -> Res.string.backup_type_hashtags_explainer
|
||||
BackupEventType.GEOHASHES -> Res.string.backup_type_geohashes_explainer
|
||||
BackupEventType.FAVORITE_ALGO_FEEDS -> Res.string.backup_type_favorite_algo_feeds_explainer
|
||||
BackupEventType.EPHEMERAL_CHATS -> Res.string.backup_type_ephemeral_chats_explainer
|
||||
BackupEventType.RELAY_GROUPS -> Res.string.backup_type_relay_groups_explainer
|
||||
BackupEventType.CONCORD_COMMUNITIES -> Res.string.backup_type_concord_communities_explainer
|
||||
BackupEventType.TRUST_PROVIDERS -> Res.string.backup_type_trust_providers_explainer
|
||||
BackupEventType.CASHU_WALLET -> Res.string.backup_type_cashu_wallet_explainer
|
||||
BackupEventType.NUTZAP_INFO -> Res.string.backup_type_nutzap_info_explainer
|
||||
BackupEventType.PAYMENT_TARGETS -> Res.string.backup_type_payment_targets_explainer
|
||||
BackupEventType.BOLT12_OFFERS -> Res.string.backup_type_bolt12_offers_explainer
|
||||
BackupEventType.OTHER -> Res.string.backup_type_other_explainer
|
||||
}
|
||||
|
||||
+55
-31
@@ -59,11 +59,34 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
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.model.backups.BackupEventType
|
||||
import com.vitorpamplona.amethyst.commons.model.backups.ReplaceableBackupConflict
|
||||
import com.vitorpamplona.amethyst.commons.model.navigation.Route
|
||||
import com.vitorpamplona.amethyst.commons.model.navigation.routeFor
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_action_block_again
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_action_keep_count
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_action_rejoin
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_action_remute
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_action_restore_count
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_action_restore_feeds
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_action_restore_places
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_action_restore_profile
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_action_restore_providers
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_action_restore_relays
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_action_restore_topics
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_action_restore_wallet
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_added
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_changed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_keep_new
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_private_added
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_private_changed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_private_cleared
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_removed
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_conflict_restore_mine
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_changed_by_other_app
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_title_cleared
|
||||
import com.vitorpamplona.amethyst.commons.resources.backup_review_title_updated
|
||||
import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton
|
||||
@@ -97,22 +120,23 @@ import com.vitorpamplona.quartz.nip60Cashu.wallet.CashuWalletDiff
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListDiff
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.follow.CommunityListDiff
|
||||
import com.vitorpamplona.quartz.nip85TrustedAssertions.list.TrustProviderListDiff
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
|
||||
/** A row of the review list, flattened so hundreds of entries scroll lazily. */
|
||||
@Immutable
|
||||
internal sealed interface ReviewRow {
|
||||
class Section(
|
||||
val titleRes: Int,
|
||||
val titleRes: StringResource,
|
||||
val count: Int,
|
||||
val tone: Tone,
|
||||
) : ReviewRow
|
||||
|
||||
class Note(
|
||||
val textRes: Int,
|
||||
val textRes: StringResource,
|
||||
) : ReviewRow
|
||||
|
||||
class Group(
|
||||
val labelRes: Int,
|
||||
val labelRes: StringResource,
|
||||
) : ReviewRow
|
||||
|
||||
class Entry(
|
||||
@@ -124,15 +148,15 @@ internal enum class Tone { REMOVED, ADDED, CHANGED }
|
||||
|
||||
internal fun buildRows(
|
||||
presentation: DiffPresentation,
|
||||
skipGroups: Set<Int> = emptySet(),
|
||||
skipGroups: Set<StringResource> = emptySet(),
|
||||
): List<ReviewRow> {
|
||||
val rows = mutableListOf<ReviewRow>()
|
||||
|
||||
fun section(
|
||||
titleRes: Int,
|
||||
titleRes: StringResource,
|
||||
count: Int,
|
||||
tone: Tone,
|
||||
contentNote: Int?,
|
||||
contentNote: StringResource?,
|
||||
items: (DiffGroup) -> List<ReviewItem>,
|
||||
) {
|
||||
if (count == 0 && contentNote == null) return
|
||||
@@ -149,9 +173,9 @@ internal fun buildRows(
|
||||
}
|
||||
|
||||
val content = presentation.content
|
||||
section(R.string.backup_conflict_removed, presentation.removedCount, Tone.REMOVED, R.string.backup_conflict_private_cleared.takeIf { content == ContentChange.CLEARED }) { it.removed }
|
||||
section(R.string.backup_conflict_added, presentation.addedCount, Tone.ADDED, R.string.backup_conflict_private_added.takeIf { content == ContentChange.ADDED }) { it.added }
|
||||
section(R.string.backup_conflict_changed, presentation.changedCount, Tone.CHANGED, R.string.backup_conflict_private_changed.takeIf { content == ContentChange.CHANGED }) { it.changed }
|
||||
section(Res.string.backup_conflict_removed, presentation.removedCount, Tone.REMOVED, Res.string.backup_conflict_private_cleared.takeIf { content == ContentChange.CLEARED }) { it.removed }
|
||||
section(Res.string.backup_conflict_added, presentation.addedCount, Tone.ADDED, Res.string.backup_conflict_private_added.takeIf { content == ContentChange.ADDED }) { it.added }
|
||||
section(Res.string.backup_conflict_changed, presentation.changedCount, Tone.CHANGED, Res.string.backup_conflict_private_changed.takeIf { content == ContentChange.CHANGED }) { it.changed }
|
||||
return rows
|
||||
}
|
||||
|
||||
@@ -268,7 +292,7 @@ internal fun LazyListScope.genericDiffItems(
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun GroupLabel(labelRes: Int) {
|
||||
internal fun GroupLabel(labelRes: StringResource) {
|
||||
Text(
|
||||
text = stringRes(labelRes),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
@@ -339,7 +363,7 @@ internal fun eventTitle(conflict: ReplaceableBackupConflict): String {
|
||||
val name = stringRes(eventTypeName(conflict.eventType)).replaceFirstChar { it.uppercase() }
|
||||
// Says what happened to it, not just what it is: "Community list updated".
|
||||
val emptied = conflict.incoming.tags.isEmpty() && conflict.incoming.content.isEmpty()
|
||||
return stringRes(if (emptied) R.string.backup_review_title_cleared else R.string.backup_review_title_updated, name)
|
||||
return stringRes(if (emptied) Res.string.backup_review_title_cleared else Res.string.backup_review_title_updated, name)
|
||||
}
|
||||
|
||||
/** The two choices, worded for what they do to this event: "Keep 120" / "Restore 523". */
|
||||
@@ -348,48 +372,48 @@ private fun actionLabels(conflict: ReplaceableBackupConflict): Pair<String, Stri
|
||||
when (val diff = conflict.diff) {
|
||||
is ContactListDiff -> {
|
||||
val (saved, new) = conflict.followCounts
|
||||
stringRes(R.string.backup_action_keep_count, new.toString()) to stringRes(R.string.backup_action_restore_count, saved.toString())
|
||||
stringRes(Res.string.backup_action_keep_count, new.toString()) to stringRes(Res.string.backup_action_restore_count, saved.toString())
|
||||
}
|
||||
is MuteListDiff -> {
|
||||
val removed = diff.publicMutes.removed.size
|
||||
stringRes(R.string.backup_conflict_keep_new) to
|
||||
if (removed > 0) stringRes(R.string.backup_action_remute, removed.toString()) else stringRes(R.string.backup_conflict_restore_mine)
|
||||
stringRes(Res.string.backup_conflict_keep_new) to
|
||||
if (removed > 0) stringRes(Res.string.backup_action_remute, removed.toString()) else stringRes(Res.string.backup_conflict_restore_mine)
|
||||
}
|
||||
is SimpleGroupListDiff -> {
|
||||
val removed = diff.groups.removed.size
|
||||
stringRes(R.string.backup_conflict_keep_new) to
|
||||
if (removed > 0) stringRes(R.string.backup_action_rejoin, removed.toString()) else stringRes(R.string.backup_conflict_restore_mine)
|
||||
stringRes(Res.string.backup_conflict_keep_new) to
|
||||
if (removed > 0) stringRes(Res.string.backup_action_rejoin, removed.toString()) else stringRes(Res.string.backup_conflict_restore_mine)
|
||||
}
|
||||
is MetadataDiff -> stringRes(R.string.backup_conflict_keep_new) to stringRes(R.string.backup_action_restore_profile)
|
||||
is MetadataDiff -> stringRes(Res.string.backup_conflict_keep_new) to stringRes(Res.string.backup_action_restore_profile)
|
||||
is RelayListDiff ->
|
||||
if (conflict.eventType == BackupEventType.BLOCKED_RELAYS && diff.relays.removed.isNotEmpty()) {
|
||||
stringRes(R.string.backup_conflict_keep_new) to
|
||||
stringRes(Res.string.backup_conflict_keep_new) to
|
||||
stringRes(
|
||||
R.string.backup_action_block_again,
|
||||
Res.string.backup_action_block_again,
|
||||
diff.relays.removed.size
|
||||
.toString(),
|
||||
)
|
||||
} else {
|
||||
stringRes(R.string.backup_conflict_keep_new) to stringRes(R.string.backup_action_restore_relays)
|
||||
stringRes(Res.string.backup_conflict_keep_new) to stringRes(Res.string.backup_action_restore_relays)
|
||||
}
|
||||
is AdvertisedRelayListDiff -> stringRes(R.string.backup_conflict_keep_new) to stringRes(R.string.backup_action_restore_relays)
|
||||
is AdvertisedRelayListDiff -> stringRes(Res.string.backup_conflict_keep_new) to stringRes(Res.string.backup_action_restore_relays)
|
||||
is ChannelListDiff -> rejoinLabels(diff.channels.removed.size)
|
||||
is CommunityListDiff -> rejoinLabels(diff.communities.removed.size)
|
||||
is EphemeralChatListDiff -> rejoinLabels(diff.rooms.removed.size)
|
||||
is FavoriteAlgoFeedsListDiff -> stringRes(R.string.backup_conflict_keep_new) to stringRes(R.string.backup_action_restore_feeds)
|
||||
is HashtagListDiff -> stringRes(R.string.backup_conflict_keep_new) to stringRes(R.string.backup_action_restore_topics)
|
||||
is FavoriteAlgoFeedsListDiff -> stringRes(Res.string.backup_conflict_keep_new) to stringRes(Res.string.backup_action_restore_feeds)
|
||||
is HashtagListDiff -> stringRes(Res.string.backup_conflict_keep_new) to stringRes(Res.string.backup_action_restore_topics)
|
||||
// Geohashes are places, not topics: the screen counts "places gone" under "Followed
|
||||
// locations", so the button has to agree with the page it sits on.
|
||||
is GeohashListDiff -> stringRes(R.string.backup_conflict_keep_new) to stringRes(R.string.backup_action_restore_places)
|
||||
is TrustProviderListDiff -> stringRes(R.string.backup_conflict_keep_new) to stringRes(R.string.backup_action_restore_providers)
|
||||
is CashuWalletDiff -> stringRes(R.string.backup_conflict_keep_new) to stringRes(R.string.backup_action_restore_wallet)
|
||||
else -> stringRes(R.string.backup_conflict_keep_new) to stringRes(R.string.backup_conflict_restore_mine)
|
||||
is GeohashListDiff -> stringRes(Res.string.backup_conflict_keep_new) to stringRes(Res.string.backup_action_restore_places)
|
||||
is TrustProviderListDiff -> stringRes(Res.string.backup_conflict_keep_new) to stringRes(Res.string.backup_action_restore_providers)
|
||||
is CashuWalletDiff -> stringRes(Res.string.backup_conflict_keep_new) to stringRes(Res.string.backup_action_restore_wallet)
|
||||
else -> stringRes(Res.string.backup_conflict_keep_new) to stringRes(Res.string.backup_conflict_restore_mine)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rejoinLabels(removed: Int): Pair<String, String> =
|
||||
stringRes(R.string.backup_conflict_keep_new) to
|
||||
if (removed > 0) stringRes(R.string.backup_action_rejoin, removed.toString()) else stringRes(R.string.backup_conflict_restore_mine)
|
||||
stringRes(Res.string.backup_conflict_keep_new) to
|
||||
if (removed > 0) stringRes(Res.string.backup_action_rejoin, removed.toString()) else stringRes(Res.string.backup_conflict_restore_mine)
|
||||
|
||||
/** When the other app changed it, and what the event is for. */
|
||||
@Composable
|
||||
@@ -399,7 +423,7 @@ private fun BackupConflictIntro(
|
||||
) {
|
||||
Column(modifier, verticalArrangement = Arrangement.spacedBy(2.dp)) {
|
||||
Text(
|
||||
text = stringRes(R.string.backup_review_changed_by_other_app, timeAgoNoDot(conflict.cause.createdAt)),
|
||||
text = stringRes(Res.string.backup_review_changed_by_other_app, timeAgoNoDot(conflict.cause.createdAt)),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = conflictTones().removed,
|
||||
)
|
||||
|
||||
+3
-2
@@ -42,12 +42,13 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.chats.ui.ThinSendButton
|
||||
import com.vitorpamplona.amethyst.commons.model.cordnGroups.CordnGroupChatroom
|
||||
import com.vitorpamplona.amethyst.commons.model.nip30CustomEmojis.EmojiPackState
|
||||
import com.vitorpamplona.amethyst.commons.model.nip30CustomEmojis.EmojiSuggestionState
|
||||
import com.vitorpamplona.amethyst.commons.nip30CustomEmojis.ui.ShowEmojiSuggestionList
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_composer_hint
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.commons.ui.theme.EditFieldBorder
|
||||
@@ -233,7 +234,7 @@ internal fun CordnComposer(
|
||||
shape = EditFieldBorder,
|
||||
placeholder = {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_composer_hint),
|
||||
text = stringRes(Res.string.cordn_composer_hint),
|
||||
color = MaterialTheme.colorScheme.placeholderText,
|
||||
)
|
||||
},
|
||||
|
||||
+98
-51
@@ -55,11 +55,9 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
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.cordn.CoordinatorConfig
|
||||
import com.vitorpamplona.amethyst.commons.cordn.DiscoveredCoordinator
|
||||
import com.vitorpamplona.amethyst.commons.cordn.GroupExposure
|
||||
@@ -69,6 +67,55 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
import com.vitorpamplona.amethyst.commons.model.navigation.Route
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.back
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_discover_failed
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_discover_none
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_discover_seen
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_discover_seen_on
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_discover_unheard
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_hide_older
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_relays_more
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_show_all
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_show_fewer
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_show_older
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_stale_note
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_action
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_action_invite
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_admin_count
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_admin_only_me_on
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_coordinator_change
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_coordinator_discover
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_coordinator_hide
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_coordinator_new
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_coordinator_pubkey
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_coordinator_relays
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_coverage_all
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_coverage_partial
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_coverage_unknown
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_description
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_egalitarian
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_egalitarian_note
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_failed
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_name
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_no_coordinator
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_outcome_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_outcome_failed
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_outcome_link
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_outcome_no_welcome
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_outcome_open
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_outcome_skipped
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_outcome_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_outcome_waiting
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_people_none
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_step_admins
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_step_name
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_step_people
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_step_where
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_unreachable_count
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable_detail
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_member_count
|
||||
import com.vitorpamplona.amethyst.commons.ui.components.EmptyState
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.model.cordn.CordnCoverage
|
||||
@@ -131,7 +178,7 @@ fun CordnCreateGroupScreen(
|
||||
Icon(MaterialSymbols.AutoMirrored.ArrowBack, contentDescription = stringRes(Res.string.back))
|
||||
}
|
||||
},
|
||||
title = { Text(stringRes(R.string.cordn_create_title)) },
|
||||
title = { Text(stringRes(Res.string.cordn_create_title)) },
|
||||
)
|
||||
},
|
||||
) { padding ->
|
||||
@@ -139,8 +186,8 @@ fun CordnCreateGroupScreen(
|
||||
// The app's own empty state, centred and titled, rather than a
|
||||
// sentence stranded in the top-left corner.
|
||||
EmptyState(
|
||||
title = stringRes(R.string.cordn_group_unavailable),
|
||||
description = stringRes(R.string.cordn_group_unavailable_detail),
|
||||
title = stringRes(Res.string.cordn_group_unavailable),
|
||||
description = stringRes(Res.string.cordn_group_unavailable_detail),
|
||||
modifier = Modifier.padding(padding),
|
||||
)
|
||||
return@Scaffold
|
||||
@@ -164,14 +211,14 @@ fun CordnCreateGroupScreen(
|
||||
val draft = rememberCordnGroupDraft(accountViewModel)
|
||||
var creation by remember { mutableStateOf<CordnGroupCreation?>(null) }
|
||||
var error by remember { mutableStateOf<String?>(null) }
|
||||
val failureFallback = stringRes(R.string.cordn_create_failed)
|
||||
val failureFallback = stringRes(Res.string.cordn_create_failed)
|
||||
var busy by remember { mutableStateOf(false) }
|
||||
|
||||
// Coordinators this account has never used, from their CEP-6
|
||||
// announcements. Not added to the account by looking: picking one here
|
||||
// is what commits to it, and `createGroup` opens the session.
|
||||
var discovering by remember { mutableStateOf(false) }
|
||||
val discoverFailed = stringRes(R.string.cordn_coordinators_discover_failed)
|
||||
val discoverFailed = stringRes(Res.string.cordn_coordinators_discover_failed)
|
||||
|
||||
// Offers this account already holds are not offers; they are the choices
|
||||
// above, and listing them twice would let the same coordinator be picked
|
||||
@@ -222,29 +269,29 @@ fun CordnCreateGroupScreen(
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_create_explainer),
|
||||
text = stringRes(Res.string.cordn_create_explainer),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
|
||||
StepHeading(1, stringRes(R.string.cordn_create_step_name))
|
||||
StepHeading(1, stringRes(Res.string.cordn_create_step_name))
|
||||
|
||||
OutlinedTextField(
|
||||
value = draft.name,
|
||||
onValueChange = { draft.name = it },
|
||||
label = { Text(stringRes(R.string.cordn_create_name)) },
|
||||
label = { Text(stringRes(Res.string.cordn_create_name)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = draft.description,
|
||||
onValueChange = { draft.description = it },
|
||||
label = { Text(stringRes(R.string.cordn_create_description)) },
|
||||
label = { Text(stringRes(Res.string.cordn_create_description)) },
|
||||
singleLine = false,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
|
||||
StepHeading(2, stringRes(R.string.cordn_create_step_people))
|
||||
StepHeading(2, stringRes(Res.string.cordn_create_step_people))
|
||||
|
||||
RosterSummary(
|
||||
roster = draft.roster,
|
||||
@@ -254,7 +301,7 @@ fun CordnCreateGroupScreen(
|
||||
nav = nav,
|
||||
)
|
||||
|
||||
StepHeading(3, stringRes(R.string.cordn_create_step_where))
|
||||
StepHeading(3, stringRes(Res.string.cordn_create_step_where))
|
||||
|
||||
// Collapsed to the one coordinator that will be used, because with a
|
||||
// draft.roster in hand there is usually nothing left to decide. The whole
|
||||
@@ -326,9 +373,9 @@ fun CordnCreateGroupScreen(
|
||||
TextButton(onClick = { draft.showAllLive = !draft.showAllLive }) {
|
||||
Text(
|
||||
if (draft.showAllLive) {
|
||||
stringRes(R.string.cordn_coordinators_show_fewer)
|
||||
stringRes(Res.string.cordn_coordinators_show_fewer)
|
||||
} else {
|
||||
stringRes(R.string.cordn_coordinators_show_all, live.size)
|
||||
stringRes(Res.string.cordn_coordinators_show_all, live.size)
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -338,9 +385,9 @@ fun CordnCreateGroupScreen(
|
||||
TextButton(onClick = { draft.showStale = !draft.showStale }) {
|
||||
Text(
|
||||
if (draft.showStale) {
|
||||
stringRes(R.string.cordn_coordinators_hide_older)
|
||||
stringRes(Res.string.cordn_coordinators_hide_older)
|
||||
} else {
|
||||
stringRes(R.string.cordn_coordinators_show_older, stale.size)
|
||||
stringRes(Res.string.cordn_coordinators_show_older, stale.size)
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -348,7 +395,7 @@ fun CordnCreateGroupScreen(
|
||||
|
||||
if (draft.showStale && stale.isNotEmpty()) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_coordinators_stale_note),
|
||||
text = stringRes(Res.string.cordn_coordinators_stale_note),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -372,7 +419,7 @@ fun CordnCreateGroupScreen(
|
||||
}
|
||||
|
||||
CoordinatorChoice(
|
||||
label = stringRes(R.string.cordn_create_coordinator_new),
|
||||
label = stringRes(Res.string.cordn_create_coordinator_new),
|
||||
pubKey = null,
|
||||
selected = draft.selected == null,
|
||||
onSelect = {
|
||||
@@ -402,20 +449,20 @@ fun CordnCreateGroupScreen(
|
||||
},
|
||||
enabled = !discovering && !busy,
|
||||
) {
|
||||
Text(stringRes(R.string.cordn_create_coordinator_discover))
|
||||
Text(stringRes(Res.string.cordn_create_coordinator_discover))
|
||||
}
|
||||
|
||||
draft.discovered?.takeIf { offers.isEmpty() }?.let { result ->
|
||||
Text(
|
||||
text =
|
||||
if (result.unreachable.isEmpty()) {
|
||||
stringRes(R.string.cordn_coordinators_discover_none)
|
||||
stringRes(Res.string.cordn_coordinators_discover_none)
|
||||
} else {
|
||||
// "Nobody is announcing" and "we were not told" are
|
||||
// different answers and only one of them is final.
|
||||
// Reporting the first for the second sends someone
|
||||
// off to paste a pubkey by hand over a timeout.
|
||||
stringRes(R.string.cordn_coordinators_discover_unheard, result.unreachable.size)
|
||||
stringRes(Res.string.cordn_coordinators_discover_unheard, result.unreachable.size)
|
||||
},
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
@@ -433,7 +480,7 @@ fun CordnCreateGroupScreen(
|
||||
draft.userPicked = true
|
||||
error = null
|
||||
},
|
||||
label = { Text(stringRes(R.string.cordn_create_coordinator_pubkey)) },
|
||||
label = { Text(stringRes(Res.string.cordn_create_coordinator_pubkey)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
@@ -444,7 +491,7 @@ fun CordnCreateGroupScreen(
|
||||
draft.userPicked = true
|
||||
error = null
|
||||
},
|
||||
label = { Text(stringRes(R.string.cordn_create_coordinator_relays)) },
|
||||
label = { Text(stringRes(Res.string.cordn_create_coordinator_relays)) },
|
||||
// A coordinator has no address beyond its pubkey (§8.5), so
|
||||
// the relays are how it is reached and more than one is
|
||||
// ordinary. One per line rather than comma-separated,
|
||||
@@ -456,7 +503,7 @@ fun CordnCreateGroupScreen(
|
||||
}
|
||||
}
|
||||
|
||||
StepHeading(4, stringRes(R.string.cordn_create_step_admins))
|
||||
StepHeading(4, stringRes(Res.string.cordn_create_step_admins))
|
||||
|
||||
// spec/01.md §5.3: leaving the admin list empty is not "set it up
|
||||
// later", it is choosing draft.egalitarian permanently -- so it is offered
|
||||
@@ -472,15 +519,15 @@ fun CordnCreateGroupScreen(
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text(stringRes(R.string.cordn_create_egalitarian), style = MaterialTheme.typography.bodyMedium)
|
||||
Text(stringRes(Res.string.cordn_create_egalitarian), style = MaterialTheme.typography.bodyMedium)
|
||||
Text(
|
||||
text =
|
||||
if (draft.egalitarian) {
|
||||
stringRes(R.string.cordn_create_egalitarian_note)
|
||||
stringRes(Res.string.cordn_create_egalitarian_note)
|
||||
} else if (draft.coAdmins.isEmpty()) {
|
||||
stringRes(R.string.cordn_create_admin_only_me_on)
|
||||
stringRes(Res.string.cordn_create_admin_only_me_on)
|
||||
} else {
|
||||
pluralStringRes(LocalContext.current, R.plurals.cordn_create_admin_count, draft.coAdmins.size + 1, draft.coAdmins.size + 1)
|
||||
pluralStringRes(Res.plurals.cordn_create_admin_count, draft.coAdmins.size + 1, draft.coAdmins.size + 1)
|
||||
},
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
@@ -561,9 +608,9 @@ fun CordnCreateGroupScreen(
|
||||
) {
|
||||
Text(
|
||||
if (draft.roster.isEmpty()) {
|
||||
stringRes(R.string.cordn_create_action)
|
||||
stringRes(Res.string.cordn_create_action)
|
||||
} else {
|
||||
pluralStringRes(LocalContext.current, R.plurals.cordn_create_action_invite, draft.roster.size, draft.roster.size)
|
||||
pluralStringRes(Res.plurals.cordn_create_action_invite, draft.roster.size, draft.roster.size)
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -691,9 +738,9 @@ private fun resolvedName(
|
||||
@Composable
|
||||
private fun announcedLabel(announcedAt: Long): String =
|
||||
if (TimeUtils.now() - announcedAt > TimeUtils.ONE_MONTH) {
|
||||
stringRes(R.string.cordn_coordinators_discover_seen_on, timeAgoNoDot(announcedAt).trim())
|
||||
stringRes(Res.string.cordn_coordinators_discover_seen_on, timeAgoNoDot(announcedAt).trim())
|
||||
} else {
|
||||
stringRes(R.string.cordn_coordinators_discover_seen, timeAgoNoDot(announcedAt).trim())
|
||||
stringRes(Res.string.cordn_coordinators_discover_seen, timeAgoNoDot(announcedAt).trim())
|
||||
}
|
||||
|
||||
/** The hosts it answers on, the first two and a count of the rest. */
|
||||
@@ -705,7 +752,7 @@ private fun relayLabel(relays: List<NormalizedRelayUrl>): String? {
|
||||
return if (hosts.size <= 2) {
|
||||
shown
|
||||
} else {
|
||||
stringRes(R.string.cordn_coordinators_relays_more, shown, hosts.size - 2)
|
||||
stringRes(Res.string.cordn_coordinators_relays_more, shown, hosts.size - 2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -791,7 +838,7 @@ private fun RosterSummary(
|
||||
) {
|
||||
if (roster.isEmpty()) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_create_people_none),
|
||||
text = stringRes(Res.string.cordn_create_people_none),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.weight(1f),
|
||||
@@ -804,7 +851,7 @@ private fun RosterSummary(
|
||||
}
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text(
|
||||
text = pluralStringRes(LocalContext.current, R.plurals.cordn_member_count, roster.size + 1, roster.size + 1),
|
||||
text = pluralStringRes(Res.plurals.cordn_member_count, roster.size + 1, roster.size + 1),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
// Counted over coordinators that answered, so an unreachable one
|
||||
@@ -812,7 +859,7 @@ private fun RosterSummary(
|
||||
val unreachable = roster.count { member -> coverage.values.none { it.answered && member in it.reachable } }
|
||||
if (unreachable > 0 && coverage.values.any { it.answered }) {
|
||||
Text(
|
||||
text = pluralStringRes(LocalContext.current, R.plurals.cordn_create_unreachable_count, unreachable, unreachable),
|
||||
text = pluralStringRes(Res.plurals.cordn_create_unreachable_count, unreachable, unreachable),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
@@ -855,7 +902,7 @@ private fun CoordinatorSummary(
|
||||
) {
|
||||
if (config == null) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_create_no_coordinator),
|
||||
text = stringRes(Res.string.cordn_create_no_coordinator),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.weight(1f),
|
||||
@@ -879,9 +926,9 @@ private fun CoordinatorSummary(
|
||||
Text(
|
||||
text =
|
||||
when {
|
||||
coverage == null || !coverage.answered -> stringRes(R.string.cordn_create_coverage_unknown)
|
||||
reached == rosterSize -> stringRes(R.string.cordn_create_coverage_all, rosterSize)
|
||||
else -> stringRes(R.string.cordn_create_coverage_partial, reached ?: 0, rosterSize)
|
||||
coverage == null || !coverage.answered -> stringRes(Res.string.cordn_create_coverage_unknown)
|
||||
reached == rosterSize -> stringRes(Res.string.cordn_create_coverage_all, rosterSize)
|
||||
else -> stringRes(Res.string.cordn_create_coverage_partial, reached ?: 0, rosterSize)
|
||||
},
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color =
|
||||
@@ -899,9 +946,9 @@ private fun CoordinatorSummary(
|
||||
TextButton(onClick = onToggle) {
|
||||
Text(
|
||||
if (expanded) {
|
||||
stringRes(R.string.cordn_create_coordinator_hide)
|
||||
stringRes(Res.string.cordn_create_coordinator_hide)
|
||||
} else {
|
||||
stringRes(R.string.cordn_create_coordinator_change)
|
||||
stringRes(Res.string.cordn_create_coordinator_change)
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -934,11 +981,11 @@ private fun CordnCreationOutcome(
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text(stringRes(R.string.cordn_create_outcome_title)) },
|
||||
title = { Text(stringRes(Res.string.cordn_create_outcome_title)) },
|
||||
text = {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_create_outcome_explainer),
|
||||
text = stringRes(Res.string.cordn_create_outcome_explainer),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -960,10 +1007,10 @@ private fun CordnCreationOutcome(
|
||||
Text(
|
||||
text =
|
||||
when {
|
||||
outcome == null -> stringRes(R.string.cordn_create_outcome_skipped)
|
||||
outcome.sent -> stringRes(R.string.cordn_create_outcome_waiting)
|
||||
outcome.joinedWithoutWelcome -> stringRes(R.string.cordn_create_outcome_no_welcome)
|
||||
else -> outcome.failure?.message ?: stringRes(R.string.cordn_create_outcome_failed)
|
||||
outcome == null -> stringRes(Res.string.cordn_create_outcome_skipped)
|
||||
outcome.sent -> stringRes(Res.string.cordn_create_outcome_waiting)
|
||||
outcome.joinedWithoutWelcome -> stringRes(Res.string.cordn_create_outcome_no_welcome)
|
||||
else -> outcome.failure?.message ?: stringRes(Res.string.cordn_create_outcome_failed)
|
||||
},
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color =
|
||||
@@ -979,12 +1026,12 @@ private fun CordnCreationOutcome(
|
||||
// open themselves -- which needs the group to exist,
|
||||
// and now it does.
|
||||
if (outcome == null) {
|
||||
TextButton(onClick = open) { Text(stringRes(R.string.cordn_create_outcome_link)) }
|
||||
TextButton(onClick = open) { Text(stringRes(Res.string.cordn_create_outcome_link)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = { TextButton(onClick = open) { Text(stringRes(R.string.cordn_create_outcome_open)) } },
|
||||
confirmButton = { TextButton(onClick = open) { Text(stringRes(Res.string.cordn_create_outcome_open)) } },
|
||||
)
|
||||
}
|
||||
|
||||
+37
-21
@@ -47,15 +47,31 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
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.User
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_add_member
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_admin
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_people_done
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_people_empty
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_people_note
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_reach_count
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_reach_none
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_reach_unknown
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_step_people
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_you
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable_detail
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_add_member_none
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_add_member_placeholder
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_has_key_package
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_remove_member
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_member_count
|
||||
import com.vitorpamplona.amethyst.commons.ui.components.EmptyState
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton
|
||||
@@ -101,12 +117,12 @@ fun CordnCreateMembersScreen(
|
||||
val draft = rememberCordnGroupDraft(accountViewModel)
|
||||
|
||||
Scaffold(
|
||||
topBar = { TopBarWithBackButton(stringRes(R.string.cordn_create_step_people), nav) },
|
||||
topBar = { TopBarWithBackButton(stringRes(Res.string.cordn_create_step_people), nav) },
|
||||
) { padding ->
|
||||
if (runtime == null) {
|
||||
EmptyState(
|
||||
title = stringRes(R.string.cordn_group_unavailable),
|
||||
description = stringRes(R.string.cordn_group_unavailable_detail),
|
||||
title = stringRes(Res.string.cordn_group_unavailable),
|
||||
description = stringRes(Res.string.cordn_group_unavailable_detail),
|
||||
modifier = Modifier.padding(padding),
|
||||
)
|
||||
return@Scaffold
|
||||
@@ -137,7 +153,7 @@ fun CordnCreateMembersScreen(
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_create_people_note),
|
||||
text = stringRes(Res.string.cordn_create_people_note),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -148,8 +164,8 @@ fun CordnCreateMembersScreen(
|
||||
search = it
|
||||
if (it.length > 2) userSuggestions.processCurrentWord(it) else userSuggestions.reset()
|
||||
},
|
||||
label = { Text(stringRes(R.string.cordn_create_add_member)) },
|
||||
placeholder = { Text(stringRes(R.string.cordn_info_add_member_placeholder)) },
|
||||
label = { Text(stringRes(Res.string.cordn_create_add_member)) },
|
||||
placeholder = { Text(stringRes(Res.string.cordn_info_add_member_placeholder)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
@@ -168,7 +184,7 @@ fun CordnCreateMembersScreen(
|
||||
modifier = SuggestionListDefaultHeightChat,
|
||||
onEmpty = {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_info_add_member_none),
|
||||
text = stringRes(Res.string.cordn_info_add_member_none),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
@@ -182,7 +198,7 @@ fun CordnCreateMembersScreen(
|
||||
if (user.pubkeyHex in reachable) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.Key,
|
||||
contentDescription = stringRes(R.string.cordn_info_has_key_package),
|
||||
contentDescription = stringRes(Res.string.cordn_info_has_key_package),
|
||||
modifier = Modifier.size(16.dp),
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
@@ -194,7 +210,7 @@ fun CordnCreateMembersScreen(
|
||||
}) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.PersonAdd,
|
||||
contentDescription = stringRes(R.string.cordn_create_add_member),
|
||||
contentDescription = stringRes(Res.string.cordn_create_add_member),
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
}
|
||||
@@ -206,7 +222,7 @@ fun CordnCreateMembersScreen(
|
||||
HorizontalDivider()
|
||||
|
||||
Text(
|
||||
text = pluralStringRes(LocalContext.current, R.plurals.cordn_member_count, draft.roster.size + 1, draft.roster.size + 1),
|
||||
text = pluralStringRes(Res.plurals.cordn_member_count, draft.roster.size + 1, draft.roster.size + 1),
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
)
|
||||
|
||||
@@ -230,7 +246,7 @@ fun CordnCreateMembersScreen(
|
||||
|
||||
if (draft.roster.isEmpty()) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_create_people_empty),
|
||||
text = stringRes(Res.string.cordn_create_people_empty),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -240,7 +256,7 @@ fun CordnCreateMembersScreen(
|
||||
onClick = { nav.popBack() },
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp),
|
||||
) {
|
||||
Text(stringRes(R.string.cordn_create_people_done))
|
||||
Text(stringRes(Res.string.cordn_create_people_done))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -263,14 +279,14 @@ private fun CreatorRow(
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text(observeUserNameByHex(me, accountViewModel), style = MaterialTheme.typography.bodyMedium)
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_create_you),
|
||||
text = stringRes(Res.string.cordn_create_you),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
if (!egalitarian) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_create_admin),
|
||||
text = stringRes(Res.string.cordn_create_admin),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
@@ -304,9 +320,9 @@ private fun MemberRow(
|
||||
Text(
|
||||
text =
|
||||
when {
|
||||
answered == 0 -> stringRes(R.string.cordn_create_reach_unknown)
|
||||
reaching > 0 -> pluralStringRes(LocalContext.current, R.plurals.cordn_create_reach_count, reaching, reaching)
|
||||
else -> stringRes(R.string.cordn_create_reach_none)
|
||||
answered == 0 -> stringRes(Res.string.cordn_create_reach_unknown)
|
||||
reaching > 0 -> pluralStringRes(Res.plurals.cordn_create_reach_count, reaching, reaching)
|
||||
else -> stringRes(Res.string.cordn_create_reach_none)
|
||||
},
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color =
|
||||
@@ -323,7 +339,7 @@ private fun MemberRow(
|
||||
if (!egalitarian) {
|
||||
TextButton(onClick = onToggleAdmin) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_create_admin),
|
||||
text = stringRes(Res.string.cordn_create_admin),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = if (isAdmin) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -333,7 +349,7 @@ private fun MemberRow(
|
||||
IconButton(onClick = onRemove) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.PersonRemove,
|
||||
contentDescription = stringRes(R.string.cordn_info_remove_member),
|
||||
contentDescription = stringRes(Res.string.cordn_info_remove_member),
|
||||
modifier = Modifier.size(20.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
|
||||
+50
-28
@@ -69,7 +69,6 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.cordn.CordnGroupManager
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
@@ -78,10 +77,33 @@ import com.vitorpamplona.amethyst.commons.model.navigation.Route
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.back
|
||||
import com.vitorpamplona.amethyst.commons.resources.cancel
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_action_editing
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_action_unpin
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_chat_empty_description
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_chat_empty_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_info
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_untitled
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_media_download_failed
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_media_no_server
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_media_unreadable
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_media_upload_failed
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_member_count
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_message_deleted
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_pinned_by
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_pinned_count
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_pinned_next
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_pinned_previous
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_pinned_show_all
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_pinned_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_send_failed
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_send_no_session
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_voice_record
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_voice_stop
|
||||
import com.vitorpamplona.amethyst.commons.richtext.EncryptedMediaUrlImage
|
||||
import com.vitorpamplona.amethyst.commons.richtext.EncryptedMediaUrlVideo
|
||||
import com.vitorpamplona.amethyst.commons.ui.components.EmptyState
|
||||
import com.vitorpamplona.amethyst.commons.ui.loadStringRes
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.commons.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText
|
||||
@@ -152,7 +174,7 @@ fun CordnGroupChatScreen(
|
||||
// (it was forgotten, or never opened) and not an error to throw at the
|
||||
// user as a blank screen.
|
||||
Column(Modifier.fillMaxSize().padding(24.dp), verticalArrangement = Arrangement.Center) {
|
||||
Text(stringRes(R.string.cordn_group_unavailable), style = MaterialTheme.typography.bodyLarge)
|
||||
Text(stringRes(Res.string.cordn_group_unavailable), style = MaterialTheme.typography.bodyLarge)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -209,9 +231,9 @@ private fun CordnGroupChat(
|
||||
// and simply never arrived.
|
||||
var sendError by remember { mutableStateOf<String?>(null) }
|
||||
val context = LocalContext.current
|
||||
val uploadFailed = stringRes(R.string.cordn_media_upload_failed)
|
||||
val sendFailed = stringRes(R.string.cordn_send_failed)
|
||||
val noSession = stringRes(R.string.cordn_send_no_session)
|
||||
val uploadFailed = stringRes(Res.string.cordn_media_upload_failed)
|
||||
val sendFailed = stringRes(Res.string.cordn_send_failed)
|
||||
val noSession = stringRes(Res.string.cordn_send_no_session)
|
||||
|
||||
fun manager() =
|
||||
accountViewModel.account.cordnRuntime
|
||||
@@ -359,8 +381,8 @@ private fun CordnGroupChat(
|
||||
// action that actually needed it.
|
||||
if (rows.isEmpty()) {
|
||||
EmptyState(
|
||||
title = stringRes(R.string.cordn_chat_empty_title),
|
||||
description = stringRes(R.string.cordn_chat_empty_description),
|
||||
title = stringRes(Res.string.cordn_chat_empty_title),
|
||||
description = stringRes(Res.string.cordn_chat_empty_description),
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
}
|
||||
@@ -548,7 +570,7 @@ private fun CordnGroupChat(
|
||||
}
|
||||
if (editing != null) {
|
||||
ComposerBanner(
|
||||
label = stringRes(R.string.cordn_action_editing),
|
||||
label = stringRes(Res.string.cordn_action_editing),
|
||||
onCancel = {
|
||||
editing = null
|
||||
room.draft.value = ""
|
||||
@@ -712,7 +734,7 @@ private fun PinnedRibbon(
|
||||
IconButton(onClick = { index = (at - 1 + pinned.size) % pinned.size }, modifier = Modifier.size(28.dp)) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.AutoMirrored.KeyboardArrowLeft,
|
||||
contentDescription = stringRes(R.string.cordn_pinned_previous),
|
||||
contentDescription = stringRes(Res.string.cordn_pinned_previous),
|
||||
modifier = Modifier.size(18.dp),
|
||||
)
|
||||
}
|
||||
@@ -724,7 +746,7 @@ private fun PinnedRibbon(
|
||||
IconButton(onClick = { index = (at + 1) % pinned.size }, modifier = Modifier.size(28.dp)) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.AutoMirrored.KeyboardArrowRight,
|
||||
contentDescription = stringRes(R.string.cordn_pinned_next),
|
||||
contentDescription = stringRes(Res.string.cordn_pinned_next),
|
||||
modifier = Modifier.size(18.dp),
|
||||
)
|
||||
}
|
||||
@@ -733,7 +755,7 @@ private fun PinnedRibbon(
|
||||
IconButton(onClick = { showingAll = true }, modifier = Modifier.size(28.dp)) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.AutoMirrored.List,
|
||||
contentDescription = stringRes(R.string.cordn_pinned_show_all),
|
||||
contentDescription = stringRes(Res.string.cordn_pinned_show_all),
|
||||
modifier = Modifier.size(18.dp),
|
||||
)
|
||||
}
|
||||
@@ -786,7 +808,7 @@ private fun PinnedLine(
|
||||
// points at.
|
||||
text =
|
||||
if (annotations.isDeleted(message.envelope.id)) {
|
||||
stringRes(R.string.cordn_message_deleted)
|
||||
stringRes(Res.string.cordn_message_deleted)
|
||||
} else {
|
||||
annotations.contentOf(message.envelope.id).orEmpty()
|
||||
},
|
||||
@@ -822,7 +844,7 @@ private fun AllPinnedDialog(
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(MaterialSymbols.PushPin, contentDescription = null, modifier = Modifier.size(18.dp))
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_pinned_title),
|
||||
text = stringRes(Res.string.cordn_pinned_title),
|
||||
modifier = Modifier.padding(start = 8.dp),
|
||||
)
|
||||
}
|
||||
@@ -830,7 +852,7 @@ private fun AllPinnedDialog(
|
||||
text = {
|
||||
Column {
|
||||
Text(
|
||||
text = pluralStringRes(LocalContext.current, R.plurals.cordn_pinned_count, pinned.size, pinned.size),
|
||||
text = pluralStringRes(Res.plurals.cordn_pinned_count, pinned.size, pinned.size),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -861,7 +883,7 @@ private fun AllPinnedDialog(
|
||||
modifier = Modifier.weight(1f).padding(start = 8.dp),
|
||||
)
|
||||
TextButton(onClick = { onUnpin(message) }) {
|
||||
Text(stringRes(R.string.cordn_action_unpin), style = MaterialTheme.typography.labelSmall)
|
||||
Text(stringRes(Res.string.cordn_action_unpin), style = MaterialTheme.typography.labelSmall)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -869,7 +891,7 @@ private fun AllPinnedDialog(
|
||||
Text(
|
||||
text =
|
||||
stringRes(
|
||||
R.string.cordn_pinned_by,
|
||||
Res.string.cordn_pinned_by,
|
||||
observeUserNameByHex(pinnedBy, accountViewModel),
|
||||
),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
@@ -880,7 +902,7 @@ private fun AllPinnedDialog(
|
||||
Text(
|
||||
text =
|
||||
if (annotations.isDeleted(message.envelope.id)) {
|
||||
stringRes(R.string.cordn_message_deleted)
|
||||
stringRes(Res.string.cordn_message_deleted)
|
||||
} else {
|
||||
annotations.contentOf(message.envelope.id).orEmpty()
|
||||
},
|
||||
@@ -944,7 +966,7 @@ private fun CordnChatTopBar(
|
||||
Text(title, maxLines = 1, overflow = TextOverflow.Ellipsis)
|
||||
if (members.isNotEmpty()) {
|
||||
Text(
|
||||
text = pluralStringRes(LocalContext.current, R.plurals.cordn_member_count, members.size, members.size),
|
||||
text = pluralStringRes(Res.plurals.cordn_member_count, members.size, members.size),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
}
|
||||
@@ -963,7 +985,7 @@ private fun CordnChatTopBar(
|
||||
// GroupAdd rather than Info, as in Marmot: the same screen, and the thing
|
||||
// people come to it for is adding someone.
|
||||
IconButton(onClick = onInfo) {
|
||||
Icon(MaterialSymbols.GroupAdd, contentDescription = stringRes(R.string.cordn_group_info))
|
||||
Icon(MaterialSymbols.GroupAdd, contentDescription = stringRes(Res.string.cordn_group_info))
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -995,10 +1017,10 @@ private suspend fun sendAttachment(
|
||||
// a reason a person can act on.
|
||||
val session =
|
||||
accountViewModel.account.cordnRuntime?.sessionOrNull(room.coordinatorPubKey)
|
||||
?: throw CordnAttachmentException(stringRes(context, R.string.cordn_send_no_session))
|
||||
?: throw CordnAttachmentException(loadStringRes(Res.string.cordn_send_no_session))
|
||||
val group =
|
||||
session.manager.group(room.gid)
|
||||
?: throw CordnAttachmentException(stringRes(context, R.string.cordn_send_no_session))
|
||||
?: throw CordnAttachmentException(loadStringRes(Res.string.cordn_send_no_session))
|
||||
|
||||
// The gallery inside the dialog can delete what was picked, which leaves an empty
|
||||
// orchestrator rather than a null one. canPost() now refuses that, but indexing it
|
||||
@@ -1052,14 +1074,14 @@ private suspend fun sendAttachment(
|
||||
val name = withContext(Dispatchers.IO) { resolveDisplayName(context, uri) }
|
||||
val bytes =
|
||||
withContext(Dispatchers.IO) { context.contentResolver.openInputStream(finalUri)?.use { it.readBytes() } }
|
||||
?: throw CordnAttachmentException(stringRes(context, R.string.cordn_media_unreadable))
|
||||
?: throw CordnAttachmentException(loadStringRes(Res.string.cordn_media_unreadable))
|
||||
|
||||
// Null means the chosen host has no base URL, which is a setting the person can
|
||||
// change — the one failure here that is entirely actionable.
|
||||
val tag =
|
||||
CordnMediaService(accountViewModel.account)
|
||||
.upload(group, bytes, mime, name, context, state.selectedServer.baseUrl)
|
||||
?: throw CordnAttachmentException(stringRes(context, R.string.cordn_media_no_server))
|
||||
?: throw CordnAttachmentException(loadStringRes(Res.string.cordn_media_no_server))
|
||||
|
||||
// Into the room as well, for the same reason every other send is: an
|
||||
// attachment of your own echoes back as an Echo and would otherwise be
|
||||
@@ -1140,7 +1162,7 @@ internal fun CordnAttachment(
|
||||
|
||||
if (mediaKey == null) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_media_download_failed),
|
||||
text = stringRes(Res.string.cordn_media_download_failed),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
@@ -1254,7 +1276,7 @@ internal fun VoiceNoteButton(
|
||||
) {
|
||||
Icon(
|
||||
symbol = if (recording) MaterialSymbols.Stop else MaterialSymbols.Mic,
|
||||
contentDescription = stringRes(if (recording) R.string.cordn_voice_stop else R.string.cordn_voice_record),
|
||||
contentDescription = stringRes(if (recording) Res.string.cordn_voice_stop else Res.string.cordn_voice_record),
|
||||
// Matches the attach icon beside it; red only while recording,
|
||||
// which is the one state worth pulling the eye.
|
||||
tint = if (recording) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.placeholderText,
|
||||
@@ -1284,10 +1306,10 @@ private suspend fun sendVoiceNote(
|
||||
// note that goes nowhere and says nothing is the same bug twice.
|
||||
val session =
|
||||
accountViewModel.account.cordnRuntime?.sessionOrNull(room.coordinatorPubKey)
|
||||
?: throw CordnAttachmentException(stringRes(context, R.string.cordn_send_no_session))
|
||||
?: throw CordnAttachmentException(loadStringRes(Res.string.cordn_send_no_session))
|
||||
val group =
|
||||
session.manager.group(room.gid)
|
||||
?: throw CordnAttachmentException(stringRes(context, R.string.cordn_send_no_session))
|
||||
?: throw CordnAttachmentException(loadStringRes(Res.string.cordn_send_no_session))
|
||||
|
||||
try {
|
||||
val bytes = withContext(Dispatchers.IO) { recording.file.readBytes() }
|
||||
@@ -1304,7 +1326,7 @@ private suspend fun sendVoiceNote(
|
||||
// is what makes the bubble match the preview.
|
||||
waveform = recording.amplitudes,
|
||||
)
|
||||
?: throw CordnAttachmentException(stringRes(context, R.string.cordn_media_no_server))
|
||||
?: throw CordnAttachmentException(loadStringRes(Res.string.cordn_media_no_server))
|
||||
// Into the room as well, for the same reason every other send is: an
|
||||
// attachment of your own echoes back as an Echo and would otherwise be
|
||||
// invisible to the person who sent it.
|
||||
|
||||
+103
-58
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.cordnGroup
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.clickable
|
||||
@@ -58,12 +57,10 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.cordn.CordnGroupException
|
||||
import com.vitorpamplona.amethyst.commons.cordn.GroupExposure
|
||||
import com.vitorpamplona.amethyst.commons.cordn.ui.CordnExposureCard
|
||||
@@ -76,8 +73,58 @@ import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.back
|
||||
import com.vitorpamplona.amethyst.commons.resources.cancel
|
||||
import com.vitorpamplona.amethyst.commons.resources.copy_npub_to_clipboard
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_admin_action_failed
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_admin_coordinator_silent
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_admin_no_key_package
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_admin_no_self_remove
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_admin_no_welcome
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_admin_not_a_member
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_admin_someone
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_admin_wrong_key_package
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_description
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_name
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_exposure_close
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_exposure_open
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_info
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable_detail
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_untitled
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_add_member
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_add_member_none
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_add_member_note
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_add_member_placeholder
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_admin_badge
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_admins_kept
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_coordinator
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_coordinator_key
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_coordinator_nprofile
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_copy_nprofile
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_edit_details
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_egalitarian
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_epoch
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_gid
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_has_key_package
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_members
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_remove_confirm_body
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_remove_confirm_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_remove_member
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_save
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_technical
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_member_count
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_requests_accept
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_requests_admin_only
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_requests_check
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_requests_decline
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_requests_failed
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_requests_none
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_requests_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_send_no_session
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_share_copied
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_share_copy
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_share_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_share_title
|
||||
import com.vitorpamplona.amethyst.commons.ui.components.EmptyState
|
||||
import com.vitorpamplona.amethyst.commons.ui.loadStringRes
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.commons.ui.theme.SuggestionListDefaultHeightChat
|
||||
import com.vitorpamplona.amethyst.commons.util.toShortDisplay
|
||||
@@ -124,8 +171,8 @@ fun CordnGroupInfoScreen(
|
||||
// The app's own empty state, centred and titled, rather than a
|
||||
// sentence stranded in the top-left corner.
|
||||
EmptyState(
|
||||
title = stringRes(R.string.cordn_group_unavailable),
|
||||
description = stringRes(R.string.cordn_group_unavailable_detail),
|
||||
title = stringRes(Res.string.cordn_group_unavailable),
|
||||
description = stringRes(Res.string.cordn_group_unavailable_detail),
|
||||
modifier = Modifier.padding(padding),
|
||||
)
|
||||
}
|
||||
@@ -151,7 +198,7 @@ private fun InfoTopBar(
|
||||
Icon(MaterialSymbols.AutoMirrored.ArrowBack, contentDescription = stringRes(Res.string.back))
|
||||
}
|
||||
},
|
||||
title = { Text(stringRes(R.string.cordn_group_info)) },
|
||||
title = { Text(stringRes(Res.string.cordn_group_info)) },
|
||||
actions = actions,
|
||||
)
|
||||
}
|
||||
@@ -208,8 +255,8 @@ private fun CordnGroupInfo(
|
||||
DisposableEffect(Unit) {
|
||||
onDispose { userSuggestions.reset() }
|
||||
}
|
||||
val failed = stringRes(R.string.cordn_admin_action_failed)
|
||||
val noSession = stringRes(R.string.cordn_send_no_session)
|
||||
val failed = stringRes(Res.string.cordn_admin_action_failed)
|
||||
val noSession = stringRes(Res.string.cordn_send_no_session)
|
||||
|
||||
// Computed, never asserted: hardcoding these made the card look like a
|
||||
// disclosure while reporting the same four values for every group.
|
||||
@@ -236,7 +283,6 @@ private fun CordnGroupInfo(
|
||||
* roster, and a rename stayed the old name. The runtime's own methods pair
|
||||
* each commit with that refresh.
|
||||
*/
|
||||
val context = LocalContext.current
|
||||
|
||||
fun runAdmin(
|
||||
who: String? = null,
|
||||
@@ -257,7 +303,7 @@ private fun CordnGroupInfo(
|
||||
// and gids in full, so the screen that had just shown a face
|
||||
// answered with 64 hex characters.
|
||||
Log.w("CordnGroupInfo", "admin action failed in ${room.gid}: ${e.message}", e)
|
||||
adminError = adminFailureText(context, e, who, failed)
|
||||
adminError = adminFailureText(e, who, failed)
|
||||
} finally {
|
||||
busy = false
|
||||
}
|
||||
@@ -274,7 +320,7 @@ private fun CordnGroupInfo(
|
||||
IconButton(onClick = { renaming = true }, enabled = !busy) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.Edit,
|
||||
contentDescription = stringRes(R.string.cordn_info_edit_details),
|
||||
contentDescription = stringRes(Res.string.cordn_info_edit_details),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -303,7 +349,7 @@ private fun CordnGroupInfo(
|
||||
}
|
||||
// A subtitle, not a labelled row above a list that is itself the count.
|
||||
Text(
|
||||
text = pluralStringRes(LocalContext.current, R.plurals.cordn_member_count, members.size, members.size),
|
||||
text = pluralStringRes(Res.plurals.cordn_member_count, members.size, members.size),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(top = 4.dp),
|
||||
@@ -321,7 +367,7 @@ private fun CordnGroupInfo(
|
||||
// ContextVM addresses it with ordinary p-tags, so it has a kind 0 like
|
||||
// anyone else and the app can already resolve it to a name, an avatar
|
||||
// and a profile to tap through to.
|
||||
Text(stringRes(R.string.cordn_info_coordinator), style = MaterialTheme.typography.titleMedium)
|
||||
Text(stringRes(Res.string.cordn_info_coordinator), style = MaterialTheme.typography.titleMedium)
|
||||
|
||||
Row(
|
||||
Modifier.fillMaxWidth().padding(top = 8.dp),
|
||||
@@ -347,7 +393,7 @@ private fun CordnGroupInfo(
|
||||
IconButton(onClick = { showExposure = true }, enabled = exposure != null) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.Info,
|
||||
contentDescription = stringRes(R.string.cordn_exposure_open),
|
||||
contentDescription = stringRes(Res.string.cordn_exposure_open),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
@@ -355,7 +401,7 @@ private fun CordnGroupInfo(
|
||||
|
||||
HorizontalDivider(Modifier.padding(vertical = 16.dp))
|
||||
|
||||
Text(stringRes(R.string.cordn_info_members), style = MaterialTheme.typography.titleMedium)
|
||||
Text(stringRes(Res.string.cordn_info_members), style = MaterialTheme.typography.titleMedium)
|
||||
|
||||
// Said once, and only when it is true. An empty admin set is not "none
|
||||
// configured" -- spec/01.md makes it permanently egalitarian, so the
|
||||
@@ -364,7 +410,7 @@ private fun CordnGroupInfo(
|
||||
// a count of them adds nothing.
|
||||
if (admins.isEmpty()) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_info_egalitarian),
|
||||
text = stringRes(Res.string.cordn_info_egalitarian),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(top = 2.dp, bottom = 4.dp),
|
||||
@@ -385,7 +431,7 @@ private fun CordnGroupInfo(
|
||||
)
|
||||
if (member in admins) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_info_admin_badge),
|
||||
text = stringRes(Res.string.cordn_info_admin_badge),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
@@ -398,7 +444,7 @@ private fun CordnGroupInfo(
|
||||
IconButton(onClick = { removing = member }, enabled = !busy) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.PersonRemove,
|
||||
contentDescription = stringRes(R.string.cordn_info_remove_member),
|
||||
contentDescription = stringRes(Res.string.cordn_info_remove_member),
|
||||
modifier = Modifier.size(20.dp),
|
||||
tint = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
@@ -476,9 +522,9 @@ private fun CordnGroupInfo(
|
||||
// would be a setting nobody should be nudged into.
|
||||
AlertDialog(
|
||||
onDismissRequest = { removing = null },
|
||||
title = { Text(stringRes(R.string.cordn_info_remove_confirm_title)) },
|
||||
title = { Text(stringRes(Res.string.cordn_info_remove_confirm_title)) },
|
||||
text = {
|
||||
Text(stringRes(R.string.cordn_info_remove_confirm_body, removingName))
|
||||
Text(stringRes(Res.string.cordn_info_remove_confirm_body, removingName))
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(onClick = {
|
||||
@@ -486,7 +532,7 @@ private fun CordnGroupInfo(
|
||||
runAdmin(removingName) { it.removeMember(coordinatorPubKey, room.gid, target) }
|
||||
}) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_info_remove_member),
|
||||
text = stringRes(Res.string.cordn_info_remove_member),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
@@ -518,7 +564,7 @@ private fun CordnGroupInfo(
|
||||
text = { CordnExposureCard(it) },
|
||||
confirmButton = {
|
||||
TextButton(onClick = { showExposure = false }) {
|
||||
Text(stringRes(R.string.cordn_exposure_close))
|
||||
Text(stringRes(Res.string.cordn_exposure_close))
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -577,15 +623,15 @@ private fun CordnAddMember(
|
||||
OutlinedTextField(
|
||||
value = search,
|
||||
onValueChange = onSearchChange,
|
||||
label = { Text(stringRes(R.string.cordn_info_add_member)) },
|
||||
placeholder = { Text(stringRes(R.string.cordn_info_add_member_placeholder)) },
|
||||
label = { Text(stringRes(Res.string.cordn_info_add_member)) },
|
||||
placeholder = { Text(stringRes(Res.string.cordn_info_add_member_placeholder)) },
|
||||
singleLine = true,
|
||||
enabled = !busy,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_info_add_member_note),
|
||||
text = stringRes(Res.string.cordn_info_add_member_note),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(top = 4.dp),
|
||||
@@ -601,7 +647,7 @@ private fun CordnAddMember(
|
||||
modifier = SuggestionListDefaultHeightChat,
|
||||
onEmpty = {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_info_add_member_none),
|
||||
text = stringRes(Res.string.cordn_info_add_member_none),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
@@ -612,7 +658,7 @@ private fun CordnAddMember(
|
||||
if (reachable?.contains(user.pubkeyHex) == true) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.Key,
|
||||
contentDescription = stringRes(R.string.cordn_info_has_key_package),
|
||||
contentDescription = stringRes(Res.string.cordn_info_has_key_package),
|
||||
modifier = Modifier.size(16.dp),
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
@@ -620,7 +666,7 @@ private fun CordnAddMember(
|
||||
IconButton(onClick = { onInvite(user) }) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.PersonAdd,
|
||||
contentDescription = stringRes(R.string.cordn_info_add_member),
|
||||
contentDescription = stringRes(Res.string.cordn_info_add_member),
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
}
|
||||
@@ -643,20 +689,19 @@ private fun CordnAddMember(
|
||||
* better than silence — and the caller has logged the throwable in full either
|
||||
* way.
|
||||
*/
|
||||
private fun adminFailureText(
|
||||
context: Context,
|
||||
private suspend fun adminFailureText(
|
||||
e: Throwable,
|
||||
who: String?,
|
||||
fallback: String,
|
||||
): String {
|
||||
val name = who ?: stringRes(context, R.string.cordn_admin_someone)
|
||||
val name = who ?: loadStringRes(Res.string.cordn_admin_someone)
|
||||
return when (e) {
|
||||
is CordnGroupException ->
|
||||
when (e.reason) {
|
||||
CordnGroupException.Reason.NO_KEY_PACKAGE -> stringRes(context, R.string.cordn_admin_no_key_package, name)
|
||||
CordnGroupException.Reason.WRONG_KEY_PACKAGE_OWNER -> stringRes(context, R.string.cordn_admin_wrong_key_package, name)
|
||||
CordnGroupException.Reason.NO_WELCOME -> stringRes(context, R.string.cordn_admin_no_welcome, name)
|
||||
CordnGroupException.Reason.NOT_A_MEMBER -> stringRes(context, R.string.cordn_admin_not_a_member, name)
|
||||
CordnGroupException.Reason.NO_KEY_PACKAGE -> loadStringRes(Res.string.cordn_admin_no_key_package, name)
|
||||
CordnGroupException.Reason.WRONG_KEY_PACKAGE_OWNER -> loadStringRes(Res.string.cordn_admin_wrong_key_package, name)
|
||||
CordnGroupException.Reason.NO_WELCOME -> loadStringRes(Res.string.cordn_admin_no_welcome, name)
|
||||
CordnGroupException.Reason.NOT_A_MEMBER -> loadStringRes(Res.string.cordn_admin_not_a_member, name)
|
||||
CordnGroupException.Reason.OTHER -> e.message ?: fallback
|
||||
}
|
||||
|
||||
@@ -664,14 +709,14 @@ private fun adminFailureText(
|
||||
// roster and the button disagreed rather than that anyone tried.
|
||||
is IllegalArgumentException ->
|
||||
if (e.message?.contains("self-removal") == true) {
|
||||
stringRes(context, R.string.cordn_admin_no_self_remove)
|
||||
loadStringRes(Res.string.cordn_admin_no_self_remove)
|
||||
} else {
|
||||
e.message ?: fallback
|
||||
}
|
||||
|
||||
// A coordinator that does not answer is the single commonest failure
|
||||
// here and says nothing useful in its own words.
|
||||
is TimeoutCancellationException -> stringRes(context, R.string.cordn_admin_coordinator_silent)
|
||||
is TimeoutCancellationException -> loadStringRes(Res.string.cordn_admin_coordinator_silent)
|
||||
|
||||
else -> e.message ?: fallback
|
||||
}
|
||||
@@ -701,7 +746,7 @@ private fun TechnicalDetails(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_info_technical),
|
||||
text = stringRes(Res.string.cordn_info_technical),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
@@ -725,22 +770,22 @@ private fun TechnicalDetails(
|
||||
val coordinator = remember(coordinatorPubKey) { LocalCache.getOrCreateUser(coordinatorPubKey) }
|
||||
|
||||
CopyableKeyRow(
|
||||
label = stringRes(R.string.cordn_info_coordinator_key),
|
||||
label = stringRes(Res.string.cordn_info_coordinator_key),
|
||||
shown = coordinator.pubkeyDisplayHex(),
|
||||
copied = coordinator.pubkeyNpub(),
|
||||
copyDescription = stringRes(Res.string.copy_npub_to_clipboard),
|
||||
)
|
||||
CopyableKeyRow(
|
||||
label = stringRes(R.string.cordn_info_coordinator_nprofile),
|
||||
label = stringRes(Res.string.cordn_info_coordinator_nprofile),
|
||||
shown = coordinator.toNProfile().toShortDisplay(6),
|
||||
copied = coordinator.toNProfile(),
|
||||
copyDescription = stringRes(R.string.cordn_info_copy_nprofile),
|
||||
copyDescription = stringRes(Res.string.cordn_info_copy_nprofile),
|
||||
)
|
||||
|
||||
SelectionContainer {
|
||||
Column {
|
||||
InfoRow(stringRes(R.string.cordn_info_gid), gid)
|
||||
InfoRow(stringRes(R.string.cordn_info_epoch), epoch.toString())
|
||||
InfoRow(stringRes(Res.string.cordn_info_gid), gid)
|
||||
InfoRow(stringRes(Res.string.cordn_info_epoch), epoch.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -835,7 +880,7 @@ private fun JoinRequests(
|
||||
) {
|
||||
val runtime = accountViewModel.account.cordnRuntime ?: return
|
||||
val scope = rememberCoroutineScope()
|
||||
val failed = stringRes(R.string.cordn_requests_failed)
|
||||
val failed = stringRes(Res.string.cordn_requests_failed)
|
||||
|
||||
var requests by remember { mutableStateOf<List<JoinRequest>?>(null) }
|
||||
var busy by remember { mutableStateOf(false) }
|
||||
@@ -853,15 +898,15 @@ private fun JoinRequests(
|
||||
}
|
||||
}
|
||||
|
||||
Text(stringRes(R.string.cordn_requests_title), style = MaterialTheme.typography.titleMedium)
|
||||
Text(stringRes(Res.string.cordn_requests_title), style = MaterialTheme.typography.titleMedium)
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_requests_admin_only),
|
||||
text = stringRes(Res.string.cordn_requests_admin_only),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
|
||||
OutlinedButton(onClick = { scope.launch { reload() } }, enabled = !busy) {
|
||||
Text(stringRes(R.string.cordn_requests_check))
|
||||
Text(stringRes(Res.string.cordn_requests_check))
|
||||
}
|
||||
|
||||
error?.let { Text(it, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.error) }
|
||||
@@ -870,7 +915,7 @@ private fun JoinRequests(
|
||||
if (loaded != null && !busy) {
|
||||
if (loaded.isEmpty()) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_requests_none),
|
||||
text = stringRes(Res.string.cordn_requests_none),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -899,7 +944,7 @@ private fun JoinRequests(
|
||||
reload()
|
||||
}
|
||||
}) {
|
||||
Text(stringRes(R.string.cordn_requests_accept))
|
||||
Text(stringRes(Res.string.cordn_requests_accept))
|
||||
}
|
||||
TextButton(onClick = {
|
||||
scope.launch {
|
||||
@@ -911,7 +956,7 @@ private fun JoinRequests(
|
||||
reload()
|
||||
}
|
||||
}) {
|
||||
Text(stringRes(R.string.cordn_requests_decline))
|
||||
Text(stringRes(Res.string.cordn_requests_decline))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -949,9 +994,9 @@ private fun ShareGroup(
|
||||
val clipboard = LocalClipboardManager.current
|
||||
var copied by remember { mutableStateOf(false) }
|
||||
|
||||
Text(stringRes(R.string.cordn_share_title), style = MaterialTheme.typography.titleMedium)
|
||||
Text(stringRes(Res.string.cordn_share_title), style = MaterialTheme.typography.titleMedium)
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_share_explainer),
|
||||
text = stringRes(Res.string.cordn_share_explainer),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -968,7 +1013,7 @@ private fun ShareGroup(
|
||||
},
|
||||
modifier = Modifier.padding(top = 8.dp),
|
||||
) {
|
||||
Text(stringRes(if (copied) R.string.cordn_share_copied else R.string.cordn_share_copy))
|
||||
Text(stringRes(if (copied) Res.string.cordn_share_copied else Res.string.cordn_share_copy))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -993,26 +1038,26 @@ private fun EditGroupDetailsDialog(
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text(stringRes(R.string.cordn_info_edit_details)) },
|
||||
title = { Text(stringRes(Res.string.cordn_info_edit_details)) },
|
||||
text = {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
OutlinedTextField(
|
||||
value = draftName,
|
||||
onValueChange = { draftName = it },
|
||||
label = { Text(stringRes(R.string.cordn_create_name)) },
|
||||
label = { Text(stringRes(Res.string.cordn_create_name)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = draftDescription,
|
||||
onValueChange = { draftDescription = it },
|
||||
label = { Text(stringRes(R.string.cordn_create_description)) },
|
||||
label = { Text(stringRes(Res.string.cordn_create_description)) },
|
||||
singleLine = false,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
if (admins.isNotEmpty()) {
|
||||
Text(
|
||||
text = pluralStringRes(LocalContext.current, R.plurals.cordn_info_admins_kept, admins.size, admins.size),
|
||||
text = pluralStringRes(Res.plurals.cordn_info_admins_kept, admins.size, admins.size),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -1024,7 +1069,7 @@ private fun EditGroupDetailsDialog(
|
||||
onClick = { onSave(draftName.trim(), draftDescription.trim()) },
|
||||
enabled = draftName.isNotBlank(),
|
||||
) {
|
||||
Text(stringRes(R.string.cordn_info_save))
|
||||
Text(stringRes(Res.string.cordn_info_save))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
|
||||
+16
-10
@@ -41,10 +41,8 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.cordn.CoordinatorHealth
|
||||
import com.vitorpamplona.amethyst.commons.cordn.ui.CoordinatorHealthRow
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||
@@ -52,6 +50,14 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
import com.vitorpamplona.amethyst.commons.model.cordnGroups.CordnGroupChatroom
|
||||
import com.vitorpamplona.amethyst.commons.model.navigation.Route
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable_detail
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_groups_count
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_groups_down_note
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_groups_manage
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_groups_none
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_groups_none_detail
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_groups_start
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_groups_title
|
||||
import com.vitorpamplona.amethyst.commons.ui.components.EmptyState
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
@@ -106,14 +112,14 @@ fun CordnGroupListScreen(
|
||||
IconButton(onClick = { nav.nav(Route.CordnCoordinators) }) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.Dns,
|
||||
contentDescription = stringRes(R.string.cordn_groups_manage),
|
||||
contentDescription = stringRes(Res.string.cordn_groups_manage),
|
||||
modifier = Modifier.size(22.dp),
|
||||
)
|
||||
}
|
||||
IconButton(onClick = { nav.nav(Route.CordnCreateGroup) }) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.Add,
|
||||
contentDescription = stringRes(R.string.cordn_groups_start),
|
||||
contentDescription = stringRes(Res.string.cordn_groups_start),
|
||||
modifier = Modifier.size(24.dp),
|
||||
)
|
||||
}
|
||||
@@ -122,8 +128,8 @@ fun CordnGroupListScreen(
|
||||
) { padding ->
|
||||
if (runtime == null) {
|
||||
EmptyState(
|
||||
title = stringRes(R.string.cordn_group_unavailable),
|
||||
description = stringRes(R.string.cordn_group_unavailable_detail),
|
||||
title = stringRes(Res.string.cordn_group_unavailable),
|
||||
description = stringRes(Res.string.cordn_group_unavailable_detail),
|
||||
modifier = Modifier.padding(padding),
|
||||
)
|
||||
return@Scaffold
|
||||
@@ -148,8 +154,8 @@ fun CordnGroupListScreen(
|
||||
|
||||
if (sections.isEmpty()) {
|
||||
EmptyState(
|
||||
title = stringRes(R.string.cordn_groups_none),
|
||||
description = stringRes(R.string.cordn_groups_none_detail),
|
||||
title = stringRes(Res.string.cordn_groups_none),
|
||||
description = stringRes(Res.string.cordn_groups_none_detail),
|
||||
modifier = Modifier.padding(padding),
|
||||
)
|
||||
return@Scaffold
|
||||
@@ -230,7 +236,7 @@ private fun CoordinatorSection(
|
||||
},
|
||||
)
|
||||
Text(
|
||||
text = pluralStringRes(LocalContext.current, R.plurals.cordn_groups_count, groupCount, groupCount),
|
||||
text = pluralStringRes(Res.plurals.cordn_groups_count, groupCount, groupCount),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -248,7 +254,7 @@ private fun CoordinatorSection(
|
||||
verticalAlignment = Alignment.Top,
|
||||
) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_groups_down_note),
|
||||
text = stringRes(Res.string.cordn_groups_down_note),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
|
||||
+33
-18
@@ -48,16 +48,30 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
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.commons.model.navigation.Route
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.back
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable_detail
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_untitled
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_invitations_accept
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_invitations_decline
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_invitations_decline_warning
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_invitations_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_invitations_load_failed
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_invitations_members
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_invitations_members_more
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_invitations_no_coordinators
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_invitations_none
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_invitations_refresh
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_invitations_skipped
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_invitations_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_invitations_unreachable
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_invitations_via
|
||||
import com.vitorpamplona.amethyst.commons.ui.components.EmptyState
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.model.cordn.CordnInvitation
|
||||
@@ -69,6 +83,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.cordn.CoordinatorI
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.cordn.coordinatorDisplayName
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.compose.resources.pluralStringResource
|
||||
|
||||
/**
|
||||
* Invitations to cordn groups, waiting to be answered.
|
||||
@@ -106,7 +121,7 @@ fun CordnInvitationsScreen(
|
||||
var invitations by remember { mutableStateOf<CordnInvitations?>(null) }
|
||||
var busy by remember { mutableStateOf(false) }
|
||||
var error by remember { mutableStateOf<String?>(null) }
|
||||
val loadFailed = stringRes(R.string.cordn_invitations_load_failed)
|
||||
val loadFailed = stringRes(Res.string.cordn_invitations_load_failed)
|
||||
|
||||
suspend fun reload() {
|
||||
busy = true
|
||||
@@ -130,10 +145,10 @@ fun CordnInvitationsScreen(
|
||||
Icon(MaterialSymbols.AutoMirrored.ArrowBack, contentDescription = stringRes(Res.string.back))
|
||||
}
|
||||
},
|
||||
title = { Text(stringRes(R.string.cordn_invitations_title)) },
|
||||
title = { Text(stringRes(Res.string.cordn_invitations_title)) },
|
||||
actions = {
|
||||
IconButton(onClick = { scope.launch { reload() } }, enabled = !busy) {
|
||||
Icon(MaterialSymbols.Refresh, contentDescription = stringRes(R.string.cordn_invitations_refresh))
|
||||
Icon(MaterialSymbols.Refresh, contentDescription = stringRes(Res.string.cordn_invitations_refresh))
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -150,8 +165,8 @@ fun CordnInvitationsScreen(
|
||||
) {
|
||||
if (runtime == null) {
|
||||
EmptyState(
|
||||
title = stringRes(R.string.cordn_group_unavailable),
|
||||
description = stringRes(R.string.cordn_group_unavailable_detail),
|
||||
title = stringRes(Res.string.cordn_group_unavailable),
|
||||
description = stringRes(Res.string.cordn_group_unavailable_detail),
|
||||
)
|
||||
return@Column
|
||||
}
|
||||
@@ -163,7 +178,7 @@ fun CordnInvitationsScreen(
|
||||
val coordinators by runtime.coordinators.collectAsStateWithLifecycle()
|
||||
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_invitations_explainer),
|
||||
text = stringRes(Res.string.cordn_invitations_explainer),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -212,7 +227,7 @@ fun CordnInvitationsScreen(
|
||||
NoticeCard(
|
||||
title =
|
||||
stringRes(
|
||||
R.string.cordn_invitations_unreachable,
|
||||
Res.string.cordn_invitations_unreachable,
|
||||
coordinatorDisplayName(it.coordinator.pubKey, it.coordinator.label, accountViewModel),
|
||||
),
|
||||
detail = it.reason,
|
||||
@@ -225,7 +240,7 @@ fun CordnInvitationsScreen(
|
||||
// friend swears they sent simply does not exist here.
|
||||
loaded.skipped.forEach {
|
||||
NoticeCard(
|
||||
title = stringRes(R.string.cordn_invitations_skipped),
|
||||
title = stringRes(Res.string.cordn_invitations_skipped),
|
||||
detail = it.reason,
|
||||
isError = false,
|
||||
)
|
||||
@@ -235,9 +250,9 @@ fun CordnInvitationsScreen(
|
||||
Text(
|
||||
text =
|
||||
if (coordinators.isEmpty()) {
|
||||
stringRes(R.string.cordn_invitations_no_coordinators)
|
||||
stringRes(Res.string.cordn_invitations_no_coordinators)
|
||||
} else {
|
||||
stringRes(R.string.cordn_invitations_none)
|
||||
stringRes(Res.string.cordn_invitations_none)
|
||||
},
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
@@ -276,7 +291,7 @@ private fun InvitationCard(
|
||||
|
||||
// "Already in it", never "invited you" — see the screen KDoc.
|
||||
Text(
|
||||
text = pluralStringResource(R.plurals.cordn_invitations_members, welcome.members.size, welcome.members.size),
|
||||
text = pluralStringResource(Res.plurals.cordn_invitations_members, welcome.members.size, welcome.members.size),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -300,7 +315,7 @@ private fun InvitationCard(
|
||||
}
|
||||
if (welcome.members.size > MEMBER_FACES) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_invitations_members_more, welcome.members.size - MEMBER_FACES),
|
||||
text = stringRes(Res.string.cordn_invitations_members_more, welcome.members.size - MEMBER_FACES),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -329,7 +344,7 @@ private fun InvitationCard(
|
||||
size = 20.dp,
|
||||
) { name ->
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_invitations_via, name),
|
||||
text = stringRes(Res.string.cordn_invitations_via, name),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -340,11 +355,11 @@ private fun InvitationCard(
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Button(onClick = onAccept) { Text(stringRes(R.string.cordn_invitations_accept)) }
|
||||
TextButton(onClick = onDecline) { Text(stringRes(R.string.cordn_invitations_decline)) }
|
||||
Button(onClick = onAccept) { Text(stringRes(Res.string.cordn_invitations_accept)) }
|
||||
TextButton(onClick = onDecline) { Text(stringRes(Res.string.cordn_invitations_decline)) }
|
||||
}
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_invitations_decline_warning),
|
||||
text = stringRes(Res.string.cordn_invitations_decline_warning),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
|
||||
+39
-22
@@ -55,7 +55,6 @@ 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.chats.ui.ChatDivisor
|
||||
import com.vitorpamplona.amethyst.commons.chats.ui.UserDisplayNameLayout
|
||||
import com.vitorpamplona.amethyst.commons.cordn.CordnMentions
|
||||
@@ -67,6 +66,24 @@ import com.vitorpamplona.amethyst.commons.model.navigation.Route
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.copied_to_clipboard
|
||||
import com.vitorpamplona.amethyst.commons.resources.copy_text
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_action_delete
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_action_edit
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_action_go_to_message
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_action_pin
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_action_reply
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_action_unpin
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_chat_unread_divider
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_chat_yesterday
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_delete_confirm_body
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_delete_confirm_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_delivery_accepted
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_message_deleted
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_message_details_coordinator
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_message_details_cursor
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_message_details_sent_at
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_message_details_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_message_edited
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_reactions_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.quick_action_share
|
||||
import com.vitorpamplona.amethyst.commons.resources.today
|
||||
import com.vitorpamplona.amethyst.commons.ui.components.ClickableBox
|
||||
@@ -292,7 +309,7 @@ private fun CordnBubbleContents(
|
||||
when {
|
||||
text == null ->
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_message_deleted),
|
||||
text = stringRes(Res.string.cordn_message_deleted),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -448,7 +465,7 @@ private fun CordnReactionDetailSheet(
|
||||
) {
|
||||
Column(Modifier.fillMaxWidth().verticalScroll(rememberScrollState()).padding(bottom = 24.dp)) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_reactions_title),
|
||||
text = stringRes(Res.string.cordn_reactions_title),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
modifier = Modifier.padding(horizontal = 20.dp, vertical = 12.dp),
|
||||
)
|
||||
@@ -519,7 +536,7 @@ internal fun CordnQuotedMessage(
|
||||
|
||||
val body =
|
||||
if (annotations.isDeleted(parent.envelope.id)) {
|
||||
stringRes(R.string.cordn_message_deleted)
|
||||
stringRes(Res.string.cordn_message_deleted)
|
||||
} else {
|
||||
annotations.contentOf(parent.envelope.id).orEmpty()
|
||||
}
|
||||
@@ -575,7 +592,7 @@ private fun CordnQuoteActionSheet(
|
||||
Column(Modifier.padding(bottom = 24.dp)) {
|
||||
TileRow {
|
||||
if (onGoToMessage != null) {
|
||||
ActionTile(MaterialSymbols.ArrowUpward, stringRes(R.string.cordn_action_go_to_message)) {
|
||||
ActionTile(MaterialSymbols.ArrowUpward, stringRes(Res.string.cordn_action_go_to_message)) {
|
||||
onGoToMessage()
|
||||
onDismiss()
|
||||
}
|
||||
@@ -594,7 +611,7 @@ private fun CordnQuoteActionSheet(
|
||||
*/
|
||||
@Composable
|
||||
internal fun UnreadDivider() {
|
||||
ChatDivisor(stringRes(R.string.cordn_chat_unread_divider), MaterialTheme.colorScheme.primary)
|
||||
ChatDivisor(stringRes(Res.string.cordn_chat_unread_divider), MaterialTheme.colorScheme.primary)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -618,7 +635,7 @@ private fun CordnMessageFooter(
|
||||
if (isPinned) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.PushPin,
|
||||
contentDescription = stringRes(R.string.cordn_action_pin),
|
||||
contentDescription = stringRes(Res.string.cordn_action_pin),
|
||||
modifier = Modifier.size(12.dp),
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
@@ -627,7 +644,7 @@ private fun CordnMessageFooter(
|
||||
|
||||
if (isEdited) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_message_edited),
|
||||
text = stringRes(Res.string.cordn_message_edited),
|
||||
fontSize = Font12SP,
|
||||
color = MaterialTheme.colorScheme.placeholderText,
|
||||
maxLines = 1,
|
||||
@@ -658,7 +675,7 @@ private fun CordnMessageFooter(
|
||||
Spacer(StdHorzSpacer)
|
||||
Icon(
|
||||
symbol = MaterialSymbols.Done,
|
||||
contentDescription = stringRes(R.string.cordn_delivery_accepted),
|
||||
contentDescription = stringRes(Res.string.cordn_delivery_accepted),
|
||||
modifier = Modifier.size(12.dp),
|
||||
tint = MaterialTheme.colorScheme.allGoodColor,
|
||||
)
|
||||
@@ -711,18 +728,18 @@ private fun CordnMessageDetailsSheet(
|
||||
verticalArrangement = Arrangement.spacedBy(6.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_message_details_title),
|
||||
text = stringRes(Res.string.cordn_message_details_title),
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
)
|
||||
DetailLine(stringRes(R.string.cordn_message_details_sent_at), sentAt)
|
||||
DetailLine(stringRes(R.string.cordn_message_details_cursor), message.cursor.toString())
|
||||
DetailLine(stringRes(Res.string.cordn_message_details_sent_at), sentAt)
|
||||
DetailLine(stringRes(Res.string.cordn_message_details_cursor), message.cursor.toString())
|
||||
DetailLine(
|
||||
stringRes(R.string.cordn_message_details_coordinator),
|
||||
stringRes(Res.string.cordn_message_details_coordinator),
|
||||
coordinatorDisplayName(coordinatorPubKey, label = null, accountViewModel = accountViewModel),
|
||||
)
|
||||
if (isMine) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_delivery_accepted),
|
||||
text = stringRes(Res.string.cordn_delivery_accepted),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.allGoodColor,
|
||||
)
|
||||
@@ -797,10 +814,10 @@ private fun CordnMessageActionSheet(
|
||||
|
||||
if (confirmingDelete) {
|
||||
QuickActionAlertDialog(
|
||||
title = stringRes(R.string.cordn_delete_confirm_title),
|
||||
textContent = stringRes(R.string.cordn_delete_confirm_body),
|
||||
title = stringRes(Res.string.cordn_delete_confirm_title),
|
||||
textContent = stringRes(Res.string.cordn_delete_confirm_body),
|
||||
buttonIcon = MaterialSymbols.Delete,
|
||||
buttonText = stringRes(R.string.cordn_action_delete),
|
||||
buttonText = stringRes(Res.string.cordn_action_delete),
|
||||
onClickDoOnce = performDelete,
|
||||
onClickDontShowAgain = {
|
||||
accountViewModel.account.settings.setHideDeleteRequestDialog()
|
||||
@@ -843,7 +860,7 @@ private fun CordnMessageActionSheet(
|
||||
|
||||
TileRow {
|
||||
if (isLive) {
|
||||
ActionTile(MaterialSymbols.AutoMirrored.Chat, stringRes(R.string.cordn_action_reply)) {
|
||||
ActionTile(MaterialSymbols.AutoMirrored.Chat, stringRes(Res.string.cordn_action_reply)) {
|
||||
onReply()
|
||||
onDismiss()
|
||||
}
|
||||
@@ -853,7 +870,7 @@ private fun CordnMessageActionSheet(
|
||||
// message rather than only on your own.
|
||||
ActionTile(
|
||||
MaterialSymbols.PushPin,
|
||||
stringRes(if (isPinned) R.string.cordn_action_unpin else R.string.cordn_action_pin),
|
||||
stringRes(if (isPinned) Res.string.cordn_action_unpin else Res.string.cordn_action_pin),
|
||||
) {
|
||||
onTogglePin()
|
||||
onDismiss()
|
||||
@@ -863,11 +880,11 @@ private fun CordnMessageActionSheet(
|
||||
// anyone else. Hiding them here is the same rule, stated where it stops
|
||||
// being a surprise.
|
||||
if (isMine && isLive) {
|
||||
ActionTile(MaterialSymbols.Edit, stringRes(R.string.cordn_action_edit)) {
|
||||
ActionTile(MaterialSymbols.Edit, stringRes(Res.string.cordn_action_edit)) {
|
||||
onEdit()
|
||||
onDismiss()
|
||||
}
|
||||
ActionTile(MaterialSymbols.Delete, stringRes(R.string.cordn_action_delete), isDestructive = true) {
|
||||
ActionTile(MaterialSymbols.Delete, stringRes(Res.string.cordn_action_delete), isDestructive = true) {
|
||||
// A withdrawal cannot be taken back and the coordinator keeps
|
||||
// the ciphertext either way, so it is worth one question —
|
||||
// unless the account has already opted out of being asked.
|
||||
@@ -989,7 +1006,7 @@ internal fun DaySeparator(
|
||||
val label =
|
||||
when (day) {
|
||||
today -> stringRes(Res.string.today)
|
||||
today.minusDays(1) -> stringRes(R.string.cordn_chat_yesterday)
|
||||
today.minusDays(1) -> stringRes(Res.string.cordn_chat_yesterday)
|
||||
// Year included only when it is not this one: printing 2026 on every
|
||||
// divider all year is noise.
|
||||
else ->
|
||||
|
||||
+29
-16
@@ -52,13 +52,26 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.cancel
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_contents_body
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_contents_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_export
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_exported
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_failed
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_passphrase
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_restore
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_restore_body
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_restore_confirm_body
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_restore_confirm_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_restored
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_section_export
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_section_passphrase
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_section_restore
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_backup_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable_detail
|
||||
import com.vitorpamplona.amethyst.commons.ui.components.EmptyState
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton
|
||||
@@ -113,9 +126,9 @@ fun CordnBackupScreen(
|
||||
var error by remember { mutableStateOf<String?>(null) }
|
||||
var pendingRestore by remember { mutableStateOf<Uri?>(null) }
|
||||
|
||||
val exported = stringRes(R.string.cordn_backup_exported)
|
||||
val restored = stringRes(R.string.cordn_backup_restored)
|
||||
val failed = stringRes(R.string.cordn_backup_failed)
|
||||
val exported = stringRes(Res.string.cordn_backup_exported)
|
||||
val restored = stringRes(Res.string.cordn_backup_restored)
|
||||
val failed = stringRes(Res.string.cordn_backup_failed)
|
||||
|
||||
val saver =
|
||||
rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument("application/octet-stream")) { uri ->
|
||||
@@ -179,8 +192,8 @@ fun CordnBackupScreen(
|
||||
// The app's own empty state, centred and titled, rather than a
|
||||
// sentence stranded in the top-left corner.
|
||||
EmptyState(
|
||||
title = stringRes(R.string.cordn_group_unavailable),
|
||||
description = stringRes(R.string.cordn_group_unavailable_detail),
|
||||
title = stringRes(Res.string.cordn_group_unavailable),
|
||||
description = stringRes(Res.string.cordn_group_unavailable_detail),
|
||||
modifier = Modifier.padding(padding),
|
||||
)
|
||||
return@Scaffold
|
||||
@@ -196,7 +209,7 @@ fun CordnBackupScreen(
|
||||
verticalArrangement = Arrangement.spacedBy(20.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_backup_explainer),
|
||||
text = stringRes(Res.string.cordn_backup_explainer),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -212,7 +225,7 @@ fun CordnBackupScreen(
|
||||
passphrase = it
|
||||
error = null
|
||||
},
|
||||
label = { Text(stringRes(R.string.cordn_backup_passphrase)) },
|
||||
label = { Text(stringRes(Res.string.cordn_backup_passphrase)) },
|
||||
visualTransformation = PasswordVisualTransformation(),
|
||||
// The dots are only half of it. Without the password
|
||||
// keyboard type the IME treats this as ordinary prose:
|
||||
@@ -230,9 +243,9 @@ fun CordnBackupScreen(
|
||||
|
||||
SettingsSection(Res.string.cordn_backup_section_export) {
|
||||
SettingsFormBlock {
|
||||
Text(stringRes(R.string.cordn_backup_contents_title), style = MaterialTheme.typography.titleSmall)
|
||||
Text(stringRes(Res.string.cordn_backup_contents_title), style = MaterialTheme.typography.titleSmall)
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_backup_contents_body),
|
||||
text = stringRes(Res.string.cordn_backup_contents_body),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -248,7 +261,7 @@ fun CordnBackupScreen(
|
||||
// Key derivation here is scrypt, which is slow on
|
||||
// purpose, so a greyed-out button was the only sign
|
||||
// anything was happening for several seconds.
|
||||
BusyLabel(busy, stringRes(R.string.cordn_backup_export))
|
||||
BusyLabel(busy, stringRes(Res.string.cordn_backup_export))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,7 +269,7 @@ fun CordnBackupScreen(
|
||||
SettingsSection(Res.string.cordn_backup_section_restore) {
|
||||
SettingsFormBlock {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_backup_restore_body),
|
||||
text = stringRes(Res.string.cordn_backup_restore_body),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -266,7 +279,7 @@ fun CordnBackupScreen(
|
||||
enabled = !busy && passphrase.isNotBlank(),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
BusyLabel(busy, stringRes(R.string.cordn_backup_restore))
|
||||
BusyLabel(busy, stringRes(Res.string.cordn_backup_restore))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,8 +289,8 @@ fun CordnBackupScreen(
|
||||
pendingRestore?.let { uri ->
|
||||
AlertDialog(
|
||||
onDismissRequest = { pendingRestore = null },
|
||||
title = { Text(stringRes(R.string.cordn_backup_restore_confirm_title)) },
|
||||
text = { Text(stringRes(R.string.cordn_backup_restore_confirm_body)) },
|
||||
title = { Text(stringRes(Res.string.cordn_backup_restore_confirm_title)) },
|
||||
text = { Text(stringRes(Res.string.cordn_backup_restore_confirm_body)) },
|
||||
confirmButton = {
|
||||
TextButton(onClick = {
|
||||
pendingRestore = null
|
||||
@@ -302,7 +315,7 @@ fun CordnBackupScreen(
|
||||
}
|
||||
}
|
||||
}) {
|
||||
Text(stringRes(R.string.cordn_backup_restore), color = MaterialTheme.colorScheme.error)
|
||||
Text(stringRes(Res.string.cordn_backup_restore), color = MaterialTheme.colorScheme.error)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
|
||||
+74
-40
@@ -58,7 +58,6 @@ 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.cordn.CoordinatorConfig
|
||||
import com.vitorpamplona.amethyst.commons.cordn.CoordinatorHealth
|
||||
import com.vitorpamplona.amethyst.commons.cordn.CordnCoordinatorDiscovery
|
||||
@@ -68,10 +67,45 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
import com.vitorpamplona.amethyst.commons.model.cache.LocalCache
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.cancel
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_add_action
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_add_failed
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_copy_key
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_discover_action
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_discover_add
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_discover_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_discover_failed
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_discover_none
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_discover_seen
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_discover_unheard
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_health_down
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_health_ok
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_health_retrying
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_health_unknown
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_identify
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_key
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_label
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_label_note
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_more
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_none
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_purge
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_purge_body
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_purge_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_relays_label
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_remove
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_rename
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_section_discover
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_section_manual
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_section_yours
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_server
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_server_claim
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_server_silent
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_coordinator_pubkey
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_create_coordinator_relays
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable_detail
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_info_save
|
||||
import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled
|
||||
import com.vitorpamplona.amethyst.commons.ui.components.EmptyState
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
@@ -127,8 +161,8 @@ fun CordnCoordinatorsScreen(
|
||||
// The app's own empty state, centred and titled, rather than a
|
||||
// sentence stranded in the top-left corner.
|
||||
EmptyState(
|
||||
title = stringRes(R.string.cordn_group_unavailable),
|
||||
description = stringRes(R.string.cordn_group_unavailable_detail),
|
||||
title = stringRes(Res.string.cordn_group_unavailable),
|
||||
description = stringRes(Res.string.cordn_group_unavailable_detail),
|
||||
modifier = Modifier.padding(padding),
|
||||
)
|
||||
return@Scaffold
|
||||
@@ -146,7 +180,7 @@ fun CordnCoordinatorsScreen(
|
||||
verticalArrangement = Arrangement.spacedBy(20.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_coordinators_explainer),
|
||||
text = stringRes(Res.string.cordn_coordinators_explainer),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -165,7 +199,7 @@ fun CordnCoordinatorsScreen(
|
||||
|
||||
if (coordinators.isEmpty()) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_coordinators_none),
|
||||
text = stringRes(Res.string.cordn_coordinators_none),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -225,7 +259,7 @@ private fun CoordinatorCard(
|
||||
IconButton(onClick = { renaming = true }) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.Edit,
|
||||
contentDescription = stringRes(R.string.cordn_coordinators_rename),
|
||||
contentDescription = stringRes(Res.string.cordn_coordinators_rename),
|
||||
modifier = Modifier.size(18.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -264,10 +298,10 @@ private fun CoordinatorCard(
|
||||
// away on the clipboard, which is how a comparison is actually done.
|
||||
val coordinator = remember(config.pubKey) { LocalCache.getOrCreateUser(config.pubKey) }
|
||||
CopyableKeyRow(
|
||||
label = stringRes(R.string.cordn_coordinators_key),
|
||||
label = stringRes(Res.string.cordn_coordinators_key),
|
||||
shown = coordinator.pubkeyDisplayHex(),
|
||||
copied = coordinator.pubkeyNpub(),
|
||||
copyDescription = stringRes(R.string.cordn_coordinators_copy_key),
|
||||
copyDescription = stringRes(Res.string.cordn_coordinators_copy_key),
|
||||
)
|
||||
|
||||
// Every relay, not the first two and a count: this is the management
|
||||
@@ -275,7 +309,7 @@ private fun CoordinatorCard(
|
||||
// came here to check or to rule out.
|
||||
Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_coordinators_relays_label),
|
||||
text = stringRes(Res.string.cordn_coordinators_relays_label),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
)
|
||||
@@ -304,10 +338,10 @@ private fun CoordinatorCard(
|
||||
text =
|
||||
info?.let {
|
||||
stringRes(
|
||||
R.string.cordn_coordinators_server,
|
||||
Res.string.cordn_coordinators_server,
|
||||
listOfNotNull(it.name, it.version, it.protocolVersion).joinToString(" \u00b7 "),
|
||||
)
|
||||
} ?: stringRes(R.string.cordn_coordinators_server_silent),
|
||||
} ?: stringRes(Res.string.cordn_coordinators_server_silent),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -315,7 +349,7 @@ private fun CoordinatorCard(
|
||||
// Said next to it, every time, because a name on a settings
|
||||
// screen reads as verified and this one is not: §8.5 makes
|
||||
// the pubkey the identity and nothing else.
|
||||
text = stringRes(R.string.cordn_coordinators_server_claim),
|
||||
text = stringRes(Res.string.cordn_coordinators_server_claim),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -333,7 +367,7 @@ private fun CoordinatorCard(
|
||||
infoChecked = true
|
||||
}
|
||||
}) {
|
||||
Text(stringRes(R.string.cordn_coordinators_identify))
|
||||
Text(stringRes(Res.string.cordn_coordinators_identify))
|
||||
}
|
||||
|
||||
Spacer(Modifier.weight(1f))
|
||||
@@ -345,14 +379,14 @@ private fun CoordinatorCard(
|
||||
IconButton(onClick = { menuOpen = true }) {
|
||||
Icon(
|
||||
symbol = MaterialSymbols.MoreVert,
|
||||
contentDescription = stringRes(R.string.cordn_coordinators_more),
|
||||
contentDescription = stringRes(Res.string.cordn_coordinators_more),
|
||||
modifier = Modifier.size(20.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
DropdownMenu(expanded = menuOpen, onDismissRequest = { menuOpen = false }) {
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringRes(R.string.cordn_coordinators_remove)) },
|
||||
text = { Text(stringRes(Res.string.cordn_coordinators_remove)) },
|
||||
onClick = {
|
||||
menuOpen = false
|
||||
scope.launch { runtime.forget(config.pubKey) }
|
||||
@@ -361,7 +395,7 @@ private fun CoordinatorCard(
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_coordinators_purge),
|
||||
text = stringRes(Res.string.cordn_coordinators_purge),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
},
|
||||
@@ -378,14 +412,14 @@ private fun CoordinatorCard(
|
||||
if (confirmingPurge) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { confirmingPurge = false },
|
||||
title = { Text(stringRes(R.string.cordn_coordinators_purge_title)) },
|
||||
text = { Text(stringRes(R.string.cordn_coordinators_purge_body)) },
|
||||
title = { Text(stringRes(Res.string.cordn_coordinators_purge_title)) },
|
||||
text = { Text(stringRes(Res.string.cordn_coordinators_purge_body)) },
|
||||
confirmButton = {
|
||||
TextButton(onClick = {
|
||||
confirmingPurge = false
|
||||
scope.launch { runtime.purge(config.pubKey) }
|
||||
}) {
|
||||
Text(stringRes(R.string.cordn_coordinators_purge), color = MaterialTheme.colorScheme.error)
|
||||
Text(stringRes(Res.string.cordn_coordinators_purge), color = MaterialTheme.colorScheme.error)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
@@ -409,10 +443,10 @@ private fun CoordinatorCard(
|
||||
private fun HealthLine(state: CoordinatorHealth.State) {
|
||||
val text =
|
||||
when {
|
||||
state.isUnknown -> stringRes(R.string.cordn_coordinators_health_unknown)
|
||||
state.isDown -> stringRes(R.string.cordn_coordinators_health_down, state.consecutiveFailures)
|
||||
state.consecutiveFailures > 0 -> stringRes(R.string.cordn_coordinators_health_retrying)
|
||||
else -> stringRes(R.string.cordn_coordinators_health_ok)
|
||||
state.isUnknown -> stringRes(Res.string.cordn_coordinators_health_unknown)
|
||||
state.isDown -> stringRes(Res.string.cordn_coordinators_health_down, state.consecutiveFailures)
|
||||
state.consecutiveFailures > 0 -> stringRes(Res.string.cordn_coordinators_health_retrying)
|
||||
else -> stringRes(Res.string.cordn_coordinators_health_ok)
|
||||
}
|
||||
|
||||
Text(
|
||||
@@ -447,10 +481,10 @@ private fun DiscoverCoordinators(
|
||||
var result by remember { mutableStateOf<CordnCoordinatorDiscovery.Result?>(null) }
|
||||
var busy by remember { mutableStateOf(false) }
|
||||
var error by remember { mutableStateOf<String?>(null) }
|
||||
val failed = stringRes(R.string.cordn_coordinators_discover_failed)
|
||||
val failed = stringRes(Res.string.cordn_coordinators_discover_failed)
|
||||
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_coordinators_discover_explainer),
|
||||
text = stringRes(Res.string.cordn_coordinators_discover_explainer),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -475,7 +509,7 @@ private fun DiscoverCoordinators(
|
||||
CircularProgressIndicator(Modifier.size(16.dp), strokeWidth = 2.dp)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
}
|
||||
Text(stringRes(R.string.cordn_coordinators_discover_action))
|
||||
Text(stringRes(Res.string.cordn_coordinators_discover_action))
|
||||
}
|
||||
|
||||
error?.let { Text(it, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.error) }
|
||||
@@ -497,11 +531,11 @@ private fun DiscoverCoordinators(
|
||||
Text(
|
||||
text =
|
||||
if (found.unreachable.isEmpty()) {
|
||||
stringRes(R.string.cordn_coordinators_discover_none)
|
||||
stringRes(Res.string.cordn_coordinators_discover_none)
|
||||
} else {
|
||||
// "Nobody is announcing" and "we were not told" are
|
||||
// different answers and only one of them is final.
|
||||
stringRes(R.string.cordn_coordinators_discover_unheard, found.unreachable.size)
|
||||
stringRes(Res.string.cordn_coordinators_discover_unheard, found.unreachable.size)
|
||||
},
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
@@ -529,19 +563,19 @@ private fun RenameCoordinatorDialog(
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text(stringRes(R.string.cordn_coordinators_rename)) },
|
||||
title = { Text(stringRes(Res.string.cordn_coordinators_rename)) },
|
||||
text = {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
OutlinedTextField(
|
||||
value = input,
|
||||
onValueChange = { input = it },
|
||||
label = { Text(stringRes(R.string.cordn_coordinators_label)) },
|
||||
label = { Text(stringRes(Res.string.cordn_coordinators_label)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
Text(
|
||||
// The same caution the add form gives, for the same reason.
|
||||
text = stringRes(R.string.cordn_coordinators_label_note),
|
||||
text = stringRes(Res.string.cordn_coordinators_label_note),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -549,7 +583,7 @@ private fun RenameCoordinatorDialog(
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(onClick = { onSave(input.trim().ifEmpty { null }) }) {
|
||||
Text(stringRes(R.string.cordn_info_save))
|
||||
Text(stringRes(Res.string.cordn_info_save))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
@@ -601,7 +635,7 @@ private fun DiscoveredCard(
|
||||
Text(
|
||||
// Staleness matters more here than anywhere: the last live
|
||||
// survey found most announcements were months-dead demos.
|
||||
text = stringRes(R.string.cordn_coordinators_discover_seen, timeAgoNoDot(offer.announcedAt).trim()),
|
||||
text = stringRes(Res.string.cordn_coordinators_discover_seen, timeAgoNoDot(offer.announcedAt).trim()),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -619,7 +653,7 @@ private fun DiscoveredCard(
|
||||
enabled = !busy,
|
||||
modifier = Modifier.padding(top = 4.dp),
|
||||
) {
|
||||
Text(stringRes(R.string.cordn_coordinators_discover_add))
|
||||
Text(stringRes(Res.string.cordn_coordinators_discover_add))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -633,7 +667,7 @@ private fun AddCoordinator(runtime: CordnRuntime) {
|
||||
var labelInput by remember { mutableStateOf("") }
|
||||
var error by remember { mutableStateOf<String?>(null) }
|
||||
var busy by remember { mutableStateOf(false) }
|
||||
val failed = stringRes(R.string.cordn_coordinators_add_failed)
|
||||
val failed = stringRes(Res.string.cordn_coordinators_add_failed)
|
||||
|
||||
val config =
|
||||
remember(pubKeyInput, relaysInput, labelInput) {
|
||||
@@ -652,7 +686,7 @@ private fun AddCoordinator(runtime: CordnRuntime) {
|
||||
pubKeyInput = it
|
||||
error = null
|
||||
},
|
||||
label = { Text(stringRes(R.string.cordn_create_coordinator_pubkey)) },
|
||||
label = { Text(stringRes(Res.string.cordn_create_coordinator_pubkey)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
@@ -662,14 +696,14 @@ private fun AddCoordinator(runtime: CordnRuntime) {
|
||||
relaysInput = it
|
||||
error = null
|
||||
},
|
||||
label = { Text(stringRes(R.string.cordn_create_coordinator_relays)) },
|
||||
label = { Text(stringRes(Res.string.cordn_create_coordinator_relays)) },
|
||||
singleLine = false,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = labelInput,
|
||||
onValueChange = { labelInput = it },
|
||||
label = { Text(stringRes(R.string.cordn_coordinators_label)) },
|
||||
label = { Text(stringRes(Res.string.cordn_coordinators_label)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
@@ -677,7 +711,7 @@ private fun AddCoordinator(runtime: CordnRuntime) {
|
||||
Text(
|
||||
// A label is ours, never theirs. A coordinator cannot prove a name and
|
||||
// this one is not asked for one.
|
||||
text = stringRes(R.string.cordn_coordinators_label_note),
|
||||
text = stringRes(Res.string.cordn_coordinators_label_note),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -705,6 +739,6 @@ private fun AddCoordinator(runtime: CordnRuntime) {
|
||||
enabled = !busy && config != null,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Text(stringRes(R.string.cordn_coordinators_add_action))
|
||||
Text(stringRes(Res.string.cordn_coordinators_add_action))
|
||||
}
|
||||
}
|
||||
|
||||
+32
-18
@@ -47,14 +47,28 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.cordn.CoordinatorConfig
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_none
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable_detail
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_disclosure
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_explainer
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_failed
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_last_resort_no
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_last_resort_yes
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_orphans
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_orphans_body
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_publish
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_publish_last_resort
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_section
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_summary
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_topup_note
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_withdraw_all
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_keypackages_withdraw_orphans
|
||||
import com.vitorpamplona.amethyst.commons.ui.components.EmptyState
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton
|
||||
@@ -106,8 +120,8 @@ fun CordnKeyPackagesScreen(
|
||||
) { padding ->
|
||||
if (runtime == null) {
|
||||
EmptyState(
|
||||
title = stringRes(R.string.cordn_group_unavailable),
|
||||
description = stringRes(R.string.cordn_group_unavailable_detail),
|
||||
title = stringRes(Res.string.cordn_group_unavailable),
|
||||
description = stringRes(Res.string.cordn_group_unavailable_detail),
|
||||
modifier = Modifier.padding(padding),
|
||||
)
|
||||
return@Scaffold
|
||||
@@ -125,7 +139,7 @@ fun CordnKeyPackagesScreen(
|
||||
verticalArrangement = Arrangement.spacedBy(20.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_keypackages_explainer),
|
||||
text = stringRes(Res.string.cordn_keypackages_explainer),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -140,7 +154,7 @@ fun CordnKeyPackagesScreen(
|
||||
SettingsFormBlock {
|
||||
if (coordinators.isEmpty()) {
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_coordinators_none),
|
||||
text = stringRes(Res.string.cordn_coordinators_none),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -169,7 +183,7 @@ private fun CoordinatorKeyPackages(
|
||||
var rows by remember(config.pubKey) { mutableStateOf<List<CordnKeyPackageRow>?>(null) }
|
||||
var busy by remember(config.pubKey) { mutableStateOf(false) }
|
||||
var error by remember(config.pubKey) { mutableStateOf<String?>(null) }
|
||||
val failed = stringRes(R.string.cordn_keypackages_failed)
|
||||
val failed = stringRes(Res.string.cordn_keypackages_failed)
|
||||
|
||||
suspend fun reload() {
|
||||
busy = true
|
||||
@@ -204,15 +218,15 @@ private fun CoordinatorKeyPackages(
|
||||
val hasLastResort = loaded.any { it.lastResort }
|
||||
|
||||
Text(
|
||||
text = pluralStringRes(LocalContext.current, R.plurals.cordn_keypackages_summary, single, single),
|
||||
text = pluralStringRes(Res.plurals.cordn_keypackages_summary, single, single),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
Text(
|
||||
text =
|
||||
if (hasLastResort) {
|
||||
stringRes(R.string.cordn_keypackages_last_resort_yes)
|
||||
stringRes(Res.string.cordn_keypackages_last_resort_yes)
|
||||
} else {
|
||||
stringRes(R.string.cordn_keypackages_last_resort_no)
|
||||
stringRes(Res.string.cordn_keypackages_last_resort_no)
|
||||
},
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
@@ -225,11 +239,11 @@ private fun CoordinatorKeyPackages(
|
||||
) {
|
||||
Column(Modifier.padding(12.dp)) {
|
||||
Text(
|
||||
text = pluralStringRes(LocalContext.current, R.plurals.cordn_keypackages_orphans, orphans.size, orphans.size),
|
||||
text = pluralStringRes(Res.plurals.cordn_keypackages_orphans, orphans.size, orphans.size),
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
)
|
||||
Text(
|
||||
text = stringRes(R.string.cordn_keypackages_orphans_body),
|
||||
text = stringRes(Res.string.cordn_keypackages_orphans_body),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
TextButton(onClick = {
|
||||
@@ -242,7 +256,7 @@ private fun CoordinatorKeyPackages(
|
||||
reload()
|
||||
}
|
||||
}) {
|
||||
Text(stringRes(R.string.cordn_keypackages_withdraw_orphans))
|
||||
Text(stringRes(Res.string.cordn_keypackages_withdraw_orphans))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -251,7 +265,7 @@ private fun CoordinatorKeyPackages(
|
||||
Text(
|
||||
// Above the buttons, because it is the part that cannot be taken
|
||||
// back: §8.4 makes publishing an attributable, permanent record.
|
||||
text = stringRes(R.string.cordn_keypackages_disclosure),
|
||||
text = stringRes(Res.string.cordn_keypackages_disclosure),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -274,7 +288,7 @@ private fun CoordinatorKeyPackages(
|
||||
},
|
||||
enabled = !busy,
|
||||
) {
|
||||
Text(stringRes(R.string.cordn_keypackages_publish))
|
||||
Text(stringRes(Res.string.cordn_keypackages_publish))
|
||||
}
|
||||
OutlinedButton(
|
||||
onClick = {
|
||||
@@ -289,7 +303,7 @@ private fun CoordinatorKeyPackages(
|
||||
},
|
||||
enabled = !busy && !hasLastResort,
|
||||
) {
|
||||
Text(stringRes(R.string.cordn_keypackages_publish_last_resort))
|
||||
Text(stringRes(Res.string.cordn_keypackages_publish_last_resort))
|
||||
}
|
||||
if (loaded.isNotEmpty()) {
|
||||
TextButton(
|
||||
@@ -305,7 +319,7 @@ private fun CoordinatorKeyPackages(
|
||||
},
|
||||
enabled = !busy,
|
||||
) {
|
||||
Text(stringRes(R.string.cordn_keypackages_withdraw_all), color = MaterialTheme.colorScheme.error)
|
||||
Text(stringRes(Res.string.cordn_keypackages_withdraw_all), color = MaterialTheme.colorScheme.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,7 +327,7 @@ private fun CoordinatorKeyPackages(
|
||||
Text(
|
||||
// The rule CordnRuntime.maintainKeyPackages implements, said where
|
||||
// someone can see that it applies to them.
|
||||
text = stringRes(R.string.cordn_keypackages_topup_note),
|
||||
text = stringRes(Res.string.cordn_keypackages_topup_note),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
|
||||
+10
-6
@@ -45,7 +45,6 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.cordn.CordnLinkInspection
|
||||
import com.vitorpamplona.amethyst.commons.cordn.ui.CordnExposureCard
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
@@ -60,6 +59,11 @@ import com.vitorpamplona.amethyst.commons.resources.cordn_link_no_coordinator
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_link_not_joinable
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_link_paste
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_link_relays
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_link_request
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_link_request_disclosure
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_link_request_failed
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_link_request_sent
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_link_scan
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_link_section_input
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_link_title
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
@@ -102,8 +106,8 @@ fun CordnLinkScreen(
|
||||
var requesting by remember { mutableStateOf(false) }
|
||||
val runtime = accountViewModel.account.cordnRuntime
|
||||
val scope = rememberCoroutineScope()
|
||||
val requestFailed = stringRes(R.string.cordn_link_request_failed)
|
||||
val asked = stringRes(R.string.cordn_link_request_sent)
|
||||
val requestFailed = stringRes(Res.string.cordn_link_request_failed)
|
||||
val asked = stringRes(Res.string.cordn_link_request_sent)
|
||||
var scanning by remember { mutableStateOf(false) }
|
||||
val clipboard = LocalClipboardManager.current
|
||||
|
||||
@@ -163,7 +167,7 @@ fun CordnLinkScreen(
|
||||
Text(stringResource(Res.string.cordn_link_paste))
|
||||
}
|
||||
OutlinedButton(onClick = { scanning = true }) {
|
||||
Text(stringRes(R.string.cordn_link_scan))
|
||||
Text(stringRes(Res.string.cordn_link_scan))
|
||||
}
|
||||
if (input.isNotEmpty()) {
|
||||
OutlinedButton(
|
||||
@@ -265,7 +269,7 @@ fun CordnLinkScreen(
|
||||
enabled = !requesting,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Text(stringRes(R.string.cordn_link_request))
|
||||
Text(stringRes(Res.string.cordn_link_request))
|
||||
}
|
||||
|
||||
Text(
|
||||
@@ -274,7 +278,7 @@ fun CordnLinkScreen(
|
||||
// KeyPackage under this account's own key and tells
|
||||
// the coordinator this account wants into this
|
||||
// group, whether or not anyone ever answers (§8.4).
|
||||
text = stringRes(R.string.cordn_link_request_disclosure),
|
||||
text = stringRes(Res.string.cordn_link_request_disclosure),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
|
||||
+4
-3
@@ -47,9 +47,10 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.cordn.CordnMigration
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_group_unavailable_detail
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_migrate_cancel
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_migrate_cancel_desc
|
||||
import com.vitorpamplona.amethyst.commons.resources.cordn_migrate_code_note
|
||||
@@ -119,8 +120,8 @@ fun CordnMigrateScreen(
|
||||
) { padding ->
|
||||
if (runtime == null) {
|
||||
EmptyState(
|
||||
title = stringRes(R.string.cordn_group_unavailable),
|
||||
description = stringRes(R.string.cordn_group_unavailable_detail),
|
||||
title = stringRes(Res.string.cordn_group_unavailable),
|
||||
description = stringRes(Res.string.cordn_group_unavailable_detail),
|
||||
modifier = Modifier.padding(padding),
|
||||
)
|
||||
return@Scaffold
|
||||
|
||||
@@ -353,322 +353,4 @@
|
||||
<string name="mute_button">ध्वनि सक्रिय। मौन करने के लिए टाँकें</string>
|
||||
<string name="play">चलाएँ</string>
|
||||
<string name="pause">विराम</string>
|
||||
<string name="backup_conflict_title">आपने अपना %1$s अन्य क्रमक में परिवर्तित किया</string>
|
||||
<string name="backup_conflict_removed">हटाए गए (%1$s)</string>
|
||||
<string name="backup_conflict_added">जोडे गए (%1$s)</string>
|
||||
<string name="backup_conflict_changed">परिवर्तित (%1$s)</string>
|
||||
<string name="backup_conflict_private_cleared">आपने सभी निजी (रहस्यीकृत) वस्तुओं को हटा दिया।</string>
|
||||
<string name="backup_conflict_private_changed">आपने निजी (रहस्यीकृत) वस्तुओं का परिवर्तन भी किया। उनकी तुलना यहाँ नहीं की जा सकती।</string>
|
||||
<string name="backup_conflict_private_added">आपने निजी (रहस्यीकृत) वस्तुओं को जोडा।</string>
|
||||
<string name="backup_conflict_restore_mine">सुरक्षित संस्करण पुनःस्थापन</string>
|
||||
<string name="backup_review_saved">इस यन्त्र पर</string>
|
||||
<string name="backup_review_new">नया संस्करण</string>
|
||||
<string name="backup_review_not_set">स्थापित नहीं</string>
|
||||
<string name="backup_conflict_count_removed">%1$s हटाए गए</string>
|
||||
<string name="backup_conflict_count_added">%1$s जोडे गए</string>
|
||||
<string name="backup_conflict_count_changed">%1$s परिवर्तित</string>
|
||||
<plurals name="backup_card_follows_dropped">
|
||||
<item quantity="one">आपने %1$d व्यक्ति का अनुगमन हटाया</item>
|
||||
<item quantity="other">आपने %1$d व्यक्तियों का अनुगमन हटाए</item>
|
||||
</plurals>
|
||||
<string name="backup_card_accept">स्वीकार</string>
|
||||
<string name="backup_review_title_updated">%1$s अद्यतनकृत</string>
|
||||
<string name="backup_review_title_cleared">%1$s पारित</string>
|
||||
<string name="backup_review_changed_by_other_app">अन्य क्रमक में परिवर्तित। %1$s</string>
|
||||
<string name="backup_action_keep_count">रखें %1$s</string>
|
||||
<string name="backup_action_restore_count">पुनःस्थापन %1$s</string>
|
||||
<string name="backup_action_remute">पुनःमौन %1$s</string>
|
||||
<string name="backup_action_rejoin">पुनःजुडें %1$s</string>
|
||||
<string name="backup_action_restore_profile">परिचय पुनःस्थापध</string>
|
||||
<string name="backup_action_restore_relays">पुनःप्रसारक पुनःस्थापन</string>
|
||||
<string name="backup_review_kept_count">%1$s रखे गए</string>
|
||||
<string name="backup_review_dropped_count">%1$s परित्यक्त</string>
|
||||
<string name="backup_review_new_count">%1$s नए</string>
|
||||
<string name="backup_review_tab_dropped">परित्यक्त। %1$s</string>
|
||||
<string name="backup_review_tab_new">नए। %1$s</string>
|
||||
<string name="backup_review_tab_edited">सम्पादित। %1$s</string>
|
||||
<string name="backup_review_search_people">%1$s लोग खोजें</string>
|
||||
<string name="backup_review_nothing_here">यहाँ कुछ नहीं</string>
|
||||
<string name="backup_review_unmuted">%1$s मौनावस्था हटाए गए</string>
|
||||
<string name="backup_review_unmuted_explainer">ये पुनः आपके सूचनावलियों तक अभिगम्य</string>
|
||||
<string name="backup_review_newly_muted">%1$s नए मौनकृत</string>
|
||||
<string name="backup_review_words_and_hashtags">शब्द तथा विषयसूचक</string>
|
||||
<string name="backup_review_names_and_more">%1$s तथा %2$s अधिक</string>
|
||||
<string name="backup_review_private_wiped_title">आपने सभी निजी वस्तुओं को हटा दिया</string>
|
||||
<string name="backup_review_private_wiped_body">वे रहस्यीकृत हैं। इसलिए केवल आप देख सकते हैं कि वे क्या थे। पुनःस्थापन से सब लौटके आ जाएँगे।</string>
|
||||
<string name="backup_review_private_added_title">आपने वस्तुओं को निजी किया</string>
|
||||
<string name="backup_review_private_added_body">वे अब रहस्यीकृत हैं। जो कि सम्भाव्यतः ऊपर के सार्वजनिक वस्तुओं का गन्तव्य था।</string>
|
||||
<string name="backup_review_private_changed_title">आपने निजी वस्तुओं का परिवर्तन किया</string>
|
||||
<string name="backup_review_private_changed_body">वे रहस्यीकृत हैं। इसलिए उनकी तुलना यहाँ नहीं की जा सकती।</string>
|
||||
<string name="backup_review_gone">चला गया</string>
|
||||
<string name="backup_review_new_tag">नव्य</string>
|
||||
<string name="backup_review_dropped_tag">परित्यक्त</string>
|
||||
<string name="backup_review_demoted_tag">स्थानान्तरित</string>
|
||||
<string name="backup_review_units_tag">इकाई</string>
|
||||
<string name="backup_review_left_tag">शेष</string>
|
||||
<string name="backup_review_renamed_tag">पुनःनामकृत</string>
|
||||
<string name="backup_review_outbox">निर्गतपेटिका</string>
|
||||
<string name="backup_review_outbox_explainer">आप जहाँ प्रकाशित करते हैं</string>
|
||||
<string name="backup_review_inbox">आगतपेटिका</string>
|
||||
<string name="backup_review_inbox_explainer">जहाँ अन्य आप तक अभिगमन करते हैं</string>
|
||||
<string name="backup_review_key_replaced">ग्राहक कुंचिका प्रतिस्थापित</string>
|
||||
<string name="backup_review_key_removed">ग्राहक कुंचिका हटाया गया</string>
|
||||
<string name="backup_review_key_warning">नटज्साप आगे से इस कुंचिका से बद्ध होंगे। यदि इस यन्त्र में वह नहीं है तो आप सम्भाव्यतः उनको यहाँ नहीं चुका सकते।</string>
|
||||
<string name="backup_review_left">शेष</string>
|
||||
<string name="backup_review_joined">जुड गए</string>
|
||||
<string name="backup_review_renamed">पुनःनामकृत</string>
|
||||
<string name="backup_review_was_named">पूर्वतः %1$s था</string>
|
||||
<string name="backup_action_block_again">पुनःबाधित करें %1$s को</string>
|
||||
<string name="backup_action_restore_feeds">सूचनावलियाँ पुनःस्थापन</string>
|
||||
<string name="backup_action_restore_topics">विषय पुनःस्थापन</string>
|
||||
<string name="backup_action_restore_places">स्थल पुनःस्थापन</string>
|
||||
<string name="backup_action_restore_providers">प्रदाता पुनःस्थापन</string>
|
||||
<string name="backup_action_restore_wallet">धनकोष पुनःस्थापन</string>
|
||||
<string name="backup_review_kept">रखे गए</string>
|
||||
<string name="backup_review_receiving_tag">ग्रहण मध्य</string>
|
||||
<string name="backup_review_listed_tag">सूचीबद्ध</string>
|
||||
<string name="backup_review_searching_tag">खोज मध्य</string>
|
||||
<string name="backup_review_storing_tag">अभिलेखन मध्य</string>
|
||||
<string name="backup_review_trusted_tag">विश्वसनीय</string>
|
||||
<string name="backup_review_untrusted_tag">अविश्वसनीय</string>
|
||||
<string name="backup_review_unblocked">%1$s अबाधित</string>
|
||||
<string name="backup_review_unblocked_explainer">अमेथिस्ट पुनः उनसे जुडेगा</string>
|
||||
<string name="backup_review_no_longer_blocked">अब से बाधित नहीं</string>
|
||||
<string name="backup_review_newly_blocked">नव्यतः बाधित</string>
|
||||
<string name="backup_review_still_blocked">अभी भी बाधित</string>
|
||||
<string name="backup_review_allowed_tag">अनुमत</string>
|
||||
<string name="backup_review_moved_tag">स्थानान्तरित</string>
|
||||
<string name="backup_review_feed">सूचनावली</string>
|
||||
<string name="backup_review_topics_gone">विषय हटाए गए</string>
|
||||
<string name="backup_review_places_gone">स्थल हटाए गए</string>
|
||||
<string name="backup_review_new_count_caption">नव्य</string>
|
||||
<string name="backup_review_hashtags_you_follow">विषयसूचक जिनका आप अनुगमन करते हैं</string>
|
||||
<string name="backup_review_places_you_follow">स्थल जिनका आप अनुगमन करते हैं</string>
|
||||
<string name="backup_review_services_changed">%2$s में से %1$s सेवाएँ परिवर्तित</string>
|
||||
<string name="backup_review_services_changed_explainer">वे अब अन्य व्यक्ति से आते है। अथवा किसी से नहीं</string>
|
||||
<string name="backup_review_service">सेवा</string>
|
||||
<string name="backup_review_service_rank">श्रेणी</string>
|
||||
<string name="backup_review_service_followers">अनुचर</string>
|
||||
<string name="backup_review_service_topics">विषयसूची</string>
|
||||
<string name="backup_review_trust_warning">श्रेणीयाँ तथा अनुचर गिनती तथा कचरालेख छालन जो आप देखते हैं इन प्रदाताओं से आते हैं।</string>
|
||||
<plurals name="backup_review_payment_targets_gone">
|
||||
<item quantity="one">आपको भुगतान करने की %1$d विधि हटाया गया</item>
|
||||
<item quantity="other">आपको भुगतान करने की %1$d विधियाँ हटाए गए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_review_offers_gone">
|
||||
<item quantity="one">%1$d प्रस्ताव हटाया गया</item>
|
||||
<item quantity="other">%1$d प्रस्ताव हटाए गए</item>
|
||||
</plurals>
|
||||
<string name="backup_review_payments_explainer">लोग जो आपको भुगतान करते हैं उसी को देखते हैं जो इस सूची में है।</string>
|
||||
<string name="backup_review_offer">बोल्ट॰बारह प्रस्ताव</string>
|
||||
<string name="backup_review_encrypted_cleared">आपने उसे रिक्त किया</string>
|
||||
<string name="backup_review_encrypted_added">आपने उसे बनाया</string>
|
||||
<string name="backup_review_encrypted_changed">आपने उसे परिवर्तित किया</string>
|
||||
<string name="backup_review_wallet_body">आपके धनकोष के टकसाल तथा कुंचिकाएँ आपके लिए रहस्यीकृत हैं। इसलिए उनकी तुलना वस्तु प्रति वस्तु यहाँ नहीं की जा सकती। पुनःस्थापन उन्हीं को लौट डालेगा जिनका अभिलेखन इस यन्त्र ने किया।</string>
|
||||
<string name="backup_review_concord_body">आपके कोंकोर्ड समुदाय आपके लिए रहस्यीकृत हैं। इसलिए उनकी तुलना यहाँ नहीं की जा सकती। पुनःस्थापन उन्हीं को लौट डालेगा जिनका अभिलेखन इस यन्त्र ने किया।</string>
|
||||
<plurals name="backup_card_mutes_visible">
|
||||
<item quantity="one">आपने %1$d की मौनावस्था हटाया</item>
|
||||
<item quantity="other">आपने %1$d की मौनावस्था हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_profile_lost_fields">
|
||||
<item quantity="one">आपने %1$d परिचय प्रपत्रस्थान हटाया</item>
|
||||
<item quantity="other">आपने %1$d परिचय प्रपत्रस्थान हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_nip65_lost">
|
||||
<item quantity="one">आपने %1$d सार्वजनिक पुनःप्रसारक हटाया</item>
|
||||
<item quantity="other">आपने %1$d सार्वजनिक पुनःप्रसारकों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_dm_relays_lost">
|
||||
<item quantity="one">आपने %1$d सीधासन्देश पुनःप्रसारक हटाया</item>
|
||||
<item quantity="other">आपने %1$d सीधासन्देश पुनःप्रसारकों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_key_package_relays_lost">
|
||||
<item quantity="one">आपने %1$d समूहचर्चा कुंचिका पुनःप्रसारक हटाया</item>
|
||||
<item quantity="other">आपने %1$d समूहचर्चा कुंचिका पुनःप्रसारकों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_search_relays_lost">
|
||||
<item quantity="one">आपने %1$d खोज पुनःप्रसारक हटाया</item>
|
||||
<item quantity="other">आपने %1$d खोज पुनःप्रसारकों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_indexer_relays_lost">
|
||||
<item quantity="one">आपने %1$d अनुक्रमणीकार पुनःप्रसारक हटाया</item>
|
||||
<item quantity="other">आपने %1$d अनुक्रमणीकार पुनःप्रसारकों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_relay_feeds_lost">
|
||||
<item quantity="one">आपने %1$d पुनःप्रसारक सूचनावली हटाया</item>
|
||||
<item quantity="other">आपने %1$d पुनःप्रसारक सूचनावलियाँ हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_private_outbox_lost">
|
||||
<item quantity="one">आपने %1$d निजी पुनःप्रसारक हटाया</item>
|
||||
<item quantity="other">आपने %1$d निजी पुनःप्रसारकों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trusted_lost">
|
||||
<item quantity="one">आपने %1$d पुनःप्रसारक पर विश्वास करना रोक दिया</item>
|
||||
<item quantity="other">आपने %1$d पुनःप्रसारकों पर विश्वास करना रोक दिए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_unblocked">
|
||||
<item quantity="one">आपने %1$d पुनःप्रसारक अबाधित किया</item>
|
||||
<item quantity="other">आपने %1$d पुनःप्रसारकों को अबाधित किए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_chats">
|
||||
<item quantity="one">आपने %1$d सार्वजनिक चर्चा छोड दिया</item>
|
||||
<item quantity="other">आपने %1$d सार्वजनिक चर्चाओं को छोड दिए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_communities">
|
||||
<item quantity="one">आपने %1$d समुदाय छोड दिया</item>
|
||||
<item quantity="other">आपने %1$d समुदायों को छोड दिए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_rooms">
|
||||
<item quantity="one">आपने %1$d चर्चाशाला छोड दिया</item>
|
||||
<item quantity="other">आपने %1$d चर्चाशालाओं को छोड दिए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_groups">
|
||||
<item quantity="one">आपने %1$d समूह छोड दिया</item>
|
||||
<item quantity="other">आपने %1$d समूहों को छोड दिए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_feeds_removed">
|
||||
<item quantity="one">आपने %1$d इष्ट सूचनावली हटाया</item>
|
||||
<item quantity="other">आपने %1$d इष्ट सूचनावलियों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_hashtags_unfollowed">
|
||||
<item quantity="one">आपने %1$d विषयसूचक का अनुगमन हटाया</item>
|
||||
<item quantity="other">आपने %1$d विषयसूचकों का अनुगमन हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_places_unfollowed">
|
||||
<item quantity="one">आपने %1$d स्थल का अनुगमन हटाया</item>
|
||||
<item quantity="other">आपने %1$d स्थलों का अनुगमन हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trust_services_changed">
|
||||
<item quantity="one">आपने %1$d विश्वाससेवा प्रदाता परिवर्तित किया</item>
|
||||
<item quantity="other">आपने %1$d विश्वाससेवाओं के प्रदाता को परिवर्तित किया</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_nutzap_mints_removed">
|
||||
<item quantity="one">आपने %1$d नटज्साप टकसाल हटाया</item>
|
||||
<item quantity="other">आपने %1$d नटज्साप टकसालों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_payment_targets_removed">
|
||||
<item quantity="one">आपने %1$d भुगतान प्राप्त करने की विधि हटाया</item>
|
||||
<item quantity="other">आपने %1$d भुगतान प्राप्त करने के विधियों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_offers_removed">
|
||||
<item quantity="one">आपने %1$d बोल्ट॰बारह प्रस्ताव हटाया</item>
|
||||
<item quantity="other">आपने %1$d बोल्ट॰बारह प्रस्तावों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_added">
|
||||
<item quantity="one">%1$s तथा %2$d जोडा</item>
|
||||
<item quantity="other">%1$s तथा %2$d जोडे</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_followed">
|
||||
<item quantity="one">%1$s तथा %2$d का अनुगमन किया</item>
|
||||
<item quantity="other">%1$s तथा %2$d का अनुगमन किए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_muted">
|
||||
<item quantity="one">%1$s तथा %2$d को मौनकृत किया</item>
|
||||
<item quantity="other">%1$s तथा %2$d को मौनकृत किए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_joined">
|
||||
<item quantity="one">%1$s तथा %2$d से जुडे</item>
|
||||
<item quantity="other">%1$s तथा %2$d से जुडे</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_blocked">
|
||||
<item quantity="one">%1$s तथा %2$d बाधित किया</item>
|
||||
<item quantity="other">%1$s तथा %2$d को बाधित किए</item>
|
||||
</plurals>
|
||||
<string name="backup_card_app_settings">आपके अमेथिस्ट समचरणीकृत क्रमक स्थापना विकल्पों को परिवर्तित किया गया एक अन्य क्रमक में और वह अमेथिस्ट नहीं था। इससे समस्याएँ उत्पन्न हो सकते हैं।</string>
|
||||
<string name="backup_card_nutzap_key_replaced">आपने अपनी नटज्साप कुंचिका का प्रतिस्थापन किया</string>
|
||||
<string name="backup_card_nutzap_key_removed">आपने अपनी नटज्साप कुंचिका को हटाया</string>
|
||||
<string name="backup_card_wallet_emptied">आपने अपना काशयू धनकोष रिक्त किया</string>
|
||||
<string name="backup_card_wallet_rewritten">आपने अपने काशयू धनकोष को परिवर्तित किया</string>
|
||||
<string name="backup_card_concord_emptied">आपने अपनी कोंकोर्ड सूची रिक्त की</string>
|
||||
<string name="backup_card_concord_rewritten">आपने अपनी कोंकोर्ड सूची का परिवर्तन किया</string>
|
||||
<string name="backup_conflict_keep_new">नया संस्करण का उपयोग करें</string>
|
||||
<string name="backup_conflict_relay_read_only">पठनेवशक्य</string>
|
||||
<string name="backup_conflict_relay_write_only">लेखनेवशक्य</string>
|
||||
<string name="backup_conflict_relay_read_write">पठन तथा लेखन</string>
|
||||
<string name="backup_type_profile">परिचय</string>
|
||||
<string name="backup_type_profile_explainer">आपका नाम चित्र चरित तथा भुगतान पते। जैसे सब को दिखते हैं वैसे।</string>
|
||||
<string name="backup_type_follow_list">अनुचरण सूची</string>
|
||||
<string name="backup_type_follow_list_explainer">निर्णय करता है किसके पत्र आपकी मुख्य सूचनावली में प्रकट होंगे।</string>
|
||||
<string name="backup_type_mute_list">मौन सूची</string>
|
||||
<string name="backup_type_mute_list_explainer">छिपाता है लोग शब्द विषयसूचक तथा सूत्र उन सब में से जो आप देखते हैं।</string>
|
||||
<string name="backup_type_outbox_inbox_relays">सार्वजनिक पुनःप्रसारक सूची</string>
|
||||
<string name="backup_type_outbox_inbox_relays_explainer">सबको बताता है आपके पत्र कहाँ प्राप्त करें तथा आपको उत्तर तथा उल्लेखों को कहाँ भेजें।</string>
|
||||
<string name="backup_type_dm_relays">सीधासन्देश पुनःप्रसारक सूची</string>
|
||||
<string name="backup_type_dm_relays_explainer">जहाँ अन्य आपके निजी सन्देश भेजते हैं।</string>
|
||||
<string name="backup_type_key_package_relays">समूहचर्चा कुंचिका पुनःप्रसारक</string>
|
||||
<string name="backup_type_key_package_relays_explainer">जहाँ अन्य उन कुंचिकाओं को प्राप्त करते हैं आपको रहस्यीकृत समूहचर्चाओं में जोडने के लिए।</string>
|
||||
<string name="backup_type_search_relays">खोज पुनःप्रसारक सूची</string>
|
||||
<string name="backup_type_search_relays_explainer">उपयुक्त पुनःप्रसारक जब आप खोजते हैं।</string>
|
||||
<string name="backup_type_indexer_relays">अनुक्रमणीकार पुनःप्रसारक सूची</string>
|
||||
<string name="backup_type_indexer_relays_explainer">पुनःप्रसारक उपयुक्त अन्य लोगों के परिचय तथा पुनःप्रसारक सूचियों को प्राप्त करने के लिए।</string>
|
||||
<string name="backup_type_relay_feeds">इष्ट पुनःप्रसारक सूचनावलियाँ</string>
|
||||
<string name="backup_type_relay_feeds_explainer">पुनःप्रसारक जिनका आप वीक्षण करते हैं सूचनावलियों के रूप में।</string>
|
||||
<string name="backup_type_blocked_relays">बाधित पुनःप्रसारक सूची</string>
|
||||
<string name="backup_type_blocked_relays_explainer">पुनःप्रसारक जिनसे यह क्रमक कभी भी संयोजन नहीं करता।</string>
|
||||
<string name="backup_type_trusted_relays">विश्वसनीय पुनःप्रसारक सूची</string>
|
||||
<string name="backup_type_trusted_relays_explainer">पुनःप्रसारक जिनपर आप पर्याप्त विश्वास करते हैं बिना पूछे उनसे संयोजन करने के लिए।</string>
|
||||
<string name="backup_type_private_outbox_relays">निजी पुनःप्रसारक सूची</string>
|
||||
<string name="backup_type_private_outbox_relays_explainer">जहाँ आपके पाण्डुलिपियाँ तथा निजी जानकारी रखे जाते हैं।</string>
|
||||
<string name="backup_type_app_settings">समचरणीकृत क्रमक स्थापना विकल्प</string>
|
||||
<string name="backup_type_app_settings_explainer">अमेथिस्ट स्थापना विकल्प समचरणीकृत आपके यन्त्रों में। वे रहस्यीकृत हैं। इसलिए केवल उनकी उपस्थिति की तुलना की जा सकती है।</string>
|
||||
<string name="backup_type_public_chats">सार्वजनिक चर्चा सूची</string>
|
||||
<string name="backup_type_public_chats_explainer">सार्वजनिक चर्चाएँ जिनसे आप जुडे।</string>
|
||||
<string name="backup_type_communities">समुदाय सूची</string>
|
||||
<string name="backup_type_communities_explainer">समुदाय जिनसे आप जुडे।</string>
|
||||
<string name="backup_type_hashtags">अनुचरित विषयसूचक</string>
|
||||
<string name="backup_type_hashtags_explainer">विषयसूचक जिससे युक्त पत्र आपकी मुख्य सूचनावली में प्रकट होंगे।</string>
|
||||
<string name="backup_type_geohashes">अनुचरित स्थान</string>
|
||||
<string name="backup_type_geohashes_explainer">स्थान जहाँ से पत्र आपकी मुख्य सूचनावली में प्रकट होंगे।</string>
|
||||
<string name="backup_type_favorite_algo_feeds">इष्ट सूचनावली सूची</string>
|
||||
<string name="backup_type_favorite_algo_feeds_explainer">कलनविध्यात्मक सूचनावलियाँ जिनको आपने अभिलेखित किया।</string>
|
||||
<string name="backup_type_ephemeral_chats">अस्थायी चर्चा सूची</string>
|
||||
<string name="backup_type_ephemeral_chats_explainer">अस्थायी चर्चा शालाएँ जिनसे आप जुडे।</string>
|
||||
<string name="backup_type_relay_groups">समूह सूची</string>
|
||||
<string name="backup_type_relay_groups_explainer">पुनःप्रसारक आधारित समूह जिनसे आप जुडे।</string>
|
||||
<string name="backup_type_concord_communities">कोंकोर्ड समुदाय सूची</string>
|
||||
<string name="backup_type_concord_communities_explainer">कोंकोर्ड समुदाय जिनसे आप जुडे। वे रहस्यीकृत हैं। इसलिए केवल उनकी उपस्थिति की तुलना की जा सकती है।</string>
|
||||
<string name="backup_type_trust_providers">विश्वाससेवा प्रदाता सूची</string>
|
||||
<string name="backup_type_trust_providers_explainer">सेवाएँ जिनपर आप विश्वास करते है आपके लिए लोगों का सत्यापन तथा श्रेणीकरण करने के लिए।</string>
|
||||
<string name="backup_type_cashu_wallet">काशयू धनकोष</string>
|
||||
<string name="backup_type_cashu_wallet_explainer">आपके ईकाश धनकोष स्थापना विकल्प तथा टकसाल। वे रहस्यीकृत हैं। इसलिए केवल उनकी उपस्थिति की तुलना की जा सकती है।</string>
|
||||
<string name="backup_type_nutzap_info">नटज्साप प्राप्ती स्थापना विकल्प</string>
|
||||
<string name="backup_type_nutzap_info_explainer">टकसाल तथा कुंचिका जिनका उपयोग अन्य करते हैं आपको नटज्साप भेजने के लिए।</string>
|
||||
<string name="backup_type_payment_targets">भुगतान पते</string>
|
||||
<string name="backup_type_payment_targets_explainer">विधियाँ जिनसे अन्य लोग आपको भुगतान कर सके।</string>
|
||||
<string name="backup_type_bolt12_offers">बोल्ट॰बारह प्रस्ताव</string>
|
||||
<string name="backup_type_bolt12_offers_explainer">लैटनिंग प्रस्ताव जिनका उपयोग करके अन्य लोग आपको भुगतान करते हैं।</string>
|
||||
<string name="backup_type_other">सूची</string>
|
||||
<string name="backup_type_other_explainer">इस यन्त्र पर अभिलेखित सूची।</string>
|
||||
<string name="backup_entry_profile_field">परिचय प्रपत्रस्थान</string>
|
||||
<string name="backup_entry_person">लोग</string>
|
||||
<string name="backup_entry_hashtag">विषयसूचक</string>
|
||||
<string name="backup_entry_word">शब्द</string>
|
||||
<string name="backup_entry_thread">सूत्र</string>
|
||||
<string name="backup_entry_public_chat">सार्वजनिक चर्चाएँ</string>
|
||||
<string name="backup_entry_community">समुदाय</string>
|
||||
<string name="backup_entry_algo_feed">सूचनावलियाँ</string>
|
||||
<string name="backup_entry_location">स्थान</string>
|
||||
<string name="backup_entry_relay">पुनःप्रसारक</string>
|
||||
<string name="backup_entry_relay_group">समूह</string>
|
||||
<string name="backup_entry_chat_room">चर्चा शालाएँ</string>
|
||||
<string name="backup_entry_trust_provider">विश्वाससेवा प्रदाता</string>
|
||||
<string name="backup_entry_mint">टकसाल</string>
|
||||
<string name="backup_entry_nutzap_key">नटज्साप कुंचिकाएँ</string>
|
||||
<string name="backup_entry_payment_target">भुगतान पते</string>
|
||||
<string name="backup_entry_offer">प्रस्ताव</string>
|
||||
<string name="backup_entry_identity_claim">सम्बन्धित व्यक्तिगण</string>
|
||||
<string name="backup_entry_other">अन्य प्रविष्टियाँ</string>
|
||||
<string name="backup_profile_field_name">प्रयोक्तानाम</string>
|
||||
<string name="backup_profile_field_display_name">प्रदर्शन नाम</string>
|
||||
<string name="backup_profile_field_about">जानकारी</string>
|
||||
<string name="backup_profile_field_picture">चित्र</string>
|
||||
<string name="backup_profile_field_banner">ध्वज</string>
|
||||
<string name="backup_profile_field_website">जालस्थान</string>
|
||||
<string name="backup_profile_field_nip05">नोस्टर पता</string>
|
||||
<string name="backup_profile_field_lud16">लैटनिंग पता</string>
|
||||
<string name="backup_profile_field_lud06">लैटनिंग जालपता</string>
|
||||
<string name="backup_profile_field_pronouns">सर्वनाम</string>
|
||||
<string name="backup_profile_field_birthday">जन्मदिन</string>
|
||||
<string name="backup_profile_field_clink_offer">क्लिंक॰ प्रस्ताव</string>
|
||||
<string name="backup_profile_field_bot">क्रमचर चिह्न</string>
|
||||
</resources>
|
||||
|
||||
@@ -353,322 +353,4 @@
|
||||
<string name="mute_button">Hang bekapcsolva. Koppintson a némításhoz</string>
|
||||
<string name="play">Lejátszás</string>
|
||||
<string name="pause">Szüneteltetés</string>
|
||||
<string name="backup_conflict_title">Ön módosította a következőt: %1$s, egy másik alkalmazásban</string>
|
||||
<string name="backup_conflict_removed">Eltávolítva (%1$s)</string>
|
||||
<string name="backup_conflict_added">Hozzáadva (%1$s)</string>
|
||||
<string name="backup_conflict_changed">Módosítva (%1$s)</string>
|
||||
<string name="backup_conflict_private_cleared">Ön eltávolította az összes privát (titkosított) elemet.</string>
|
||||
<string name="backup_conflict_private_changed">Ön privát (titkosított) elemeket is módosított. Ezek itt nem hasonlíthatók össze.</string>
|
||||
<string name="backup_conflict_private_added">Ön privát (titkosított) elemeket adott hozzá.</string>
|
||||
<string name="backup_conflict_restore_mine">Mentett verzió visszaállítása</string>
|
||||
<string name="backup_review_saved">Ezen az eszközön</string>
|
||||
<string name="backup_review_new">Új verzió</string>
|
||||
<string name="backup_review_not_set">Nincs beállítva</string>
|
||||
<string name="backup_conflict_count_removed">%1$s eltávolítva</string>
|
||||
<string name="backup_conflict_count_added">%1$s hozzáadva</string>
|
||||
<string name="backup_conflict_count_changed">%1$s módosítva</string>
|
||||
<plurals name="backup_card_follows_dropped">
|
||||
<item quantity="one">%1$d személyt nem követ többé</item>
|
||||
<item quantity="other">%1$d személyt nem követ többé</item>
|
||||
</plurals>
|
||||
<string name="backup_card_accept">Elfogadás</string>
|
||||
<string name="backup_review_title_updated">%1$s frissítve</string>
|
||||
<string name="backup_review_title_cleared">%1$s törölve</string>
|
||||
<string name="backup_review_changed_by_other_app">Módosítva egy másik alkalmazásban · %1$s</string>
|
||||
<string name="backup_action_keep_count">%1$s megtartása</string>
|
||||
<string name="backup_action_restore_count">%1$s visszaállítása</string>
|
||||
<string name="backup_action_remute">%1$s újbóli némítása</string>
|
||||
<string name="backup_action_rejoin">Újbóli csatlakozás ehhez: %1$s</string>
|
||||
<string name="backup_action_restore_profile">Profil visszaállítása</string>
|
||||
<string name="backup_action_restore_relays">Átjátszók visszaállítása</string>
|
||||
<string name="backup_review_kept_count">%1$s megtartva</string>
|
||||
<string name="backup_review_dropped_count">%1$s elvetve</string>
|
||||
<string name="backup_review_new_count">%1$s új</string>
|
||||
<string name="backup_review_tab_dropped">Elvetve · %1$s</string>
|
||||
<string name="backup_review_tab_new">Új · %1$s</string>
|
||||
<string name="backup_review_tab_edited">Szerkesztve · %1$s</string>
|
||||
<string name="backup_review_search_people">%1$s személy keresése</string>
|
||||
<string name="backup_review_nothing_here">Itt nincs semmi</string>
|
||||
<string name="backup_review_unmuted">%1$s némítása feloldva</string>
|
||||
<string name="backup_review_unmuted_explainer">Ezek újra megjelenhetnek a hírfolyamaiban</string>
|
||||
<string name="backup_review_newly_muted">%1$s újonnan némítva</string>
|
||||
<string name="backup_review_words_and_hashtags">Szavak és kulcsszavak</string>
|
||||
<string name="backup_review_names_and_more">%1$s és %2$s további</string>
|
||||
<string name="backup_review_private_wiped_title">Ön eltávolította az összes privát elemet</string>
|
||||
<string name="backup_review_private_wiped_body">Titkosítva vannak, így csak Ön láthatja, mik voltak. A visszaállítás mindet visszahozza.</string>
|
||||
<string name="backup_review_private_added_title">Ön priváttá tette az elemeket</string>
|
||||
<string name="backup_review_private_added_body">Most már titkosítva vannak, valószínűleg ide kerültek a fenti nyilvános elemek.</string>
|
||||
<string name="backup_review_private_changed_title">Ön módosította a privát elemeket</string>
|
||||
<string name="backup_review_private_changed_body">Titkosítva vannak, így itt nem hasonlíthatók össze.</string>
|
||||
<string name="backup_review_gone">Eltűnt</string>
|
||||
<string name="backup_review_new_tag">Új</string>
|
||||
<string name="backup_review_dropped_tag">Elvetve</string>
|
||||
<string name="backup_review_demoted_tag">Áthelyezve</string>
|
||||
<string name="backup_review_units_tag">Egységek</string>
|
||||
<string name="backup_review_left_tag">Elhagyva</string>
|
||||
<string name="backup_review_renamed_tag">Átnevezve</string>
|
||||
<string name="backup_review_outbox">Kimenő</string>
|
||||
<string name="backup_review_outbox_explainer">ahol közzétesz</string>
|
||||
<string name="backup_review_inbox">Bejövő</string>
|
||||
<string name="backup_review_inbox_explainer">ahol mások elérik Önt</string>
|
||||
<string name="backup_review_key_replaced">Fogadási kulcs lecserélve</string>
|
||||
<string name="backup_review_key_removed">Fogadási kulcs eltávolítva</string>
|
||||
<string name="backup_review_key_warning">A nutzapok ehhez az új kulcshoz lesznek kötve. Ha ez az eszköz nem rendelkezik vele, lehet, hogy itt nem tudja beváltani őket.</string>
|
||||
<string name="backup_review_left">elhagyta a csoportot</string>
|
||||
<string name="backup_review_joined">csatlakozott</string>
|
||||
<string name="backup_review_renamed">átnevezte</string>
|
||||
<string name="backup_review_was_named">„%1$s” volt</string>
|
||||
<string name="backup_action_block_again">%1$s újbóli letiltása</string>
|
||||
<string name="backup_action_restore_feeds">Hírfolyamok visszaállítása</string>
|
||||
<string name="backup_action_restore_topics">Témák visszaállítása</string>
|
||||
<string name="backup_action_restore_places">Helyek visszaállítása</string>
|
||||
<string name="backup_action_restore_providers">Szolgáltatók visszaállítása</string>
|
||||
<string name="backup_action_restore_wallet">Pénztárca visszaállítása</string>
|
||||
<string name="backup_review_kept">megtartva</string>
|
||||
<string name="backup_review_receiving_tag">Fogadás</string>
|
||||
<string name="backup_review_listed_tag">Listázva</string>
|
||||
<string name="backup_review_searching_tag">Keresés</string>
|
||||
<string name="backup_review_storing_tag">Tárolás</string>
|
||||
<string name="backup_review_trusted_tag">Megbízható</string>
|
||||
<string name="backup_review_untrusted_tag">Nem megbízható</string>
|
||||
<string name="backup_review_unblocked">%1$s letiltása feloldva</string>
|
||||
<string name="backup_review_unblocked_explainer">Az Amethyst újra kapcsolódni fog hozzájuk</string>
|
||||
<string name="backup_review_no_longer_blocked">Már nincs letiltva</string>
|
||||
<string name="backup_review_newly_blocked">Újonnan letiltva</string>
|
||||
<string name="backup_review_still_blocked">Továbbra is le van tiltva</string>
|
||||
<string name="backup_review_allowed_tag">Engedélyezve</string>
|
||||
<string name="backup_review_moved_tag">Áthelyezve</string>
|
||||
<string name="backup_review_feed">Hírfolyam</string>
|
||||
<string name="backup_review_topics_gone">eltűnt témák</string>
|
||||
<string name="backup_review_places_gone">eltűnt helyek</string>
|
||||
<string name="backup_review_new_count_caption">új</string>
|
||||
<string name="backup_review_hashtags_you_follow">Ön által követett kulcsszavak</string>
|
||||
<string name="backup_review_places_you_follow">Ön által követett helyek</string>
|
||||
<string name="backup_review_services_changed">%2$s szolgáltatásból %1$s módosult</string>
|
||||
<string name="backup_review_services_changed_explainer">Most már valaki mástól vagy senkitől sem származnak</string>
|
||||
<string name="backup_review_service">Szolgáltatás</string>
|
||||
<string name="backup_review_service_rank">Rang</string>
|
||||
<string name="backup_review_service_followers">Követők</string>
|
||||
<string name="backup_review_service_topics">Témák</string>
|
||||
<string name="backup_review_trust_warning">A látott rangok, követőszámok és a kéretlen tartalomszűrés ezektől a szolgáltatóktól származnak.</string>
|
||||
<plurals name="backup_review_payment_targets_gone">
|
||||
<item quantity="one">%1$d fizetési mód eltávolítva</item>
|
||||
<item quantity="other">%1$d fizetési mód eltávolítva</item>
|
||||
</plurals>
|
||||
<plurals name="backup_review_offers_gone">
|
||||
<item quantity="one">%1$d ajánlat eltávolítva</item>
|
||||
<item quantity="other">%1$d ajánlat eltávolítva</item>
|
||||
</plurals>
|
||||
<string name="backup_review_payments_explainer">A fizető emberek csak azt látják, ami ebben a listában van.</string>
|
||||
<string name="backup_review_offer">BOLT12 ajánlat</string>
|
||||
<string name="backup_review_encrypted_cleared">Ön kiürítette</string>
|
||||
<string name="backup_review_encrypted_added">Ön hozta létre</string>
|
||||
<string name="backup_review_encrypted_changed">Ön módosította</string>
|
||||
<string name="backup_review_wallet_body">A saját pénztárca pénzverdéi és kulcsai Önhöz vannak titkosítva, így itt nem hasonlíthatók össze tételesen. A visszaállítás pontosan azt hozza vissza, amit ez az eszköz mentett.</string>
|
||||
<string name="backup_review_concord_body">A Concord közösségei Önhöz vannak titkosítva, így itt nem hasonlíthatók össze. A visszaállítás pontosan azt hozza vissza, amit ez az eszköz mentett.</string>
|
||||
<plurals name="backup_card_mutes_visible">
|
||||
<item quantity="one">Ön %1$d dolog némítását oldotta fel</item>
|
||||
<item quantity="other">%1$d dolog némítását oldotta fel</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_profile_lost_fields">
|
||||
<item quantity="one">Ön %1$d profilmezőt távolított el</item>
|
||||
<item quantity="other">%1$d profilmezőt távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_nip65_lost">
|
||||
<item quantity="one">Ön %1$d nyilvános átjátszót távolított el</item>
|
||||
<item quantity="other">%1$d nyilvános átjátszót távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_dm_relays_lost">
|
||||
<item quantity="one">Ön %1$d privát üzenetátjátszót távolított el</item>
|
||||
<item quantity="other">%1$d privát üzenet átjátszót távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_key_package_relays_lost">
|
||||
<item quantity="one">Ön %1$d csoportos csevegési kulcsátjátszót távolított el</item>
|
||||
<item quantity="other">%1$d csoportcsevegés kulcs átjátszót távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_search_relays_lost">
|
||||
<item quantity="one">Ön %1$d kereső átjátszót távolított el</item>
|
||||
<item quantity="other">%1$d kereső átjátszót távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_indexer_relays_lost">
|
||||
<item quantity="one">Ön %1$d indexelő átjátszót távolított el</item>
|
||||
<item quantity="other">%1$d indexelő átjátszót távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_relay_feeds_lost">
|
||||
<item quantity="one">Ön %1$d átjátszó-hírfolyamot távolított el</item>
|
||||
<item quantity="other">%1$d átjátszó hírfolyamot távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_private_outbox_lost">
|
||||
<item quantity="one">Ön %1$d privát átjátszót távolított el</item>
|
||||
<item quantity="other">%1$d privát átjátszót távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trusted_lost">
|
||||
<item quantity="one">Ön %1$d átjátszóban nem bízik többé</item>
|
||||
<item quantity="other">%1$d átjátszóban nem bízik többé</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_unblocked">
|
||||
<item quantity="one">Ön %1$d átjátszó letiltását oldotta fel</item>
|
||||
<item quantity="other">%1$d átjátszó blokkolását oldotta fel</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_chats">
|
||||
<item quantity="one">Ön %1$d nyilvános csevegést hagyott el</item>
|
||||
<item quantity="other">%1$d nyilvános csevegést hagyott el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_communities">
|
||||
<item quantity="one">Ön %1$d közösséget hagyott el</item>
|
||||
<item quantity="other">%1$d közösséget hagyott el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_rooms">
|
||||
<item quantity="one">Ön %1$d csevegőszobát hagyott el</item>
|
||||
<item quantity="other">%1$d csevegőszobát hagyott el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_groups">
|
||||
<item quantity="one">Ön %1$d csoportot hagyott el</item>
|
||||
<item quantity="other">%1$d csoportot hagyott el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_feeds_removed">
|
||||
<item quantity="one">Ön %1$d kedvenc hírfolyamot távolított el</item>
|
||||
<item quantity="other">%1$d kedvenc hírfolyamot távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_hashtags_unfollowed">
|
||||
<item quantity="one">Ön %1$d kulcsszót nem követ többé</item>
|
||||
<item quantity="other">%1$d hashtaget nem követ többé</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_places_unfollowed">
|
||||
<item quantity="one">Ön %1$d helyet nem követ többé</item>
|
||||
<item quantity="other">%1$d helyet nem követ többé</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trust_services_changed">
|
||||
<item quantity="one">Ön %1$d bizalmi szolgáltatás szolgáltatóját módosította</item>
|
||||
<item quantity="other">%1$d bizalmi szolgáltatás szolgáltatóját változtatta meg</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_nutzap_mints_removed">
|
||||
<item quantity="one">Ön %1$d nutzap pénzverdét távolított el</item>
|
||||
<item quantity="other">%1$d nutzap pénzverdét távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_payment_targets_removed">
|
||||
<item quantity="one">Ön %1$d fizetési módot távolított el</item>
|
||||
<item quantity="other">%1$d fizetési módot távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_offers_removed">
|
||||
<item quantity="one">Ön %1$d BOLT12 ajánlatot távolított el</item>
|
||||
<item quantity="other">%1$d BOLT12 ajánlatot távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_added">
|
||||
<item quantity="one">%1$s és %2$d hozzáadva</item>
|
||||
<item quantity="other">%1$s és %2$d hozzáadva</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_followed">
|
||||
<item quantity="one">%1$s és %2$d követve</item>
|
||||
<item quantity="other">%1$s és %2$d követve</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_muted">
|
||||
<item quantity="one">%1$s és %2$d némítva</item>
|
||||
<item quantity="other">%1$s és %2$d némítva</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_joined">
|
||||
<item quantity="one">%1$s és %2$d csatlakozva</item>
|
||||
<item quantity="other">%1$s és %2$d csatlakozva</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_blocked">
|
||||
<item quantity="one">%1$s és %2$d letiltva</item>
|
||||
<item quantity="other">%1$s és %2$d letiltva</item>
|
||||
</plurals>
|
||||
<string name="backup_card_app_settings">A szinkronizált Amethyst alkalmazásbeállításai egy másik, nem Amethyst alkalmazásban módosultak. Ez problémákat okozhat.</string>
|
||||
<string name="backup_card_nutzap_key_replaced">Ön lecserélte a nutzap kulcsát</string>
|
||||
<string name="backup_card_nutzap_key_removed">Ön eltávolította a nutzap kulcsát</string>
|
||||
<string name="backup_card_wallet_emptied">Ön kiürítette a Cashu pénztárcáját</string>
|
||||
<string name="backup_card_wallet_rewritten">Ön módosította a Cashu pénztárcáját</string>
|
||||
<string name="backup_card_concord_emptied">Ön kiürítette a Concord listáját</string>
|
||||
<string name="backup_card_concord_rewritten">Ön módosította a Concord listáját</string>
|
||||
<string name="backup_conflict_keep_new">Új verzió használata</string>
|
||||
<string name="backup_conflict_relay_read_only">csak olvasható</string>
|
||||
<string name="backup_conflict_relay_write_only">csak írható</string>
|
||||
<string name="backup_conflict_relay_read_write">olvasás és írás</string>
|
||||
<string name="backup_type_profile">profil</string>
|
||||
<string name="backup_type_profile_explainer">Az Ön neve, képe, bemutatkozása és fizetési címei, ahogy mindenki látja őket.</string>
|
||||
<string name="backup_type_follow_list">követési lista</string>
|
||||
<string name="backup_type_follow_list_explainer">Meghatározza, kinek a bejegyzései jelenjenek meg a kezdőlapon.</string>
|
||||
<string name="backup_type_mute_list">némítási lista</string>
|
||||
<string name="backup_type_mute_list_explainer">Elrejti a személyeket, szavakat, kulcsszavakat és beszélgetéseket mindenből, amit lát.</string>
|
||||
<string name="backup_type_outbox_inbox_relays">nyilvános átjátszólista</string>
|
||||
<string name="backup_type_outbox_inbox_relays_explainer">Megmondja mindenkinek, hol találhatók a bejegyzései, és hová küldjék a válaszokat és említéseket.</string>
|
||||
<string name="backup_type_dm_relays">privát üzenet átjátszólista</string>
|
||||
<string name="backup_type_dm_relays_explainer">Ahová mások kézbesítik a privát üzeneteit.</string>
|
||||
<string name="backup_type_key_package_relays">csoportos csevegési kulcsátjátszók</string>
|
||||
<string name="backup_type_key_package_relays_explainer">Ahol mások megtalálják a kulcsokat, hogy titkosított csoportos csevegésekhez adhassák Önt.</string>
|
||||
<string name="backup_type_search_relays">kereső átjátszólista</string>
|
||||
<string name="backup_type_search_relays_explainer">Kereséskor használt átjátszók.</string>
|
||||
<string name="backup_type_indexer_relays">indexelő átjátszólista</string>
|
||||
<string name="backup_type_indexer_relays_explainer">Azok az átjátszók, amelyeket mások profiljainak és átjátszólistáinak megtalálásához használnak.</string>
|
||||
<string name="backup_type_relay_feeds">kedvenc átjátszóhírfolyamok</string>
|
||||
<string name="backup_type_relay_feeds_explainer">Olyan átjátszók, amelyeket hírfolyamként böngész.</string>
|
||||
<string name="backup_type_blocked_relays">letiltott átjátszólista</string>
|
||||
<string name="backup_type_blocked_relays_explainer">Átjátszók, amelyekhez ez az alkalmazás soha nem kapcsolódik.</string>
|
||||
<string name="backup_type_trusted_relays">megbízható átjátszólista</string>
|
||||
<string name="backup_type_trusted_relays_explainer">Átjátszók, amelyekhez kérdezés nélkül kapcsolódhat.</string>
|
||||
<string name="backup_type_private_outbox_relays">privát átjátszólista</string>
|
||||
<string name="backup_type_private_outbox_relays_explainer">Ahol a piszkozatai és privát adatai tárolódnak.</string>
|
||||
<string name="backup_type_app_settings">szinkronizált alkalmazásbeállítások</string>
|
||||
<string name="backup_type_app_settings_explainer">Az eszközök között szinkronizált Amethyst-beállítások. Titkosítva vannak, így csak a jelenlétük hasonlítható össze.</string>
|
||||
<string name="backup_type_public_chats">nyilvános csevegési lista</string>
|
||||
<string name="backup_type_public_chats_explainer">Nyilvános csevegések, amelyekhez csatlakozott.</string>
|
||||
<string name="backup_type_communities">közösséglista</string>
|
||||
<string name="backup_type_communities_explainer">Közösségek, amelyekhez csatlakozott.</string>
|
||||
<string name="backup_type_hashtags">követett kulcsszavak</string>
|
||||
<string name="backup_type_hashtags_explainer">Kulcsszavak, amelyek bejegyzései megjelennek a hírfolyamban.</string>
|
||||
<string name="backup_type_geohashes">követett helyek</string>
|
||||
<string name="backup_type_geohashes_explainer">Helyek, amelyek bejegyzései megjelennek a hírfolyamaiban.</string>
|
||||
<string name="backup_type_favorite_algo_feeds">kedvenc hírfolyamlista</string>
|
||||
<string name="backup_type_favorite_algo_feeds_explainer">Mentett algoritmus-hírfolyamok.</string>
|
||||
<string name="backup_type_ephemeral_chats">rövid életű csevegési lista</string>
|
||||
<string name="backup_type_ephemeral_chats_explainer">Rövid életű csevegőszobák, amelyekhez csatlakozott.</string>
|
||||
<string name="backup_type_relay_groups">csoportlista</string>
|
||||
<string name="backup_type_relay_groups_explainer">Átjátszó-alapú csoportok, amelyekhez csatlakozott.</string>
|
||||
<string name="backup_type_concord_communities">Concord közösséglista</string>
|
||||
<string name="backup_type_concord_communities_explainer">A Concord közösségek, amelyekhez csatlakozott. Titkosítva vannak, így csak a jelenlétük hasonlítható össze.</string>
|
||||
<string name="backup_type_trust_providers">bizalmi szolgáltatólista</string>
|
||||
<string name="backup_type_trust_providers_explainer">A szolgáltatások, amelyekben megbízik, hogy rangsorolják és ellenőrizzék Önnek az embereket.</string>
|
||||
<string name="backup_type_cashu_wallet">Cashu pénztárca</string>
|
||||
<string name="backup_type_cashu_wallet_explainer">Az ecash pénztárca beállításai és pénzverdéi. Titkosítva vannak, így csak a jelenlétük hasonlítható össze.</string>
|
||||
<string name="backup_type_nutzap_info">nutzap fogadási beállítások</string>
|
||||
<string name="backup_type_nutzap_info_explainer">A pénzverdék és a kulcs, amelyeket mások a nutzapok küldéséhez használnak az Ön számára.</string>
|
||||
<string name="backup_type_payment_targets">fizetési címek</string>
|
||||
<string name="backup_type_payment_targets_explainer">A módok, ahogy mások fizethetnek Önnek.</string>
|
||||
<string name="backup_type_bolt12_offers">BOLT12 ajánlatok</string>
|
||||
<string name="backup_type_bolt12_offers_explainer">A lightning ajánlatok, amelyeket mások a fizetéshez használnak az Ön számára.</string>
|
||||
<string name="backup_type_other">lista</string>
|
||||
<string name="backup_type_other_explainer">Egy listaelem ezen az eszközön mentve.</string>
|
||||
<string name="backup_entry_profile_field">Profilmezők</string>
|
||||
<string name="backup_entry_person">Személyek</string>
|
||||
<string name="backup_entry_hashtag">Kulcsszavak</string>
|
||||
<string name="backup_entry_word">Szavak</string>
|
||||
<string name="backup_entry_thread">Beszélgetések</string>
|
||||
<string name="backup_entry_public_chat">Nyilvános csevegések</string>
|
||||
<string name="backup_entry_community">Közösségek</string>
|
||||
<string name="backup_entry_algo_feed">Hírfolyamok</string>
|
||||
<string name="backup_entry_location">Helyek</string>
|
||||
<string name="backup_entry_relay">Átjátszók</string>
|
||||
<string name="backup_entry_relay_group">Csoportok</string>
|
||||
<string name="backup_entry_chat_room">Csevegőszobák</string>
|
||||
<string name="backup_entry_trust_provider">Bizalmi szolgáltatók</string>
|
||||
<string name="backup_entry_mint">Pénzverdék</string>
|
||||
<string name="backup_entry_nutzap_key">Nutzap kulcsok</string>
|
||||
<string name="backup_entry_payment_target">Fizetési címek</string>
|
||||
<string name="backup_entry_offer">Ajánlatok</string>
|
||||
<string name="backup_entry_identity_claim">Kapcsolt identitások</string>
|
||||
<string name="backup_entry_other">Egyéb bejegyzések</string>
|
||||
<string name="backup_profile_field_name">Felhasználónév</string>
|
||||
<string name="backup_profile_field_display_name">Megjelenített név</string>
|
||||
<string name="backup_profile_field_about">Névjegy</string>
|
||||
<string name="backup_profile_field_picture">Kép</string>
|
||||
<string name="backup_profile_field_banner">Borító</string>
|
||||
<string name="backup_profile_field_website">Weboldal</string>
|
||||
<string name="backup_profile_field_nip05">Nostr-cím</string>
|
||||
<string name="backup_profile_field_lud16">Lightning-cím</string>
|
||||
<string name="backup_profile_field_lud06">LNURL</string>
|
||||
<string name="backup_profile_field_pronouns">Névmások</string>
|
||||
<string name="backup_profile_field_birthday">Születésnap</string>
|
||||
<string name="backup_profile_field_clink_offer">CLINK-ajánlat</string>
|
||||
<string name="backup_profile_field_bot">Bot jelölő</string>
|
||||
</resources>
|
||||
|
||||
@@ -381,382 +381,4 @@
|
||||
<string name="mute_button">Dźwięk włączony. Kliknij, aby wyciszyć</string>
|
||||
<string name="play">Odtwórz</string>
|
||||
<string name="pause">Pauza</string>
|
||||
<string name="backup_conflict_title">Zmieniłeś %1$s w innej aplikacji</string>
|
||||
<string name="backup_conflict_removed">Usunięto (%1$s)</string>
|
||||
<string name="backup_conflict_added">Dodano (%1$s)</string>
|
||||
<string name="backup_conflict_changed">Zmieniono (%1$s)</string>
|
||||
<string name="backup_conflict_private_cleared">Usunąłeś wszystkie prywatne (zaszyfrowane) elementy.</string>
|
||||
<string name="backup_conflict_private_changed">Zmieniłeś również elementy prywatne (zaszyfrowane). Nie można ich tutaj porównać.</string>
|
||||
<string name="backup_conflict_private_added">Dodano prywatne (zaszyfrowane) pozycje.</string>
|
||||
<string name="backup_conflict_restore_mine">Przywróć zapisaną wersję</string>
|
||||
<string name="backup_review_saved">Na tym urządzeniu</string>
|
||||
<string name="backup_review_new">Nowa wersja</string>
|
||||
<string name="backup_review_not_set">Nie ustawiono</string>
|
||||
<string name="backup_conflict_count_removed">Usunięto %1$s</string>
|
||||
<string name="backup_conflict_count_added">Dodano %1$s</string>
|
||||
<string name="backup_conflict_count_changed">%1$s zmieniono</string>
|
||||
<plurals name="backup_card_follows_dropped">
|
||||
<item quantity="one">Przestałeś obserwować %1$d osobę</item>
|
||||
<item quantity="few">Przestałeś obserwować %1$d osób</item>
|
||||
<item quantity="many">Przestałeś obserwować %1$d osób</item>
|
||||
<item quantity="other">Przestałeś obserwować %1$d osoby</item>
|
||||
</plurals>
|
||||
<string name="backup_card_accept">Zaakceptuj</string>
|
||||
<string name="backup_review_title_updated">%1$s zaktualizowano</string>
|
||||
<string name="backup_review_title_cleared">%1$s wyczyszczono</string>
|
||||
<string name="backup_review_changed_by_other_app">Zmieniono w innej aplikacji · %1$s</string>
|
||||
<string name="backup_action_keep_count">Zachowaj %1$s</string>
|
||||
<string name="backup_action_restore_count">Przywróć %1$s</string>
|
||||
<string name="backup_action_remute">Ponownie wycisz %1$s</string>
|
||||
<string name="backup_action_rejoin">Ponów %1$s</string>
|
||||
<string name="backup_action_restore_profile">Przywróć profil</string>
|
||||
<string name="backup_action_restore_relays">Przywróć transmitery</string>
|
||||
<string name="backup_review_kept_count">Zachowano %1$s</string>
|
||||
<string name="backup_review_dropped_count">%1$s odrzuconych</string>
|
||||
<string name="backup_review_new_count">%1$s nowych</string>
|
||||
<string name="backup_review_tab_dropped">Usunięte · %1$s</string>
|
||||
<string name="backup_review_tab_new">Nowe · %1$s</string>
|
||||
<string name="backup_review_tab_edited">Edytowane · %1$s</string>
|
||||
<string name="backup_review_search_people">Szukaj %1$s osób</string>
|
||||
<string name="backup_review_nothing_here">Nic tu nie ma!</string>
|
||||
<string name="backup_review_unmuted">%1$s odblokowanych</string>
|
||||
<string name="backup_review_unmuted_explainer">Mogą one ponownie pojawić się w Twoich informacjach</string>
|
||||
<string name="backup_review_newly_muted">%1$s nowo wyciszonych</string>
|
||||
<string name="backup_review_words_and_hashtags">Wyrazy & hasztagi</string>
|
||||
<string name="backup_review_names_and_more">%1$s i %2$s więcej</string>
|
||||
<string name="backup_review_private_wiped_title">Usunąłeś wszystkie prywatne elementy</string>
|
||||
<string name="backup_review_private_wiped_body">Są zaszyfrowane, więc tylko Ty możesz zobaczyć, co to było. Odtworzenie przywróci je wszystkie.</string>
|
||||
<string name="backup_review_private_added_title">Ustawiłeś te pozycje jako prywatne</string>
|
||||
<string name="backup_review_private_added_body">Są teraz zaszyfrowane, co prawdopodobnie wyjaśnia, gdzie podziały się powyższe elementy publiczne.</string>
|
||||
<string name="backup_review_private_changed_title">Zmieniłeś prywatne elementy</string>
|
||||
<string name="backup_review_private_changed_body">Są zaszyfrowane, więc nie można ich tu porównać.</string>
|
||||
<string name="backup_review_gone">Zniknęła</string>
|
||||
<string name="backup_review_new_tag">Nowa</string>
|
||||
<string name="backup_review_dropped_tag">Usunięta</string>
|
||||
<string name="backup_review_demoted_tag">Przeniesiona</string>
|
||||
<string name="backup_review_units_tag">Jednostek</string>
|
||||
<string name="backup_review_left_tag">Zostało</string>
|
||||
<string name="backup_review_renamed_tag">Zmieniono nazwę</string>
|
||||
<string name="backup_review_outbox">Skrzynka nadawcza</string>
|
||||
<string name="backup_review_outbox_explainer">gdzie publikujesz</string>
|
||||
<string name="backup_review_inbox">Skrzynka odbiorcza</string>
|
||||
<string name="backup_review_inbox_explainer">gdzie inni docierają do Ciebie</string>
|
||||
<string name="backup_review_key_replaced">Wymieniono klucz odbierający</string>
|
||||
<string name="backup_review_key_removed">Usunięto klucz odbierający</string>
|
||||
<string name="backup_review_key_warning">Nutzapy zostaną przypisane do tego nowego klucza. Jeśli urządzenie nie posiada tego klucza, może się okazać, że nie będzie można ich tutaj zrealizować.</string>
|
||||
<string name="backup_review_left">zostało</string>
|
||||
<string name="backup_review_joined">dołączył(a)</string>
|
||||
<string name="backup_review_renamed">zmieniono nazwę</string>
|
||||
<string name="backup_review_was_named">było „%1$s”</string>
|
||||
<string name="backup_action_block_again">Zablokuj %1$s ponownie</string>
|
||||
<string name="backup_action_restore_feeds">Przywróć kanały</string>
|
||||
<string name="backup_action_restore_topics">Przywróć tematy</string>
|
||||
<string name="backup_action_restore_places">Przywróć miejsca</string>
|
||||
<string name="backup_action_restore_providers">Przywróć dostawców</string>
|
||||
<string name="backup_action_restore_wallet">Przywróć portfel</string>
|
||||
<string name="backup_review_kept">zachowane</string>
|
||||
<string name="backup_review_receiving_tag">Pobieranie</string>
|
||||
<string name="backup_review_listed_tag">Na Liście</string>
|
||||
<string name="backup_review_searching_tag">Szukam</string>
|
||||
<string name="backup_review_storing_tag">Przechowywanie</string>
|
||||
<string name="backup_review_trusted_tag">Zaufane</string>
|
||||
<string name="backup_review_untrusted_tag">Niezaufane</string>
|
||||
<string name="backup_review_unblocked">%1$s odblokowane</string>
|
||||
<string name="backup_review_unblocked_explainer">Ametyst ponownie połączy się z nimi</string>
|
||||
<string name="backup_review_no_longer_blocked">Nie jest już zablokowana</string>
|
||||
<string name="backup_review_newly_blocked">Nowo zablokowana</string>
|
||||
<string name="backup_review_still_blocked">Nadal zablokowana</string>
|
||||
<string name="backup_review_allowed_tag">Dozwolona</string>
|
||||
<string name="backup_review_moved_tag">Przeniesiona</string>
|
||||
<string name="backup_review_feed">Kanał</string>
|
||||
<string name="backup_review_topics_gone">tematy zniknęły</string>
|
||||
<string name="backup_review_places_gone"> miejsca zniknęły</string>
|
||||
<string name="backup_review_new_count_caption">nowe</string>
|
||||
<string name="backup_review_hashtags_you_follow">Hashtagi, które obserwujesz</string>
|
||||
<string name="backup_review_places_you_follow">Miejsca które obserwujesz</string>
|
||||
<string name="backup_review_services_changed">Zmieniono %1$s z %2$s serwisów</string>
|
||||
<string name="backup_review_services_changed_explainer">Teraz pochodzą od kogoś innego albo od nikogo</string>
|
||||
<string name="backup_review_service">Serwis</string>
|
||||
<string name="backup_review_service_rank">Ranking</string>
|
||||
<string name="backup_review_service_followers">Obserwujący</string>
|
||||
<string name="backup_review_service_topics">Tematy</string>
|
||||
<string name="backup_review_trust_warning">Rankingi, liczba obserwujących i filtrowanie spamu, które widzisz, pochodzą od tych dostawców.</string>
|
||||
<plurals name="backup_review_payment_targets_gone">
|
||||
<item quantity="one">%1$d sposób płatności został usunięty</item>
|
||||
<item quantity="few">%1$d sposobów płatności zostało usuniętych</item>
|
||||
<item quantity="many">%1$d sposobów płatności zostało usuniętych</item>
|
||||
<item quantity="other">%1$d sposoby płatności zostały usunięte</item>
|
||||
</plurals>
|
||||
<plurals name="backup_review_offers_gone">
|
||||
<item quantity="one">%1$d oferta usunięta</item>
|
||||
<item quantity="few">%1$d ofert usunięto</item>
|
||||
<item quantity="many">%1$d ofert usunięto</item>
|
||||
<item quantity="other">%1$d oferty usunięte</item>
|
||||
</plurals>
|
||||
<string name="backup_review_payments_explainer">Osoby, które Ci płacą, widzą tylko to, co znajduje się na tej liście.</string>
|
||||
<string name="backup_review_offer">Oferta BOLT12</string>
|
||||
<string name="backup_review_encrypted_cleared">Opróżniłeś to</string>
|
||||
<string name="backup_review_encrypted_added">Utworzyłeś to</string>
|
||||
<string name="backup_review_encrypted_changed">Zmieniłeś to</string>
|
||||
<string name="backup_review_wallet_body">Minty i klucze w Twoim portfelu są zaszyfrowane dla Ciebie, więc nie można ich tutaj porównać pozycja po pozycji. Przywrócenie danych powoduje przywrócenie dokładnie tego, co zostało zapisane na tym urządzeniu.</string>
|
||||
<string name="backup_review_concord_body">Twoje społeczności w Concord są dla Ciebie zaszyfrowane, więc nie można ich tutaj porównać. Przywrócenie danych powoduje przywrócenie dokładnie tego, co zostało zapisane na tym urządzeniu.</string>
|
||||
<plurals name="backup_card_mutes_visible">
|
||||
<item quantity="one">Włączyłeś dźwięk dla %1$d elementu</item>
|
||||
<item quantity="few">Włączyłeś dźwięk dla %1$d elementów</item>
|
||||
<item quantity="many">Włączyłeś dźwięk dla %1$d elementów</item>
|
||||
<item quantity="other">%1$d elementy mają włączony dźwięk</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_profile_lost_fields">
|
||||
<item quantity="one">Usunąłeś %1$d pole profilu</item>
|
||||
<item quantity="few">Usunąłeś %1$d pól profilowych</item>
|
||||
<item quantity="many">Usunąłeś %1$d pól profilowych</item>
|
||||
<item quantity="other">Usunąłeś %1$d pola profilowe</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_nip65_lost">
|
||||
<item quantity="one">Usunąłeś %1$d publiczny transmiter</item>
|
||||
<item quantity="few">Usunąłeś %1$d publicznych transmiterów</item>
|
||||
<item quantity="many">Usunąłeś %1$d publicznych transmiterów</item>
|
||||
<item quantity="other">Usunąłeś %1$d publiczne transmitery</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_dm_relays_lost">
|
||||
<item quantity="one">Usunąłeś %1$d transmiter DM</item>
|
||||
<item quantity="few">Usunąłeś %1$d transmiterów DM</item>
|
||||
<item quantity="many">Usunąłeś %1$d transmiterów DM</item>
|
||||
<item quantity="other">Usunąłeś %1$d transmitery DM</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_key_package_relays_lost">
|
||||
<item quantity="one">Usunięto %1$d transmiter klucza grupowego czatu</item>
|
||||
<item quantity="few">Usunięto %1$d transmiterów klucza grupowego czatu</item>
|
||||
<item quantity="many">Usunięto %1$d transmiterów klucza grupowego czatu</item>
|
||||
<item quantity="other">Usunięto %1$d transmitery klucza grupowego czatu</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_search_relays_lost">
|
||||
<item quantity="one">Usunięto %1$d transmiter wyszukiwania</item>
|
||||
<item quantity="few">Usunięto %1$d transmiterów wyszukiwania</item>
|
||||
<item quantity="many">Usunięto %1$d transmiterów wyszukiwania</item>
|
||||
<item quantity="other">Usunięto %1$d transmitery wyszukiwania</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_indexer_relays_lost">
|
||||
<item quantity="one">Usunięto %1$d transmiter indeksujący</item>
|
||||
<item quantity="few">Usunięto %1$d transmiterów indeksujących</item>
|
||||
<item quantity="many">Usunięto %1$d transmiterów indeksujących</item>
|
||||
<item quantity="other">Usunięto %1$d transmitery indeksujące</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_relay_feeds_lost">
|
||||
<item quantity="one">Usunięto %1$d kanał transmitera</item>
|
||||
<item quantity="few">Usunięto %1$d kanałów transmitera</item>
|
||||
<item quantity="many">Usunięto %1$d kanałów transmitera</item>
|
||||
<item quantity="other">Usunięto %1$d kanały transmitera</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_private_outbox_lost">
|
||||
<item quantity="one">Usunięto %1$d prywatny transmiter</item>
|
||||
<item quantity="few">Usunięto %1$d prywatnych transmiterów</item>
|
||||
<item quantity="many">Usunięto %1$d prywatnych transmiterów</item>
|
||||
<item quantity="other">Usunięto %1$d prywatne transmitery</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trusted_lost">
|
||||
<item quantity="one">Przestałeś ufać %1$d transmiterowi</item>
|
||||
<item quantity="few">Przestałeś ufać %1$d transmiterom</item>
|
||||
<item quantity="many">Przestałeś ufać %1$d transmiterom</item>
|
||||
<item quantity="other">Przestałeś ufać %1$d transmiterom</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_unblocked">
|
||||
<item quantity="one">Odblokowałeś %1$d transmiter</item>
|
||||
<item quantity="few">Odblokowałeś %1$d transmiterów</item>
|
||||
<item quantity="many">Odblokowałeś %1$d transmiterów</item>
|
||||
<item quantity="other">Odblokowałeś %1$d transmitery</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_chats">
|
||||
<item quantity="one">Opuściłeś %1$d czat publiczny</item>
|
||||
<item quantity="few">Opuściłeś %1$d czatów publicznych</item>
|
||||
<item quantity="many">Opuściłeś %1$d czatów publicznych</item>
|
||||
<item quantity="other">Opuściłeś %1$d czaty publiczne</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_communities">
|
||||
<item quantity="one">Opuściłeś %1$d społeczność</item>
|
||||
<item quantity="few">Opuściłeś %1$d społeczności</item>
|
||||
<item quantity="many">Opuściłeś %1$d społeczności</item>
|
||||
<item quantity="other">Opuściłeś %1$d społeczności</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_rooms">
|
||||
<item quantity="one">Opuściłeś %1$d pokój czatu</item>
|
||||
<item quantity="few">Opuściłeś %1$d pokoi czatu</item>
|
||||
<item quantity="many">Opuściłeś %1$d pokoi czatu</item>
|
||||
<item quantity="other">Opuściłeś %1$d pokoje czatu</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_groups">
|
||||
<item quantity="one">Opuściłeś %1$d grupę</item>
|
||||
<item quantity="few">Opuściłeś %1$d grup</item>
|
||||
<item quantity="many">Opuściłeś %1$d grup</item>
|
||||
<item quantity="other">Opuszczono %1$d grupy</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_feeds_removed">
|
||||
<item quantity="one">Usunąłeś %1$d ulubiony kanał</item>
|
||||
<item quantity="few">Usunąłeś %1$d ulubionych kanałów</item>
|
||||
<item quantity="many">Usunąłeś %1$d ulubionych kanałów</item>
|
||||
<item quantity="other">Usunięto %1$d ulubione kanały</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_hashtags_unfollowed">
|
||||
<item quantity="one">Przestałeś obserwować %1$d hashtag</item>
|
||||
<item quantity="few">Przestałeś obserwować %1$d hashtagów</item>
|
||||
<item quantity="many">Przestałeś obserwować %1$d hashtagów</item>
|
||||
<item quantity="other">Przestałeś obserwować %1$d hashtagi</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_places_unfollowed">
|
||||
<item quantity="one">Przestałeś obserwować %1$d miejsce</item>
|
||||
<item quantity="few">Przestałeś obserwować %1$d miejsc</item>
|
||||
<item quantity="many">Przestałeś obserwować %1$d miejsc</item>
|
||||
<item quantity="other">Przestałeś obserwować %1$d miejsca</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trust_services_changed">
|
||||
<item quantity="one">Zmieniłeś dostawcę %1$d zaufanego serwisu</item>
|
||||
<item quantity="few">Zmieniłeś dostawcę %1$d zaufanych serwisów</item>
|
||||
<item quantity="many">Zmieniłeś dostawcę %1$d zaufanych serwisów</item>
|
||||
<item quantity="other">Zmieniłeś dostawcę %1$d zaufanych serwisów</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_nutzap_mints_removed">
|
||||
<item quantity="one">Usunięto %1$d nutzap mint</item>
|
||||
<item quantity="few">Usunięto %1$d nutzap mintów</item>
|
||||
<item quantity="many">Usunięto %1$d nutzap mintów</item>
|
||||
<item quantity="other">Usunięto %1$d nutzap minty</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_payment_targets_removed">
|
||||
<item quantity="one">Usunięto %1$d sposób na otrzymanie zapłaty</item>
|
||||
<item quantity="few">Usunięto %1$d sposobów otrzymywania zapłaty</item>
|
||||
<item quantity="many">Usunięto %1$d sposobów otrzymywania zapłaty</item>
|
||||
<item quantity="other">Usunięto %1$d sposoby otrzymywania zapłaty</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_offers_removed">
|
||||
<item quantity="one">Usunięto %1$d ofertę BOLT12</item>
|
||||
<item quantity="few">Usunięto %1$d ofert BOLT12</item>
|
||||
<item quantity="many">Usunięto %1$d ofert BOLT12</item>
|
||||
<item quantity="other">Usunięto %1$d oferty BOLT12</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_added">
|
||||
<item quantity="one">%1$s i dodano %2$d</item>
|
||||
<item quantity="few">%1$s i dodano %2$d</item>
|
||||
<item quantity="many">%1$s i dodano %2$d</item>
|
||||
<item quantity="other">%1$s i dodano %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_followed">
|
||||
<item quantity="one">%1$s i obserwowany %2$d</item>
|
||||
<item quantity="few">%1$s i obserwowanych %2$d</item>
|
||||
<item quantity="many">%1$s i obserwowanych %2$d</item>
|
||||
<item quantity="other">%1$s i obserwowane %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_muted">
|
||||
<item quantity="one">%1$s i wyciszony %2$d</item>
|
||||
<item quantity="few">%1$s i wyciszono %2$d</item>
|
||||
<item quantity="many">%1$s i wyciszono %2$d</item>
|
||||
<item quantity="other">%1$s i wyciszone %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_joined">
|
||||
<item quantity="one">%1$s i dołączono do %2$d</item>
|
||||
<item quantity="few">%1$s i dołączono do %2$d</item>
|
||||
<item quantity="many">%1$s i dołączono do %2$d</item>
|
||||
<item quantity="other">%1$s i dołączono do %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_blocked">
|
||||
<item quantity="one">%1$s i zablokowano %2$d</item>
|
||||
<item quantity="few">%1$s i zablokowano %2$d</item>
|
||||
<item quantity="many">%1$s i zablokowano %2$d</item>
|
||||
<item quantity="other">%1$s i zablokowano %2$d</item>
|
||||
</plurals>
|
||||
<string name="backup_card_app_settings">Twoje zsynchronizowane ustawienia aplikacji Amethyst zostały zmienione w innej aplikacji, która nie jest Amethystem. To może powodować problemy.</string>
|
||||
<string name="backup_card_nutzap_key_replaced">Wymieniłeś swój klucz Nutzap</string>
|
||||
<string name="backup_card_nutzap_key_removed">Usunąłeś swój klucz nutzap</string>
|
||||
<string name="backup_card_wallet_emptied">Opróżniłeś swój portfel Cashu</string>
|
||||
<string name="backup_card_wallet_rewritten">Zmieniłeś swój portfel Cashu</string>
|
||||
<string name="backup_card_concord_emptied">Opróżniłeś swoją listę Concorda</string>
|
||||
<string name="backup_card_concord_rewritten">Zmieniłeś swoją listę Concorda</string>
|
||||
<string name="backup_conflict_keep_new">Użyj nowej wersji</string>
|
||||
<string name="backup_conflict_relay_read_only">tylko do odczytu</string>
|
||||
<string name="backup_conflict_relay_write_only">tylko do zapisu</string>
|
||||
<string name="backup_conflict_relay_read_write">odczyt i zapis</string>
|
||||
<string name="backup_type_profile">profil</string>
|
||||
<string name="backup_type_profile_explainer">Twoje imię i nazwisko, zdjęcie, biografia oraz adresy do płatności – tak, jak widzą je wszyscy.</string>
|
||||
<string name="backup_type_follow_list">lista obserwowanych</string>
|
||||
<string name="backup_type_follow_list_explainer">Określa, czyje posty pojawiają się w Twoim kanale głównym.</string>
|
||||
<string name="backup_type_mute_list">lista zablokowanych</string>
|
||||
<string name="backup_type_mute_list_explainer">Ukrywa osoby, słowa, hashtagi i wątki we wszystkich wyświetlanych treściach.</string>
|
||||
<string name="backup_type_outbox_inbox_relays">lista publicznych transmiterów</string>
|
||||
<string name="backup_type_outbox_inbox_relays_explainer">Informuje wszystkich, gdzie mogą znaleźć Twoje posty oraz gdzie mają wysyłać Ci odpowiedzi i wzmianki.</string>
|
||||
<string name="backup_type_dm_relays">Lista transmiterów DM</string>
|
||||
<string name="backup_type_dm_relays_explainer">Gdzie inni dostarczają Twoje prywatne wiadomości.</string>
|
||||
<string name="backup_type_key_package_relays">transmitery kluczy czatu grupowego</string>
|
||||
<string name="backup_type_key_package_relays_explainer">Gdzie inni znajdą klucze do dodawania cię do zaszyfrowanych czatów grupowych.</string>
|
||||
<string name="backup_type_search_relays">lista transmiterów wyszukiwania</string>
|
||||
<string name="backup_type_search_relays_explainer">Transmitery używane podczas wyszukiwania.</string>
|
||||
<string name="backup_type_indexer_relays">lista transmiterów indeksujących</string>
|
||||
<string name="backup_type_indexer_relays_explainer">Transmitery służące do wyszukiwania profili innych osób oraz list transmiterów.</string>
|
||||
<string name="backup_type_relay_feeds">ulubione kanały transmitera</string>
|
||||
<string name="backup_type_relay_feeds_explainer">Transmitery, które przeglądasz jako kanały informacyjne.</string>
|
||||
<string name="backup_type_blocked_relays">lista zablokowanych przekaźników</string>
|
||||
<string name="backup_type_blocked_relays_explainer">Transmitery, z którymi ta aplikacja nigdy się nie łączy.</string>
|
||||
<string name="backup_type_trusted_relays">lista zaufanych transmiterów</string>
|
||||
<string name="backup_type_trusted_relays_explainer">Zaufane transmitery, z którymi bez wahania nawiązujesz połączenie.</string>
|
||||
<string name="backup_type_private_outbox_relays">lista prywatnych transmiterów</string>
|
||||
<string name="backup_type_private_outbox_relays_explainer">Gdzie przechowywane są Twoje projekty i prywatne dane.</string>
|
||||
<string name="backup_type_app_settings">zsynchronizowane ustawienia aplikacji</string>
|
||||
<string name="backup_type_app_settings_explainer">Ustawienia Amethyst są synchronizowane na wszystkich Twoich urządzeniach. Są one zaszyfrowane, więc można porównać jedynie sam fakt ich obecności.</string>
|
||||
<string name="backup_type_public_chats">lista czatów publicznych</string>
|
||||
<string name="backup_type_public_chats_explainer">Publiczne czaty, do których dołączyłeś.</string>
|
||||
<string name="backup_type_communities">lista społeczności</string>
|
||||
<string name="backup_type_communities_explainer">Społeczności, do których dołączyłeś.</string>
|
||||
<string name="backup_type_hashtags">obserwowane hashtagi</string>
|
||||
<string name="backup_type_hashtags_explainer">Hashtagi, z których pochodzą posty wyświetlane w Twoich kanałach.</string>
|
||||
<string name="backup_type_geohashes">obserwowane lokalizacje</string>
|
||||
<string name="backup_type_geohashes_explainer">Miejsca, z których posty pojawiają się na Twoich kanałach.</string>
|
||||
<string name="backup_type_favorite_algo_feeds">lista ulubionych kanałów</string>
|
||||
<string name="backup_type_favorite_algo_feeds_explainer">Zapisane przez Ciebie kanały algorytmiczne.</string>
|
||||
<string name="backup_type_ephemeral_chats">lista czatów efemerycznych</string>
|
||||
<string name="backup_type_ephemeral_chats_explainer">Tymczasowe czaty, do których dołączyłeś.</string>
|
||||
<string name="backup_type_relay_groups">lista grup</string>
|
||||
<string name="backup_type_relay_groups_explainer">Grupy oparte na transmiterach, do których dołączyłeś.</string>
|
||||
<string name="backup_type_concord_communities">Lista społeczności Concord</string>
|
||||
<string name="backup_type_concord_communities_explainer">Społeczności Concord, do których dołączyłeś. Są one zaszyfrowane, więc można porównać jedynie fakt ich istnienia.</string>
|
||||
<string name="backup_type_trust_providers">lista zaufanych dostawców</string>
|
||||
<string name="backup_type_trust_providers_explainer">Serwisy, którym ufasz, a które zajmują się klasyfikowaniem i weryfikacją osób w Twoim imieniu.</string>
|
||||
<string name="backup_type_cashu_wallet">Portfel Cashu</string>
|
||||
<string name="backup_type_cashu_wallet_explainer">Ustawienia portfela ecash oraz minty. Są one zaszyfrowane, więc można porównać jedynie sam fakt ich istnienia.</string>
|
||||
<string name="backup_type_nutzap_info">ustawienia odbioru nutzap</string>
|
||||
<string name="backup_type_nutzap_info_explainer">Minty i klucz, które inni używają do wysyłania ci „nutzapów”.</string>
|
||||
<string name="backup_type_payment_targets">adresy płatności</string>
|
||||
<string name="backup_type_payment_targets_explainer">Sposoby, w jakie inni mogą Ci zapłacić.</string>
|
||||
<string name="backup_type_bolt12_offers">Oferta BOLT12</string>
|
||||
<string name="backup_type_bolt12_offers_explainer">Ta możliwość pozwala innym płacić Ci za pomocą Lightning.</string>
|
||||
<string name="backup_type_other">lista</string>
|
||||
<string name="backup_type_other_explainer">Lista zapisana na tym urządzeniu.</string>
|
||||
<string name="backup_entry_profile_field">Pola profilu</string>
|
||||
<string name="backup_entry_person">Osoby</string>
|
||||
<string name="backup_entry_hashtag">Hashtagi</string>
|
||||
<string name="backup_entry_word">Słowa</string>
|
||||
<string name="backup_entry_thread">Wątki</string>
|
||||
<string name="backup_entry_public_chat">Czaty publiczne</string>
|
||||
<string name="backup_entry_community">Społeczności</string>
|
||||
<string name="backup_entry_algo_feed">Kanały</string>
|
||||
<string name="backup_entry_location">Lokalizacje</string>
|
||||
<string name="backup_entry_relay">Transmitery</string>
|
||||
<string name="backup_entry_relay_group">Grupy</string>
|
||||
<string name="backup_entry_chat_room">Czat pokoje</string>
|
||||
<string name="backup_entry_trust_provider">Zaufani dostawcy</string>
|
||||
<string name="backup_entry_mint">Minty</string>
|
||||
<string name="backup_entry_nutzap_key">Klucze Nutzap</string>
|
||||
<string name="backup_entry_payment_target">Adresy płatności</string>
|
||||
<string name="backup_entry_offer">Oferty</string>
|
||||
<string name="backup_entry_identity_claim">Powiązane tożsamości</string>
|
||||
<string name="backup_entry_other">Inne wpisy</string>
|
||||
<string name="backup_profile_field_name">Nazwa użytkownika</string>
|
||||
<string name="backup_profile_field_display_name">Nazwa wyświetlana</string>
|
||||
<string name="backup_profile_field_about">O profilu</string>
|
||||
<string name="backup_profile_field_picture">Zdjęcie</string>
|
||||
<string name="backup_profile_field_banner">Baner</string>
|
||||
<string name="backup_profile_field_website">Strona www</string>
|
||||
<string name="backup_profile_field_nip05">Adres Nostr</string>
|
||||
<string name="backup_profile_field_lud16">Lightning Adres</string>
|
||||
<string name="backup_profile_field_lud06">LNURL</string>
|
||||
<string name="backup_profile_field_pronouns">Zaimki</string>
|
||||
<string name="backup_profile_field_birthday">Data urodzin</string>
|
||||
<string name="backup_profile_field_clink_offer">Oferta CLINK</string>
|
||||
<string name="backup_profile_field_bot">Flaga bota</string>
|
||||
</resources>
|
||||
|
||||
@@ -305,250 +305,6 @@
|
||||
|
||||
|
||||
|
||||
<string name="cordn_groups_manage">Coordinators</string>
|
||||
<string name="cordn_groups_down_note">Nothing is arriving from these groups. Amethyst keeps retrying.</string>
|
||||
<string name="cordn_groups_none">No cordn groups yet</string>
|
||||
<string name="cordn_groups_none_detail">A cordn group lives on one coordinator that holds its membership and passes messages along, without ever seeing what anyone writes.</string>
|
||||
<string name="cordn_groups_start">Start one</string>
|
||||
<string name="cordn_group_unavailable">This group is not available. Its coordinator may have been removed.</string>
|
||||
<string name="cordn_group_info">Group info</string>
|
||||
<string name="cordn_message_deleted">Message deleted</string>
|
||||
<string name="cordn_message_edited">edited</string>
|
||||
<string name="cordn_action_go_to_message">Go to message</string>
|
||||
<string name="cordn_delete_confirm_title">Withdraw message</string>
|
||||
<string name="cordn_delete_confirm_body">Everyone in the group will see this message as withdrawn, and Amethyst will stop showing its text. The coordinator still holds the encrypted copy it was sent as, and anyone who already read it has already read it.</string>
|
||||
<string name="cordn_delivery_accepted">Accepted by the coordinator</string>
|
||||
<string name="cordn_message_details_title">Message details</string>
|
||||
<string name="cordn_message_details_sent_at">Sent</string>
|
||||
<string name="cordn_message_details_cursor">Cursor</string>
|
||||
<string name="cordn_message_details_coordinator">Coordinator</string>
|
||||
<string name="cordn_composer_hint">Message</string>
|
||||
<string name="cordn_action_reply">Reply</string>
|
||||
<string name="cordn_action_edit">Edit</string>
|
||||
<string name="cordn_action_delete">Delete</string>
|
||||
<string name="cordn_action_pin">Pin</string>
|
||||
<string name="cordn_pinned_previous">Previous pinned message</string>
|
||||
<string name="cordn_pinned_next">Next pinned message</string>
|
||||
<string name="cordn_pinned_show_all">Show all pinned messages</string>
|
||||
<string name="cordn_pinned_title">Pinned messages</string>
|
||||
<string name="cordn_pinned_by">Pinned by %1$s</string>
|
||||
<plurals name="cordn_pinned_count">
|
||||
<item quantity="one">%1$d pinned message in this group</item>
|
||||
<item quantity="other">%1$d pinned messages in this group</item>
|
||||
</plurals>
|
||||
<string name="cordn_action_unpin">Unpin</string>
|
||||
<string name="cordn_action_editing">Editing your message</string>
|
||||
<string name="cordn_media_upload_failed">Could not send that file.</string>
|
||||
<string name="cordn_send_failed">That did not send.</string>
|
||||
<string name="cordn_send_no_session">This group\'s coordinator is not open, so nothing can be sent yet.</string>
|
||||
<string name="cordn_media_download_failed">Could not open that file.</string>
|
||||
<string name="cordn_media_no_server">No media server is set for this account, so there is nowhere to put the file. Pick one in Settings.</string>
|
||||
<string name="cordn_media_unreadable">That file could not be read.</string>
|
||||
<string name="cordn_voice_record">Record a voice note</string>
|
||||
<string name="cordn_voice_stop">Stop and send</string>
|
||||
<string name="cordn_voice_play">Play voice note</string>
|
||||
<string name="cordn_backup_explainer">Your nsec cannot bring cordn groups back. A cordn group lives as encryption state on this device and an ordered stream on a coordinator that cannot read it — lose the device without a backup and the group is gone, including everything already said in it.</string>
|
||||
<string name="cordn_backup_passphrase">Passphrase</string>
|
||||
<string name="cordn_backup_contents_title">What is in the file</string>
|
||||
<string name="cordn_backup_contents_body">Your group encryption keys, your key packages, and every message in those groups. Anyone who opens it can read the conversations. The passphrase is the only thing protecting it once it leaves Amethyst.</string>
|
||||
<string name="cordn_backup_export">Export</string>
|
||||
<string name="cordn_backup_exported">Backup saved.</string>
|
||||
<string name="cordn_backup_restore_title">Restore</string>
|
||||
<string name="cordn_backup_restore_body">Restoring replaces the cordn groups on this device with the ones in the file. It is for a phone that has taken over from another — not a way to use the same groups on two devices at once.</string>
|
||||
<string name="cordn_backup_restore">Restore</string>
|
||||
<string name="cordn_backup_restore_confirm_title">Replace this device\'s cordn groups?</string>
|
||||
<string name="cordn_backup_restore_confirm_body">Every cordn group now on this device will be removed and replaced by the ones in the file.\n\nDo not restore onto a second phone while the first is still in use. Both would hold the same group keys, and once both have sent a message the group breaks for everyone — silently, and with no way back.</string>
|
||||
<string name="cordn_backup_restored">Restored.</string>
|
||||
<string name="cordn_backup_failed">That did not work. Check the passphrase and the file.</string>
|
||||
<string name="cordn_send">Send</string>
|
||||
<string name="cordn_info_coordinator">Coordinator</string>
|
||||
<string name="cordn_info_coordinator_key">Coordinator key</string>
|
||||
<string name="cordn_info_coordinator_nprofile">Coordinator link</string>
|
||||
<string name="cordn_info_copy_nprofile">Copy the coordinator\'s nprofile</string>
|
||||
<string name="cordn_info_gid">Group id</string>
|
||||
<string name="cordn_info_epoch">Epoch</string>
|
||||
<string name="cordn_info_members">Members</string>
|
||||
<string name="cordn_info_egalitarian">This group has no admins: everyone can add, remove and rename, permanently.</string>
|
||||
<string name="cordn_info_technical">Technical details</string>
|
||||
<string name="cordn_create_title">New Cordn group</string>
|
||||
<string name="cordn_create_explainer">A cordn group is ordered by one coordinator you choose. Creating the group happens on this device — the coordinator only learns the group exists once you invite someone or send a message.</string>
|
||||
<string name="cordn_create_people_none">Nobody yet — tap to add people</string>
|
||||
<string name="cordn_create_people_empty">Nobody added yet. A group can be created empty and invitations sent later, but naming people now is what shows which coordinator can reach them.</string>
|
||||
<string name="cordn_create_people_done">Done</string>
|
||||
<string name="cordn_create_you">You, always an admin</string>
|
||||
<string name="cordn_create_step_name">Name it</string>
|
||||
<string name="cordn_create_step_people">Who is in it</string>
|
||||
<string name="cordn_create_step_where">Where it lives</string>
|
||||
<string name="cordn_create_step_admins">Who can add and remove</string>
|
||||
<string name="cordn_create_add_member">Add someone</string>
|
||||
<string name="cordn_create_people_note">Naming people now is what tells us which coordinator can reach them. Each one gets a Welcome left on that coordinator, which they pick up next time they open their app.</string>
|
||||
<string name="cordn_create_reach_unknown">Not checked yet</string>
|
||||
<string name="cordn_create_reach_none">No key on any coordinator you use</string>
|
||||
<string name="cordn_create_egalitarian">Everyone can add and remove</string>
|
||||
<string name="cordn_create_admin">Admin</string>
|
||||
<string name="cordn_create_no_coordinator">No coordinator chosen</string>
|
||||
<string name="cordn_create_coordinator_change">Change</string>
|
||||
<string name="cordn_create_coordinator_hide">Done</string>
|
||||
<string name="cordn_create_coverage_unknown">Not checked — picking it will ask</string>
|
||||
<string name="cordn_create_coverage_all">Reaches all %1$d of your people</string>
|
||||
<string name="cordn_create_coverage_partial">Reaches %1$d of %2$d — the rest would be left out</string>
|
||||
<string name="cordn_create_outcome_title">The group exists</string>
|
||||
<string name="cordn_create_outcome_explainer">Each invitation is a Welcome left on the coordinator, so they can fail one at a time. Nobody has been notified: they see it next time they open their app.</string>
|
||||
<string name="cordn_create_outcome_no_welcome">Added to the group, but the invitation did not reach them — try again from the group screen</string>
|
||||
<string name="cordn_create_outcome_waiting">Waiting for them</string>
|
||||
<string name="cordn_create_outcome_failed">The coordinator refused the invitation</string>
|
||||
<string name="cordn_create_outcome_skipped">No key here, so no Welcome could be left</string>
|
||||
<string name="cordn_create_outcome_link">Send a link</string>
|
||||
<string name="cordn_create_outcome_open">Open the chat</string>
|
||||
<string name="cordn_create_coordinator">Coordinator</string>
|
||||
<string name="cordn_create_coordinator_discover">Find coordinators</string>
|
||||
<string name="cordn_create_coordinator_new">Another coordinator</string>
|
||||
<string name="cordn_create_coordinator_pubkey">Coordinator public key (hex or npub)</string>
|
||||
<string name="cordn_create_coordinator_relays">Relays it answers on, one per line</string>
|
||||
<string name="cordn_create_name">Group name</string>
|
||||
<string name="cordn_create_description">Description (optional)</string>
|
||||
<string name="cordn_create_egalitarian_note">Everyone in the group can invite, remove members and change its details. Any member can name admins later, which ends that.</string>
|
||||
<string name="cordn_create_admin_only_me">Only I manage this group</string>
|
||||
<string name="cordn_admin_action_failed">That change could not be made.</string>
|
||||
<string name="cordn_info_remove_member">Remove</string>
|
||||
<string name="cordn_info_remove_confirm_title">Remove from group?</string>
|
||||
<string name="cordn_info_remove_confirm_body">%1$s stops receiving messages from here. They keep what they have already read, and this cannot be undone — they would have to be invited again.</string>
|
||||
<string name="cordn_info_edit_details">Edit details</string>
|
||||
<string name="cordn_info_save">Save</string>
|
||||
<string name="cordn_create_admin_only_me_on">Only you can invite, remove members or change the group\'s details. You can hand that to someone else later.</string>
|
||||
<string name="cordn_create_action">Create group</string>
|
||||
<string name="cordn_create_failed">The group could not be created.</string>
|
||||
<string name="cordn_invitations_title">Cordn invitations</string>
|
||||
<string name="cordn_invitations_explainer">Checked when you open this screen, and at no other time — asking a coordinator whether anyone invited you tells it you are here, so Amethyst does not do it in the background.</string>
|
||||
<string name="cordn_invitations_refresh">Check again</string>
|
||||
<string name="cordn_invitations_accept">Join</string>
|
||||
<string name="cordn_invitations_decline">Decline</string>
|
||||
<string name="cordn_invitations_decline_warning">Declining is permanent. Getting back in means being invited again.</string>
|
||||
<string name="cordn_chat_yesterday">Yesterday</string>
|
||||
<string name="cordn_chat_unread_divider">New messages</string>
|
||||
<string name="cordn_chat_empty_title">No messages yet</string>
|
||||
<string name="cordn_chat_empty_description">Anything sent here is encrypted for this group. The coordinator relays it without being able to read it.</string>
|
||||
<string name="cordn_reactions_title">Reactions</string>
|
||||
<string name="cordn_group_unavailable_detail">Add a coordinator in Settings to start using cordn groups.</string>
|
||||
<string name="cordn_coordinators_discover_explainer">Reads announcements your relays already carry. No coordinator is contacted, so none of them learns you looked.</string>
|
||||
<string name="cordn_coordinators_discover_action">Look for coordinators</string>
|
||||
<string name="cordn_coordinators_discover_add">Add</string>
|
||||
<string name="cordn_coordinators_discover_failed">Could not read announcements</string>
|
||||
<string name="cordn_coordinators_discover_none">Nobody is announcing on your relays.</string>
|
||||
<string name="cordn_coordinators_discover_unheard">Nothing found, and %1$d of your relays did not answer.</string>
|
||||
<string name="cordn_coordinators_discover_seen">Announced %1$s ago</string>
|
||||
<string name="cordn_coordinators_discover_seen_on">Last announced %1$s</string>
|
||||
<string name="cordn_coordinators_relays">%1$s</string>
|
||||
<string name="cordn_coordinators_relays_more">%1$s +%2$d more</string>
|
||||
<string name="cordn_coordinators_show_all">Show all %1$d</string>
|
||||
<string name="cordn_coordinators_show_fewer">Show fewer</string>
|
||||
<string name="cordn_coordinators_show_older">Show %1$d that stopped announcing</string>
|
||||
<string name="cordn_coordinators_hide_older">Hide the ones that stopped announcing</string>
|
||||
<string name="cordn_coordinators_stale_note">These have not announced in over a month. Creating a group on one that has gone away will fail.</string>
|
||||
<string name="cordn_info_add_member">Add someone</string>
|
||||
<string name="cordn_info_add_member_placeholder">Name, npub or name@domain</string>
|
||||
<string name="cordn_info_has_key_package">Can be added on this coordinator</string>
|
||||
<string name="cordn_info_add_member_note">They can only be added if they published a key package to this coordinator.</string>
|
||||
<string name="cordn_exposure_open">What this coordinator can see</string>
|
||||
<string name="cordn_exposure_close">Got it</string>
|
||||
<string name="cordn_admin_someone">That person</string>
|
||||
<string name="cordn_admin_no_key_package">%1$s has not published a key package to this coordinator, so they cannot be added yet. Ask them to open cordn on this coordinator first.</string>
|
||||
<string name="cordn_admin_wrong_key_package">This coordinator served a key package that belongs to someone else, so %1$s was not added. Nothing was changed.</string>
|
||||
<string name="cordn_admin_no_welcome">%1$s could not be given a way into the group, so the add was abandoned.</string>
|
||||
<string name="cordn_admin_not_a_member">%1$s is not in this group.</string>
|
||||
<string name="cordn_admin_no_self_remove">You cannot remove yourself from a cordn group.</string>
|
||||
<string name="cordn_admin_coordinator_silent">The coordinator did not answer, so nothing was changed. Try again in a moment.</string>
|
||||
<string name="cordn_info_add_member_none">Nobody found by that name.</string>
|
||||
<string name="cordn_info_admin_badge">Admin</string>
|
||||
<string name="cordn_invitations_members_more">+%1$d more</string>
|
||||
<string name="cordn_invitations_via">Through %1$s</string>
|
||||
<string name="cordn_invitations_none">No invitations waiting.</string>
|
||||
<string name="cordn_invitations_no_coordinators">You have no coordinator open. cordn invitations arrive through a coordinator, so there is nowhere to look yet.</string>
|
||||
<string name="cordn_invitations_unreachable">%1$s did not answer</string>
|
||||
<string name="cordn_invitations_skipped">An invitation was left for another device</string>
|
||||
<string name="cordn_invitations_load_failed">Could not read invitations.</string>
|
||||
<string name="cordn_link_request">Ask to join this group</string>
|
||||
<string name="cordn_link_request_disclosure">This publishes a key package under your own account key and tells the coordinator you want into this group — whether or not anyone answers.</string>
|
||||
<string name="cordn_link_request_sent">Asked. A member of the group has to add you; the invitation will show up under cordn invitations.</string>
|
||||
<string name="cordn_link_request_failed">Could not ask to join.</string>
|
||||
<string name="cordn_requests_title">Requests to join</string>
|
||||
<string name="cordn_requests_check">Check for requests</string>
|
||||
<string name="cordn_requests_none">Nobody is waiting to join.</string>
|
||||
<string name="cordn_requests_accept">Add</string>
|
||||
<string name="cordn_requests_decline">Dismiss</string>
|
||||
<string name="cordn_requests_admin_only">Only an admin can accept. In a group with no admins, that is everyone.</string>
|
||||
<string name="cordn_requests_failed">Could not read the requests.</string>
|
||||
<string name="cordn_link_scan">Scan</string>
|
||||
<string name="cordn_share_title">Share this group</string>
|
||||
<string name="cordn_share_explainer">Anyone with this link can ask to join. An admin still has to let them in.</string>
|
||||
<string name="cordn_share_copy">Copy link</string>
|
||||
<string name="cordn_share_copied">Copied</string>
|
||||
<string name="cordn_coordinators_explainer">A coordinator orders one group\'s messages and is the only thing that can. Losing it loses the ordering, and a second one does not mirror the first — so these are named things you choose, not interchangeable relays.</string>
|
||||
<string name="cordn_coordinators_none">No coordinators yet.</string>
|
||||
<string name="cordn_coordinators_add_action">Add</string>
|
||||
<string name="cordn_coordinators_add_failed">Could not open that coordinator.</string>
|
||||
<string name="cordn_coordinators_label">A name for it (yours, optional)</string>
|
||||
<string name="cordn_coordinators_relays_label">Answers on</string>
|
||||
<string name="cordn_coordinators_key">Coordinator key</string>
|
||||
<string name="cordn_coordinators_copy_key">Copy the coordinator\'s npub</string>
|
||||
<string name="cordn_coordinators_more">More actions</string>
|
||||
<string name="cordn_coordinators_rename">Rename</string>
|
||||
<string name="cordn_coordinators_label_note">This name is yours and stays on this device. A coordinator cannot prove a name, so it is never asked for one.</string>
|
||||
<string name="cordn_coordinators_identify">Ask who it is</string>
|
||||
<string name="cordn_coordinators_server">Says it is: %1$s</string>
|
||||
<string name="cordn_coordinators_server_silent">Answered, but named nothing.</string>
|
||||
<string name="cordn_coordinators_server_claim">A coordinator\'s name and version are strings it chose. Its public key is the only thing that identifies it.</string>
|
||||
<string name="cordn_coordinators_health_ok">Answering.</string>
|
||||
<string name="cordn_coordinators_health_retrying">A call failed; retrying.</string>
|
||||
<string name="cordn_coordinators_health_down">Not answering — %1$d calls in a row have failed. Groups on it are not syncing.</string>
|
||||
<string name="cordn_coordinators_health_unknown">Nothing asked of it yet.</string>
|
||||
<string name="cordn_coordinators_remove">Remove</string>
|
||||
<string name="cordn_coordinators_purge">Purge</string>
|
||||
<string name="cordn_coordinators_purge_title">Purge this coordinator?</string>
|
||||
<string name="cordn_coordinators_purge_body">Removing keeps the groups on this device, so adding the coordinator back brings them with it. Purging deletes them: the group keys, the read positions and your key packages all go, and those groups can only be re-entered by a fresh invitation.\n\nThe coordinator is not told and keeps whatever it already had.</string>
|
||||
<string name="cordn_keypackages_explainer">Others can only add you to a cordn group by taking a key package you published to that coordinator. cordn has no other place to keep one, so with none published nobody can invite you — and nothing tells them why.</string>
|
||||
<plurals name="cordn_create_unreachable_count">
|
||||
<item quantity="one">%1$d person cannot be reached by any coordinator you use</item>
|
||||
<item quantity="other">%1$d people cannot be reached by any coordinator you use</item>
|
||||
</plurals>
|
||||
<plurals name="cordn_groups_count">
|
||||
<item quantity="one">%1$d group</item>
|
||||
<item quantity="other">%1$d groups</item>
|
||||
</plurals>
|
||||
<plurals name="cordn_create_reach_count">
|
||||
<item quantity="one">Reachable on %1$d coordinator</item>
|
||||
<item quantity="other">Reachable on %1$d coordinators</item>
|
||||
</plurals>
|
||||
<plurals name="cordn_create_admin_count">
|
||||
<item quantity="one">%1$d person can add and remove</item>
|
||||
<item quantity="other">%1$d people can add and remove</item>
|
||||
</plurals>
|
||||
<plurals name="cordn_create_action_invite">
|
||||
<item quantity="one">Create and invite %1$d person</item>
|
||||
<item quantity="other">Create and invite %1$d people</item>
|
||||
</plurals>
|
||||
<plurals name="cordn_member_count">
|
||||
<item quantity="one">%1$d member</item>
|
||||
<item quantity="other">%1$d members</item>
|
||||
</plurals>
|
||||
<plurals name="cordn_keypackages_summary">
|
||||
<item quantity="one">%1$d single-use package available.</item>
|
||||
<item quantity="other">%1$d single-use packages available.</item>
|
||||
</plurals>
|
||||
<string name="cordn_keypackages_last_resort_yes">A last-resort package is published, so an invitation can still be made once the single-use ones run out.</string>
|
||||
<string name="cordn_keypackages_last_resort_no">No last-resort package. Once the single-use ones run out, invitations fail.</string>
|
||||
<plurals name="cordn_keypackages_orphans">
|
||||
<item quantity="one">%1$d package this device cannot open</item>
|
||||
<item quantity="other">%1$d packages this device cannot open</item>
|
||||
</plurals>
|
||||
<string name="cordn_keypackages_orphans_body">The coordinator will hand these to anyone inviting you, but the private half is not on this device — it belongs to another install. If that install is gone, an invitation using one of these produces a welcome nobody can ever open.</string>
|
||||
<string name="cordn_keypackages_withdraw_orphans">Withdraw those</string>
|
||||
<string name="cordn_keypackages_disclosure">Publishing signs a record under your own account key. That coordinator then knows this account exists and is invitable — permanently, and whether or not anyone invites you.</string>
|
||||
<string name="cordn_keypackages_publish">Publish one</string>
|
||||
<string name="cordn_keypackages_publish_last_resort">Publish last-resort</string>
|
||||
<string name="cordn_keypackages_withdraw_all">Withdraw all</string>
|
||||
<string name="cordn_keypackages_topup_note">Once you have published here, Amethyst quietly replaces packages as they are used up. It never publishes the first one for you.</string>
|
||||
<string name="cordn_keypackages_failed">Could not read the key packages.</string>
|
||||
<!-- Buzz calls its groups channels, and a Buzz relay is one workspace rather than a directory of groups. -->
|
||||
<string name="buzz_channel_flag_forum">Forum channel</string>
|
||||
<string name="buzz_channel_flag_forum_desc">Threaded posts instead of a chat timeline. This cannot be changed later.</string>
|
||||
@@ -899,10 +655,6 @@
|
||||
|
||||
<!-- My Fitness: the signed-in user's own training summary. Android resource because
|
||||
NavBarItemDef labels are R.string ids. -->
|
||||
<plurals name="cordn_invitations_members">
|
||||
<item quantity="one">%1$d person is already in this group</item>
|
||||
<item quantity="other">%1$d people are already in this group</item>
|
||||
</plurals>
|
||||
<string name="private_message">Private Message</string>
|
||||
<string name="pow_kind_chat_message">Chat message</string>
|
||||
<string name="nest_notification_broadcasting">Nest — Live</string>
|
||||
@@ -931,326 +683,4 @@
|
||||
<string name="mute_button">Sound on. Click to mute</string>
|
||||
<string name="play">Play</string>
|
||||
<string name="pause">Pause</string>
|
||||
<string name="backup_conflict_title">You changed your %1$s in another app</string>
|
||||
<string name="backup_conflict_removed">Removed (%1$s)</string>
|
||||
<string name="backup_conflict_added">Added (%1$s)</string>
|
||||
<string name="backup_conflict_changed">Changed (%1$s)</string>
|
||||
<string name="backup_conflict_private_cleared">You removed all private (encrypted) items.</string>
|
||||
<string name="backup_conflict_private_changed">You also changed private (encrypted) items. They can\'t be compared here.</string>
|
||||
<string name="backup_conflict_private_added">You added private (encrypted) items.</string>
|
||||
<string name="backup_conflict_restore_mine">Restore saved version</string>
|
||||
<string name="backup_review_saved">On this device</string>
|
||||
<string name="backup_review_new">New version</string>
|
||||
<string name="backup_review_not_set">Not set</string>
|
||||
<string name="backup_conflict_count_removed">%1$s removed</string>
|
||||
<string name="backup_conflict_count_added">%1$s added</string>
|
||||
<string name="backup_conflict_count_changed">%1$s changed</string>
|
||||
<plurals name="backup_card_follows_dropped">
|
||||
<item quantity="one">You unfollowed %1$d person</item>
|
||||
<item quantity="other">You unfollowed %1$d people</item>
|
||||
</plurals>
|
||||
<string name="backup_card_accept">Accept</string>
|
||||
<string name="backup_review_title_updated">%1$s updated</string>
|
||||
<string name="backup_review_title_cleared">%1$s cleared</string>
|
||||
<string name="backup_review_changed_by_other_app">Changed in another app · %1$s</string>
|
||||
<string name="backup_action_keep_count">Keep %1$s</string>
|
||||
<string name="backup_action_restore_count">Restore %1$s</string>
|
||||
<string name="backup_action_remute">Re-mute %1$s</string>
|
||||
<string name="backup_action_rejoin">Rejoin %1$s</string>
|
||||
<string name="backup_action_restore_profile">Restore profile</string>
|
||||
<string name="backup_action_restore_relays">Restore relays</string>
|
||||
<string name="backup_review_kept_count">%1$s kept</string>
|
||||
<string name="backup_review_dropped_count">%1$s dropped</string>
|
||||
<string name="backup_review_new_count">%1$s new</string>
|
||||
<string name="backup_review_tab_dropped">Dropped · %1$s</string>
|
||||
<string name="backup_review_tab_new">New · %1$s</string>
|
||||
<string name="backup_review_tab_edited">Edited · %1$s</string>
|
||||
<string name="backup_review_search_people">Search %1$s people</string>
|
||||
<string name="backup_review_nothing_here">Nothing here</string>
|
||||
<string name="backup_review_unmuted">%1$s unmuted</string>
|
||||
<string name="backup_review_unmuted_explainer">These can reach your feeds again</string>
|
||||
<string name="backup_review_newly_muted">%1$s newly muted</string>
|
||||
<string name="backup_review_words_and_hashtags">Words & hashtags</string>
|
||||
<string name="backup_review_names_and_more">%1$s and %2$s more</string>
|
||||
<string name="backup_review_private_wiped_title">You removed all private items</string>
|
||||
<string name="backup_review_private_wiped_body">They\'re encrypted, so only you can see what they were. Restoring brings them all back.</string>
|
||||
<string name="backup_review_private_added_title">You made items private</string>
|
||||
<string name="backup_review_private_added_body">They\'re encrypted now, which is likely where the public items above went.</string>
|
||||
<string name="backup_review_private_changed_title">You changed private items</string>
|
||||
<string name="backup_review_private_changed_body">They\'re encrypted, so they can\'t be compared here.</string>
|
||||
<string name="backup_review_gone">Gone</string>
|
||||
<string name="backup_review_new_tag">New</string>
|
||||
<string name="backup_review_dropped_tag">Dropped</string>
|
||||
<string name="backup_review_demoted_tag">Moved</string>
|
||||
<string name="backup_review_units_tag">Units</string>
|
||||
<string name="backup_review_left_tag">Left</string>
|
||||
<string name="backup_review_renamed_tag">Renamed</string>
|
||||
<string name="backup_review_outbox">Outbox</string>
|
||||
<string name="backup_review_outbox_explainer">where you publish</string>
|
||||
<string name="backup_review_inbox">Inbox</string>
|
||||
<string name="backup_review_inbox_explainer">where others reach you</string>
|
||||
<string name="backup_review_key_replaced">Receiving key replaced</string>
|
||||
<string name="backup_review_key_removed">Receiving key removed</string>
|
||||
<string name="backup_review_key_warning">Nutzaps will be locked to this new key. If this device doesn\'t have it, you may not be able to redeem them here.</string>
|
||||
<string name="backup_review_left">left</string>
|
||||
<string name="backup_review_joined">joined</string>
|
||||
<string name="backup_review_renamed">renamed</string>
|
||||
<string name="backup_review_was_named">was “%1$s”</string>
|
||||
<string name="backup_action_block_again">Block %1$s again</string>
|
||||
<string name="backup_action_restore_feeds">Restore feeds</string>
|
||||
<string name="backup_action_restore_topics">Restore topics</string>
|
||||
<string name="backup_action_restore_places">Restore places</string>
|
||||
<string name="backup_action_restore_providers">Restore providers</string>
|
||||
<string name="backup_action_restore_wallet">Restore wallet</string>
|
||||
<string name="backup_review_kept">kept</string>
|
||||
<string name="backup_review_receiving_tag">Receiving</string>
|
||||
<string name="backup_review_listed_tag">Listed</string>
|
||||
<string name="backup_review_searching_tag">Searching</string>
|
||||
<string name="backup_review_storing_tag">Storing</string>
|
||||
<string name="backup_review_trusted_tag">Trusted</string>
|
||||
<string name="backup_review_untrusted_tag">Untrusted</string>
|
||||
<string name="backup_review_unblocked">%1$s unblocked</string>
|
||||
<string name="backup_review_unblocked_explainer">Amethyst will connect to them again</string>
|
||||
<string name="backup_review_no_longer_blocked">No longer blocked</string>
|
||||
<string name="backup_review_newly_blocked">Newly blocked</string>
|
||||
<string name="backup_review_still_blocked">Still blocked</string>
|
||||
<string name="backup_review_allowed_tag">Allowed</string>
|
||||
<string name="backup_review_moved_tag">Moved</string>
|
||||
<string name="backup_review_feed">Feed</string>
|
||||
<string name="backup_review_topics_gone">topics gone</string>
|
||||
<string name="backup_review_places_gone">places gone</string>
|
||||
<string name="backup_review_new_count_caption">new</string>
|
||||
<string name="backup_review_hashtags_you_follow">Hashtags you follow</string>
|
||||
<string name="backup_review_places_you_follow">Places you follow</string>
|
||||
<string name="backup_review_services_changed">%1$s of %2$s services changed</string>
|
||||
<string name="backup_review_services_changed_explainer">They now come from someone else, or no one</string>
|
||||
<string name="backup_review_service">Service</string>
|
||||
<string name="backup_review_service_rank">Rank</string>
|
||||
<string name="backup_review_service_followers">Followers</string>
|
||||
<string name="backup_review_service_topics">Topics</string>
|
||||
<string name="backup_review_trust_warning">Ranks, follower counts and spam filtering you see come from these providers.</string>
|
||||
<plurals name="backup_review_payment_targets_gone">
|
||||
<item quantity="one">%1$d way to pay you removed</item>
|
||||
<item quantity="other">%1$d ways to pay you removed</item>
|
||||
</plurals>
|
||||
<plurals name="backup_review_offers_gone">
|
||||
<item quantity="one">%1$d offer removed</item>
|
||||
<item quantity="other">%1$d offers removed</item>
|
||||
</plurals>
|
||||
<string name="backup_review_payments_explainer">People paying you only see what\'s in this list.</string>
|
||||
<string name="backup_review_offer">BOLT12 offer</string>
|
||||
<string name="backup_review_encrypted_cleared">You emptied it</string>
|
||||
<string name="backup_review_encrypted_added">You created it</string>
|
||||
<string name="backup_review_encrypted_changed">You changed it</string>
|
||||
<string name="backup_review_wallet_body">Your wallet\'s mints and keys are encrypted to you, so they can\'t be compared item by item here. Restoring puts back exactly what this device saved.</string>
|
||||
<string name="backup_review_concord_body">Your Concord communities are encrypted to you, so they can\'t be compared here. Restoring puts back exactly what this device saved.</string>
|
||||
<plurals name="backup_card_mutes_visible">
|
||||
<item quantity="one">You unmuted %1$d thing</item>
|
||||
<item quantity="other">You unmuted %1$d things</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_profile_lost_fields">
|
||||
<item quantity="one">You removed %1$d profile field</item>
|
||||
<item quantity="other">You removed %1$d profile fields</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_nip65_lost">
|
||||
<item quantity="one">You removed %1$d public relay</item>
|
||||
<item quantity="other">You removed %1$d public relays</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_dm_relays_lost">
|
||||
<item quantity="one">You removed %1$d DM relay</item>
|
||||
<item quantity="other">You removed %1$d DM relays</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_key_package_relays_lost">
|
||||
<item quantity="one">You removed %1$d group-chat key relay</item>
|
||||
<item quantity="other">You removed %1$d group-chat key relays</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_search_relays_lost">
|
||||
<item quantity="one">You removed %1$d search relay</item>
|
||||
<item quantity="other">You removed %1$d search relays</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_indexer_relays_lost">
|
||||
<item quantity="one">You removed %1$d indexer relay</item>
|
||||
<item quantity="other">You removed %1$d indexer relays</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_relay_feeds_lost">
|
||||
<item quantity="one">You removed %1$d relay feed</item>
|
||||
<item quantity="other">You removed %1$d relay feeds</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_private_outbox_lost">
|
||||
<item quantity="one">You removed %1$d private relay</item>
|
||||
<item quantity="other">You removed %1$d private relays</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trusted_lost">
|
||||
<item quantity="one">You stopped trusting %1$d relay</item>
|
||||
<item quantity="other">You stopped trusting %1$d relays</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_unblocked">
|
||||
<item quantity="one">You unblocked %1$d relay</item>
|
||||
<item quantity="other">You unblocked %1$d relays</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_chats">
|
||||
<item quantity="one">You left %1$d public chat</item>
|
||||
<item quantity="other">You left %1$d public chats</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_communities">
|
||||
<item quantity="one">You left %1$d community</item>
|
||||
<item quantity="other">You left %1$d communities</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_rooms">
|
||||
<item quantity="one">You left %1$d chat room</item>
|
||||
<item quantity="other">You left %1$d chat rooms</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_groups">
|
||||
<item quantity="one">You left %1$d group</item>
|
||||
<item quantity="other">You left %1$d groups</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_feeds_removed">
|
||||
<item quantity="one">You removed %1$d favorite feed</item>
|
||||
<item quantity="other">You removed %1$d favorite feeds</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_hashtags_unfollowed">
|
||||
<item quantity="one">You unfollowed %1$d hashtag</item>
|
||||
<item quantity="other">You unfollowed %1$d hashtags</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_places_unfollowed">
|
||||
<item quantity="one">You unfollowed %1$d place</item>
|
||||
<item quantity="other">You unfollowed %1$d places</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trust_services_changed">
|
||||
<item quantity="one">You changed the provider of %1$d trust service</item>
|
||||
<item quantity="other">You changed the provider of %1$d trust services</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_nutzap_mints_removed">
|
||||
<item quantity="one">You removed %1$d nutzap mint</item>
|
||||
<item quantity="other">You removed %1$d nutzap mints</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_payment_targets_removed">
|
||||
<item quantity="one">You removed %1$d way to get paid</item>
|
||||
<item quantity="other">You removed %1$d ways to get paid</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_offers_removed">
|
||||
<item quantity="one">You removed %1$d BOLT12 offer</item>
|
||||
<item quantity="other">You removed %1$d BOLT12 offers</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_added">
|
||||
<item quantity="one">%1$s and added %2$d</item>
|
||||
<item quantity="other">%1$s and added %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_followed">
|
||||
<item quantity="one">%1$s and followed %2$d</item>
|
||||
<item quantity="other">%1$s and followed %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_muted">
|
||||
<item quantity="one">%1$s and muted %2$d</item>
|
||||
<item quantity="other">%1$s and muted %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_joined">
|
||||
<item quantity="one">%1$s and joined %2$d</item>
|
||||
<item quantity="other">%1$s and joined %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_blocked">
|
||||
<item quantity="one">%1$s and blocked %2$d</item>
|
||||
<item quantity="other">%1$s and blocked %2$d</item>
|
||||
</plurals>
|
||||
<string name="backup_card_app_settings">Your Amethyst synced app settings changed in another app that is not Amethyst. This can create problems.</string>
|
||||
<string name="backup_card_nutzap_key_replaced">You replaced your nutzap key</string>
|
||||
<string name="backup_card_nutzap_key_removed">You removed your nutzap key</string>
|
||||
<string name="backup_card_wallet_emptied">You emptied your Cashu wallet</string>
|
||||
<string name="backup_card_wallet_rewritten">You changed your Cashu wallet</string>
|
||||
<string name="backup_card_concord_emptied">You emptied your Concord list</string>
|
||||
<string name="backup_card_concord_rewritten">You changed your Concord list</string>
|
||||
<string name="backup_conflict_keep_new">Use new version</string>
|
||||
<string name="backup_conflict_relay_read_only">read only</string>
|
||||
<string name="backup_conflict_relay_write_only">write only</string>
|
||||
<string name="backup_conflict_relay_read_write">read and write</string>
|
||||
<string name="backup_type_profile">profile</string>
|
||||
<string name="backup_type_profile_explainer">Your name, picture, bio and payment addresses, as everyone sees them.</string>
|
||||
<string name="backup_type_follow_list">follow list</string>
|
||||
<string name="backup_type_follow_list_explainer">Decides whose posts appear in your home feed.</string>
|
||||
<string name="backup_type_mute_list">mute list</string>
|
||||
<string name="backup_type_mute_list_explainer">Hides people, words, hashtags and threads from everything you see.</string>
|
||||
<string name="backup_type_outbox_inbox_relays">public relay list</string>
|
||||
<string name="backup_type_outbox_inbox_relays_explainer">Tells everyone where to find your posts and where to send you replies and mentions.</string>
|
||||
<string name="backup_type_dm_relays">DM relay list</string>
|
||||
<string name="backup_type_dm_relays_explainer">Where others deliver your private messages.</string>
|
||||
<string name="backup_type_key_package_relays">group-chat key relays</string>
|
||||
<string name="backup_type_key_package_relays_explainer">Where others find the keys to add you to encrypted group chats.</string>
|
||||
<string name="backup_type_search_relays">search relay list</string>
|
||||
<string name="backup_type_search_relays_explainer">The relays used when you search.</string>
|
||||
<string name="backup_type_indexer_relays">indexer relay list</string>
|
||||
<string name="backup_type_indexer_relays_explainer">The relays used to find other people\'s profiles and relay lists.</string>
|
||||
<string name="backup_type_relay_feeds">favorite relay feeds</string>
|
||||
<string name="backup_type_relay_feeds_explainer">The relays you browse as feeds.</string>
|
||||
<string name="backup_type_blocked_relays">blocked relay list</string>
|
||||
<string name="backup_type_blocked_relays_explainer">Relays this app never connects to.</string>
|
||||
<string name="backup_type_trusted_relays">trusted relay list</string>
|
||||
<string name="backup_type_trusted_relays_explainer">Relays you trust to connect to without asking.</string>
|
||||
<string name="backup_type_private_outbox_relays">private relay list</string>
|
||||
<string name="backup_type_private_outbox_relays_explainer">Where your drafts and private data are stored.</string>
|
||||
<string name="backup_type_app_settings">synced app settings</string>
|
||||
<string name="backup_type_app_settings_explainer">Amethyst settings synced across your devices. They are encrypted, so only their presence can be compared.</string>
|
||||
<string name="backup_type_public_chats">public chat list</string>
|
||||
<string name="backup_type_public_chats_explainer">The public chats you joined.</string>
|
||||
<string name="backup_type_communities">community list</string>
|
||||
<string name="backup_type_communities_explainer">The communities you joined.</string>
|
||||
<string name="backup_type_hashtags">followed hashtags</string>
|
||||
<string name="backup_type_hashtags_explainer">Hashtags whose posts appear in your feeds.</string>
|
||||
<string name="backup_type_geohashes">followed locations</string>
|
||||
<string name="backup_type_geohashes_explainer">Locations whose posts appear in your feeds.</string>
|
||||
<string name="backup_type_favorite_algo_feeds">favorite feeds list</string>
|
||||
<string name="backup_type_favorite_algo_feeds_explainer">The algorithmic feeds you saved.</string>
|
||||
<string name="backup_type_ephemeral_chats">ephemeral chat list</string>
|
||||
<string name="backup_type_ephemeral_chats_explainer">The ephemeral chat rooms you joined.</string>
|
||||
<string name="backup_type_relay_groups">group list</string>
|
||||
<string name="backup_type_relay_groups_explainer">The relay-based groups you joined.</string>
|
||||
<string name="backup_type_concord_communities">Concord community list</string>
|
||||
<string name="backup_type_concord_communities_explainer">The Concord communities you joined. They are encrypted, so only their presence can be compared.</string>
|
||||
<string name="backup_type_trust_providers">trust provider list</string>
|
||||
<string name="backup_type_trust_providers_explainer">The services you trust to rank and verify people for you.</string>
|
||||
<string name="backup_type_cashu_wallet">Cashu wallet</string>
|
||||
<string name="backup_type_cashu_wallet_explainer">Your ecash wallet settings and mints. They are encrypted, so only their presence can be compared.</string>
|
||||
<string name="backup_type_nutzap_info">nutzap receiving settings</string>
|
||||
<string name="backup_type_nutzap_info_explainer">The mints and key others use to send you nutzaps.</string>
|
||||
<string name="backup_type_payment_targets">payment addresses</string>
|
||||
<string name="backup_type_payment_targets_explainer">The ways other people can pay you.</string>
|
||||
<string name="backup_type_bolt12_offers">BOLT12 offers</string>
|
||||
<string name="backup_type_bolt12_offers_explainer">The lightning offers others use to pay you.</string>
|
||||
<string name="backup_type_other">list</string>
|
||||
<string name="backup_type_other_explainer">A list saved on this device.</string>
|
||||
<string name="backup_entry_profile_field">Profile fields</string>
|
||||
<string name="backup_entry_person">People</string>
|
||||
<string name="backup_entry_hashtag">Hashtags</string>
|
||||
<string name="backup_entry_word">Words</string>
|
||||
<string name="backup_entry_thread">Threads</string>
|
||||
<string name="backup_entry_public_chat">Public chats</string>
|
||||
<string name="backup_entry_community">Communities</string>
|
||||
<string name="backup_entry_algo_feed">Feeds</string>
|
||||
<string name="backup_entry_location">Locations</string>
|
||||
<string name="backup_entry_relay">Relays</string>
|
||||
<string name="backup_entry_relay_group">Groups</string>
|
||||
<string name="backup_entry_chat_room">Chat rooms</string>
|
||||
<string name="backup_entry_trust_provider">Trust providers</string>
|
||||
<string name="backup_entry_mint">Mints</string>
|
||||
<string name="backup_entry_nutzap_key">Nutzap keys</string>
|
||||
<string name="backup_entry_payment_target">Payment addresses</string>
|
||||
<string name="backup_entry_offer">Offers</string>
|
||||
<string name="backup_entry_identity_claim">Linked identities</string>
|
||||
<string name="backup_entry_other">Other entries</string>
|
||||
<string name="backup_profile_field_name">Username</string>
|
||||
<string name="backup_profile_field_display_name">Display name</string>
|
||||
<string name="backup_profile_field_about">About</string>
|
||||
<string name="backup_profile_field_picture">Picture</string>
|
||||
<string name="backup_profile_field_banner">Banner</string>
|
||||
<string name="backup_profile_field_website">Website</string>
|
||||
<string name="backup_profile_field_nip05">Nostr address</string>
|
||||
<string name="backup_profile_field_lud16">Lightning address</string>
|
||||
<string name="backup_profile_field_lud06">LNURL</string>
|
||||
<string name="backup_profile_field_pronouns">Pronouns</string>
|
||||
<string name="backup_profile_field_birthday">Birthday</string>
|
||||
<string name="backup_profile_field_clink_offer">CLINK offer</string>
|
||||
<string name="backup_profile_field_bot">Bot flag</string>
|
||||
<plurals name="cordn_info_admins_kept">
|
||||
<item quantity="one">The group\'s %1$d admin stays as it is.</item>
|
||||
<item quantity="other">The group\'s %1$d admins stay as they are.</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -58,7 +58,10 @@ is specific to the UI module.
|
||||
`tools/icon-font/build_icon_font.py` read `icons/` and write
|
||||
`composeResources/font/` in this module (see root `.claude/CLAUDE.md`, "Icons").
|
||||
- Translations: `crowdin.yml` and `tools/strings-migrate/` target
|
||||
`commonsUI/src/commonMain/composeResources/`.
|
||||
`commonsUI/src/commonMain/composeResources/`. This is where **every new
|
||||
user-visible string** goes, Android-only screens included; the app's own
|
||||
`res/values/strings.xml` holds only the synchronous-platform tier (see root
|
||||
`.claude/CLAUDE.md`, "Strings").
|
||||
- CI: `.github/workflows/build.yml` runs `:commonsUI:jvmTest`,
|
||||
`:commonsUI:verifyKmpPurity` and the iOS compile/test tasks next to the
|
||||
`:commons` ones.
|
||||
|
||||
@@ -5286,4 +5286,322 @@
|
||||
<string name="cyberspace_bag_unsigned">हस्ताक्षररहित। इसलिए यह कर्ता केवल एक कथन है</string>
|
||||
<string name="cyberspace_bag_unknown_kind">प्रकार %1$d का वस्तु। जिसे यह ग्राहक चित्रित नहीं करता</string>
|
||||
<string name="cyberspace_bag_opaque">%1$d अष्टकों का अमुक जिसे यह ग्राहक पढता नहीं</string>
|
||||
<string name="backup_action_block_again">पुनःबाधित करें %1$s को</string>
|
||||
<string name="backup_action_keep_count">रखें %1$s</string>
|
||||
<string name="backup_action_rejoin">पुनःजुडें %1$s</string>
|
||||
<string name="backup_action_remute">पुनःमौन %1$s</string>
|
||||
<string name="backup_action_restore_count">पुनःस्थापन %1$s</string>
|
||||
<string name="backup_action_restore_feeds">सूचनावलियाँ पुनःस्थापन</string>
|
||||
<string name="backup_action_restore_places">स्थल पुनःस्थापन</string>
|
||||
<string name="backup_action_restore_profile">परिचय पुनःस्थापध</string>
|
||||
<string name="backup_action_restore_providers">प्रदाता पुनःस्थापन</string>
|
||||
<string name="backup_action_restore_relays">पुनःप्रसारक पुनःस्थापन</string>
|
||||
<string name="backup_action_restore_topics">विषय पुनःस्थापन</string>
|
||||
<string name="backup_action_restore_wallet">धनकोष पुनःस्थापन</string>
|
||||
<string name="backup_card_accept">स्वीकार</string>
|
||||
<plurals name="backup_card_and_added">
|
||||
<item quantity="one">%1$s तथा %2$d जोडा</item>
|
||||
<item quantity="other">%1$s तथा %2$d जोडे</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_blocked">
|
||||
<item quantity="one">%1$s तथा %2$d बाधित किया</item>
|
||||
<item quantity="other">%1$s तथा %2$d को बाधित किए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_followed">
|
||||
<item quantity="one">%1$s तथा %2$d का अनुगमन किया</item>
|
||||
<item quantity="other">%1$s तथा %2$d का अनुगमन किए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_joined">
|
||||
<item quantity="one">%1$s तथा %2$d से जुडे</item>
|
||||
<item quantity="other">%1$s तथा %2$d से जुडे</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_muted">
|
||||
<item quantity="one">%1$s तथा %2$d को मौनकृत किया</item>
|
||||
<item quantity="other">%1$s तथा %2$d को मौनकृत किए</item>
|
||||
</plurals>
|
||||
<string name="backup_card_app_settings">आपके अमेथिस्ट समचरणीकृत क्रमक स्थापना विकल्पों को परिवर्तित किया गया एक अन्य क्रमक में और वह अमेथिस्ट नहीं था। इससे समस्याएँ उत्पन्न हो सकते हैं।</string>
|
||||
<string name="backup_card_concord_emptied">आपने अपनी कोंकोर्ड सूची रिक्त की</string>
|
||||
<string name="backup_card_concord_rewritten">आपने अपनी कोंकोर्ड सूची का परिवर्तन किया</string>
|
||||
<plurals name="backup_card_dm_relays_lost">
|
||||
<item quantity="one">आपने %1$d सीधासन्देश पुनःप्रसारक हटाया</item>
|
||||
<item quantity="other">आपने %1$d सीधासन्देश पुनःप्रसारकों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_feeds_removed">
|
||||
<item quantity="one">आपने %1$d इष्ट सूचनावली हटाया</item>
|
||||
<item quantity="other">आपने %1$d इष्ट सूचनावलियों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_follows_dropped">
|
||||
<item quantity="one">आपने %1$d व्यक्ति का अनुगमन हटाया</item>
|
||||
<item quantity="other">आपने %1$d व्यक्तियों का अनुगमन हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_hashtags_unfollowed">
|
||||
<item quantity="one">आपने %1$d विषयसूचक का अनुगमन हटाया</item>
|
||||
<item quantity="other">आपने %1$d विषयसूचकों का अनुगमन हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_indexer_relays_lost">
|
||||
<item quantity="one">आपने %1$d अनुक्रमणीकार पुनःप्रसारक हटाया</item>
|
||||
<item quantity="other">आपने %1$d अनुक्रमणीकार पुनःप्रसारकों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_key_package_relays_lost">
|
||||
<item quantity="one">आपने %1$d समूहचर्चा कुंचिका पुनःप्रसारक हटाया</item>
|
||||
<item quantity="other">आपने %1$d समूहचर्चा कुंचिका पुनःप्रसारकों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_chats">
|
||||
<item quantity="one">आपने %1$d सार्वजनिक चर्चा छोड दिया</item>
|
||||
<item quantity="other">आपने %1$d सार्वजनिक चर्चाओं को छोड दिए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_communities">
|
||||
<item quantity="one">आपने %1$d समुदाय छोड दिया</item>
|
||||
<item quantity="other">आपने %1$d समुदायों को छोड दिए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_groups">
|
||||
<item quantity="one">आपने %1$d समूह छोड दिया</item>
|
||||
<item quantity="other">आपने %1$d समूहों को छोड दिए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_rooms">
|
||||
<item quantity="one">आपने %1$d चर्चाशाला छोड दिया</item>
|
||||
<item quantity="other">आपने %1$d चर्चाशालाओं को छोड दिए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_mutes_visible">
|
||||
<item quantity="one">आपने %1$d की मौनावस्था हटाया</item>
|
||||
<item quantity="other">आपने %1$d की मौनावस्था हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_nip65_lost">
|
||||
<item quantity="one">आपने %1$d सार्वजनिक पुनःप्रसारक हटाया</item>
|
||||
<item quantity="other">आपने %1$d सार्वजनिक पुनःप्रसारकों को हटाए</item>
|
||||
</plurals>
|
||||
<string name="backup_card_nutzap_key_removed">आपने अपनी नटज्साप कुंचिका को हटाया</string>
|
||||
<string name="backup_card_nutzap_key_replaced">आपने अपनी नटज्साप कुंचिका का प्रतिस्थापन किया</string>
|
||||
<plurals name="backup_card_nutzap_mints_removed">
|
||||
<item quantity="one">आपने %1$d नटज्साप टकसाल हटाया</item>
|
||||
<item quantity="other">आपने %1$d नटज्साप टकसालों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_offers_removed">
|
||||
<item quantity="one">आपने %1$d बोल्ट॰बारह प्रस्ताव हटाया</item>
|
||||
<item quantity="other">आपने %1$d बोल्ट॰बारह प्रस्तावों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_payment_targets_removed">
|
||||
<item quantity="one">आपने %1$d भुगतान प्राप्त करने की विधि हटाया</item>
|
||||
<item quantity="other">आपने %1$d भुगतान प्राप्त करने के विधियों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_places_unfollowed">
|
||||
<item quantity="one">आपने %1$d स्थल का अनुगमन हटाया</item>
|
||||
<item quantity="other">आपने %1$d स्थलों का अनुगमन हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_private_outbox_lost">
|
||||
<item quantity="one">आपने %1$d निजी पुनःप्रसारक हटाया</item>
|
||||
<item quantity="other">आपने %1$d निजी पुनःप्रसारकों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_profile_lost_fields">
|
||||
<item quantity="one">आपने %1$d परिचय प्रपत्रस्थान हटाया</item>
|
||||
<item quantity="other">आपने %1$d परिचय प्रपत्रस्थान हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_relay_feeds_lost">
|
||||
<item quantity="one">आपने %1$d पुनःप्रसारक सूचनावली हटाया</item>
|
||||
<item quantity="other">आपने %1$d पुनःप्रसारक सूचनावलियाँ हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_search_relays_lost">
|
||||
<item quantity="one">आपने %1$d खोज पुनःप्रसारक हटाया</item>
|
||||
<item quantity="other">आपने %1$d खोज पुनःप्रसारकों को हटाए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trust_services_changed">
|
||||
<item quantity="one">आपने %1$d विश्वाससेवा प्रदाता परिवर्तित किया</item>
|
||||
<item quantity="other">आपने %1$d विश्वाससेवाओं के प्रदाता को परिवर्तित किया</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trusted_lost">
|
||||
<item quantity="one">आपने %1$d पुनःप्रसारक पर विश्वास करना रोक दिया</item>
|
||||
<item quantity="other">आपने %1$d पुनःप्रसारकों पर विश्वास करना रोक दिए</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_unblocked">
|
||||
<item quantity="one">आपने %1$d पुनःप्रसारक अबाधित किया</item>
|
||||
<item quantity="other">आपने %1$d पुनःप्रसारकों को अबाधित किए</item>
|
||||
</plurals>
|
||||
<string name="backup_card_wallet_emptied">आपने अपना काशयू धनकोष रिक्त किया</string>
|
||||
<string name="backup_card_wallet_rewritten">आपने अपने काशयू धनकोष को परिवर्तित किया</string>
|
||||
<string name="backup_conflict_added">जोडे गए (%1$s)</string>
|
||||
<string name="backup_conflict_changed">परिवर्तित (%1$s)</string>
|
||||
<string name="backup_conflict_count_added">%1$s जोडे गए</string>
|
||||
<string name="backup_conflict_count_changed">%1$s परिवर्तित</string>
|
||||
<string name="backup_conflict_count_removed">%1$s हटाए गए</string>
|
||||
<string name="backup_conflict_keep_new">नया संस्करण का उपयोग करें</string>
|
||||
<string name="backup_conflict_private_added">आपने निजी (रहस्यीकृत) वस्तुओं को जोडा।</string>
|
||||
<string name="backup_conflict_private_changed">आपने निजी (रहस्यीकृत) वस्तुओं का परिवर्तन भी किया। उनकी तुलना यहाँ नहीं की जा सकती।</string>
|
||||
<string name="backup_conflict_private_cleared">आपने सभी निजी (रहस्यीकृत) वस्तुओं को हटा दिया।</string>
|
||||
<string name="backup_conflict_relay_read_only">पठनेवशक्य</string>
|
||||
<string name="backup_conflict_relay_read_write">पठन तथा लेखन</string>
|
||||
<string name="backup_conflict_relay_write_only">लेखनेवशक्य</string>
|
||||
<string name="backup_conflict_removed">हटाए गए (%1$s)</string>
|
||||
<string name="backup_conflict_restore_mine">सुरक्षित संस्करण पुनःस्थापन</string>
|
||||
<string name="backup_conflict_title">आपने अपना %1$s अन्य क्रमक में परिवर्तित किया</string>
|
||||
<string name="backup_entry_algo_feed">सूचनावलियाँ</string>
|
||||
<string name="backup_entry_chat_room">चर्चा शालाएँ</string>
|
||||
<string name="backup_entry_community">समुदाय</string>
|
||||
<string name="backup_entry_hashtag">विषयसूचक</string>
|
||||
<string name="backup_entry_identity_claim">सम्बन्धित व्यक्तिगण</string>
|
||||
<string name="backup_entry_location">स्थान</string>
|
||||
<string name="backup_entry_mint">टकसाल</string>
|
||||
<string name="backup_entry_nutzap_key">नटज्साप कुंचिकाएँ</string>
|
||||
<string name="backup_entry_offer">प्रस्ताव</string>
|
||||
<string name="backup_entry_other">अन्य प्रविष्टियाँ</string>
|
||||
<string name="backup_entry_payment_target">भुगतान पते</string>
|
||||
<string name="backup_entry_person">लोग</string>
|
||||
<string name="backup_entry_profile_field">परिचय प्रपत्रस्थान</string>
|
||||
<string name="backup_entry_public_chat">सार्वजनिक चर्चाएँ</string>
|
||||
<string name="backup_entry_relay">पुनःप्रसारक</string>
|
||||
<string name="backup_entry_relay_group">समूह</string>
|
||||
<string name="backup_entry_thread">सूत्र</string>
|
||||
<string name="backup_entry_trust_provider">विश्वाससेवा प्रदाता</string>
|
||||
<string name="backup_entry_word">शब्द</string>
|
||||
<string name="backup_profile_field_about">जानकारी</string>
|
||||
<string name="backup_profile_field_banner">ध्वज</string>
|
||||
<string name="backup_profile_field_birthday">जन्मदिन</string>
|
||||
<string name="backup_profile_field_bot">क्रमचर चिह्न</string>
|
||||
<string name="backup_profile_field_clink_offer">क्लिंक॰ प्रस्ताव</string>
|
||||
<string name="backup_profile_field_display_name">प्रदर्शन नाम</string>
|
||||
<string name="backup_profile_field_lud06">लैटनिंग जालपता</string>
|
||||
<string name="backup_profile_field_lud16">लैटनिंग पता</string>
|
||||
<string name="backup_profile_field_name">प्रयोक्तानाम</string>
|
||||
<string name="backup_profile_field_nip05">नोस्टर पता</string>
|
||||
<string name="backup_profile_field_picture">चित्र</string>
|
||||
<string name="backup_profile_field_pronouns">सर्वनाम</string>
|
||||
<string name="backup_profile_field_website">जालस्थान</string>
|
||||
<string name="backup_review_allowed_tag">अनुमत</string>
|
||||
<string name="backup_review_changed_by_other_app">अन्य क्रमक में परिवर्तित। %1$s</string>
|
||||
<string name="backup_review_concord_body">आपके कोंकोर्ड समुदाय आपके लिए रहस्यीकृत हैं। इसलिए उनकी तुलना यहाँ नहीं की जा सकती। पुनःस्थापन उन्हीं को लौट डालेगा जिनका अभिलेखन इस यन्त्र ने किया।</string>
|
||||
<string name="backup_review_demoted_tag">स्थानान्तरित</string>
|
||||
<string name="backup_review_dropped_count">%1$s परित्यक्त</string>
|
||||
<string name="backup_review_dropped_tag">परित्यक्त</string>
|
||||
<string name="backup_review_encrypted_added">आपने उसे बनाया</string>
|
||||
<string name="backup_review_encrypted_changed">आपने उसे परिवर्तित किया</string>
|
||||
<string name="backup_review_encrypted_cleared">आपने उसे रिक्त किया</string>
|
||||
<string name="backup_review_feed">सूचनावली</string>
|
||||
<string name="backup_review_gone">चला गया</string>
|
||||
<string name="backup_review_hashtags_you_follow">विषयसूचक जिनका आप अनुगमन करते हैं</string>
|
||||
<string name="backup_review_inbox">आगतपेटिका</string>
|
||||
<string name="backup_review_inbox_explainer">जहाँ अन्य आप तक अभिगमन करते हैं</string>
|
||||
<string name="backup_review_joined">जुड गए</string>
|
||||
<string name="backup_review_kept">रखे गए</string>
|
||||
<string name="backup_review_kept_count">%1$s रखे गए</string>
|
||||
<string name="backup_review_key_removed">ग्राहक कुंचिका हटाया गया</string>
|
||||
<string name="backup_review_key_replaced">ग्राहक कुंचिका प्रतिस्थापित</string>
|
||||
<string name="backup_review_key_warning">नटज्साप आगे से इस कुंचिका से बद्ध होंगे। यदि इस यन्त्र में वह नहीं है तो आप सम्भाव्यतः उनको यहाँ नहीं चुका सकते।</string>
|
||||
<string name="backup_review_left">शेष</string>
|
||||
<string name="backup_review_left_tag">शेष</string>
|
||||
<string name="backup_review_listed_tag">सूचीबद्ध</string>
|
||||
<string name="backup_review_moved_tag">स्थानान्तरित</string>
|
||||
<string name="backup_review_names_and_more">%1$s तथा %2$s अधिक</string>
|
||||
<string name="backup_review_new">नया संस्करण</string>
|
||||
<string name="backup_review_new_count">%1$s नए</string>
|
||||
<string name="backup_review_new_count_caption">नव्य</string>
|
||||
<string name="backup_review_new_tag">नव्य</string>
|
||||
<string name="backup_review_newly_blocked">नव्यतः बाधित</string>
|
||||
<string name="backup_review_newly_muted">%1$s नए मौनकृत</string>
|
||||
<string name="backup_review_no_longer_blocked">अब से बाधित नहीं</string>
|
||||
<string name="backup_review_not_set">स्थापित नहीं</string>
|
||||
<string name="backup_review_nothing_here">यहाँ कुछ नहीं</string>
|
||||
<string name="backup_review_offer">बोल्ट॰बारह प्रस्ताव</string>
|
||||
<plurals name="backup_review_offers_gone">
|
||||
<item quantity="one">%1$d प्रस्ताव हटाया गया</item>
|
||||
<item quantity="other">%1$d प्रस्ताव हटाए गए</item>
|
||||
</plurals>
|
||||
<string name="backup_review_outbox">निर्गतपेटिका</string>
|
||||
<string name="backup_review_outbox_explainer">आप जहाँ प्रकाशित करते हैं</string>
|
||||
<plurals name="backup_review_payment_targets_gone">
|
||||
<item quantity="one">आपको भुगतान करने की %1$d विधि हटाया गया</item>
|
||||
<item quantity="other">आपको भुगतान करने की %1$d विधियाँ हटाए गए</item>
|
||||
</plurals>
|
||||
<string name="backup_review_payments_explainer">लोग जो आपको भुगतान करते हैं उसी को देखते हैं जो इस सूची में है।</string>
|
||||
<string name="backup_review_places_gone">स्थल हटाए गए</string>
|
||||
<string name="backup_review_places_you_follow">स्थल जिनका आप अनुगमन करते हैं</string>
|
||||
<string name="backup_review_private_added_body">वे अब रहस्यीकृत हैं। जो कि सम्भाव्यतः ऊपर के सार्वजनिक वस्तुओं का गन्तव्य था।</string>
|
||||
<string name="backup_review_private_added_title">आपने वस्तुओं को निजी किया</string>
|
||||
<string name="backup_review_private_changed_body">वे रहस्यीकृत हैं। इसलिए उनकी तुलना यहाँ नहीं की जा सकती।</string>
|
||||
<string name="backup_review_private_changed_title">आपने निजी वस्तुओं का परिवर्तन किया</string>
|
||||
<string name="backup_review_private_wiped_body">वे रहस्यीकृत हैं। इसलिए केवल आप देख सकते हैं कि वे क्या थे। पुनःस्थापन से सब लौटके आ जाएँगे।</string>
|
||||
<string name="backup_review_private_wiped_title">आपने सभी निजी वस्तुओं को हटा दिया</string>
|
||||
<string name="backup_review_receiving_tag">ग्रहण मध्य</string>
|
||||
<string name="backup_review_renamed">पुनःनामकृत</string>
|
||||
<string name="backup_review_renamed_tag">पुनःनामकृत</string>
|
||||
<string name="backup_review_saved">इस यन्त्र पर</string>
|
||||
<string name="backup_review_search_people">%1$s लोग खोजें</string>
|
||||
<string name="backup_review_searching_tag">खोज मध्य</string>
|
||||
<string name="backup_review_service">सेवा</string>
|
||||
<string name="backup_review_service_followers">अनुचर</string>
|
||||
<string name="backup_review_service_rank">श्रेणी</string>
|
||||
<string name="backup_review_service_topics">विषयसूची</string>
|
||||
<string name="backup_review_services_changed">%2$s में से %1$s सेवाएँ परिवर्तित</string>
|
||||
<string name="backup_review_services_changed_explainer">वे अब अन्य व्यक्ति से आते है। अथवा किसी से नहीं</string>
|
||||
<string name="backup_review_still_blocked">अभी भी बाधित</string>
|
||||
<string name="backup_review_storing_tag">अभिलेखन मध्य</string>
|
||||
<string name="backup_review_tab_dropped">परित्यक्त। %1$s</string>
|
||||
<string name="backup_review_tab_edited">सम्पादित। %1$s</string>
|
||||
<string name="backup_review_tab_new">नए। %1$s</string>
|
||||
<string name="backup_review_title_cleared">%1$s पारित</string>
|
||||
<string name="backup_review_title_updated">%1$s अद्यतनकृत</string>
|
||||
<string name="backup_review_topics_gone">विषय हटाए गए</string>
|
||||
<string name="backup_review_trust_warning">श्रेणीयाँ तथा अनुचर गिनती तथा कचरालेख छालन जो आप देखते हैं इन प्रदाताओं से आते हैं।</string>
|
||||
<string name="backup_review_trusted_tag">विश्वसनीय</string>
|
||||
<string name="backup_review_unblocked">%1$s अबाधित</string>
|
||||
<string name="backup_review_unblocked_explainer">अमेथिस्ट पुनः उनसे जुडेगा</string>
|
||||
<string name="backup_review_units_tag">इकाई</string>
|
||||
<string name="backup_review_unmuted">%1$s मौनावस्था हटाए गए</string>
|
||||
<string name="backup_review_unmuted_explainer">ये पुनः आपके सूचनावलियों तक अभिगम्य</string>
|
||||
<string name="backup_review_untrusted_tag">अविश्वसनीय</string>
|
||||
<string name="backup_review_wallet_body">आपके धनकोष के टकसाल तथा कुंचिकाएँ आपके लिए रहस्यीकृत हैं। इसलिए उनकी तुलना वस्तु प्रति वस्तु यहाँ नहीं की जा सकती। पुनःस्थापन उन्हीं को लौट डालेगा जिनका अभिलेखन इस यन्त्र ने किया।</string>
|
||||
<string name="backup_review_was_named">पूर्वतः %1$s था</string>
|
||||
<string name="backup_review_words_and_hashtags">शब्द तथा विषयसूचक</string>
|
||||
<string name="backup_type_app_settings">समचरणीकृत क्रमक स्थापना विकल्प</string>
|
||||
<string name="backup_type_app_settings_explainer">अमेथिस्ट स्थापना विकल्प समचरणीकृत आपके यन्त्रों में। वे रहस्यीकृत हैं। इसलिए केवल उनकी उपस्थिति की तुलना की जा सकती है।</string>
|
||||
<string name="backup_type_blocked_relays">बाधित पुनःप्रसारक सूची</string>
|
||||
<string name="backup_type_blocked_relays_explainer">पुनःप्रसारक जिनसे यह क्रमक कभी भी संयोजन नहीं करता।</string>
|
||||
<string name="backup_type_bolt12_offers">बोल्ट॰बारह प्रस्ताव</string>
|
||||
<string name="backup_type_bolt12_offers_explainer">लैटनिंग प्रस्ताव जिनका उपयोग करके अन्य लोग आपको भुगतान करते हैं।</string>
|
||||
<string name="backup_type_cashu_wallet">काशयू धनकोष</string>
|
||||
<string name="backup_type_cashu_wallet_explainer">आपके ईकाश धनकोष स्थापना विकल्प तथा टकसाल। वे रहस्यीकृत हैं। इसलिए केवल उनकी उपस्थिति की तुलना की जा सकती है।</string>
|
||||
<string name="backup_type_communities">समुदाय सूची</string>
|
||||
<string name="backup_type_communities_explainer">समुदाय जिनसे आप जुडे।</string>
|
||||
<string name="backup_type_concord_communities">कोंकोर्ड समुदाय सूची</string>
|
||||
<string name="backup_type_concord_communities_explainer">कोंकोर्ड समुदाय जिनसे आप जुडे। वे रहस्यीकृत हैं। इसलिए केवल उनकी उपस्थिति की तुलना की जा सकती है।</string>
|
||||
<string name="backup_type_dm_relays">सीधासन्देश पुनःप्रसारक सूची</string>
|
||||
<string name="backup_type_dm_relays_explainer">जहाँ अन्य आपके निजी सन्देश भेजते हैं।</string>
|
||||
<string name="backup_type_ephemeral_chats">अस्थायी चर्चा सूची</string>
|
||||
<string name="backup_type_ephemeral_chats_explainer">अस्थायी चर्चा शालाएँ जिनसे आप जुडे।</string>
|
||||
<string name="backup_type_favorite_algo_feeds">इष्ट सूचनावली सूची</string>
|
||||
<string name="backup_type_favorite_algo_feeds_explainer">कलनविध्यात्मक सूचनावलियाँ जिनको आपने अभिलेखित किया।</string>
|
||||
<string name="backup_type_follow_list">अनुचरण सूची</string>
|
||||
<string name="backup_type_follow_list_explainer">निर्णय करता है किसके पत्र आपकी मुख्य सूचनावली में प्रकट होंगे।</string>
|
||||
<string name="backup_type_geohashes">अनुचरित स्थान</string>
|
||||
<string name="backup_type_geohashes_explainer">स्थान जहाँ से पत्र आपकी मुख्य सूचनावली में प्रकट होंगे।</string>
|
||||
<string name="backup_type_hashtags">अनुचरित विषयसूचक</string>
|
||||
<string name="backup_type_hashtags_explainer">विषयसूचक जिससे युक्त पत्र आपकी मुख्य सूचनावली में प्रकट होंगे।</string>
|
||||
<string name="backup_type_indexer_relays">अनुक्रमणीकार पुनःप्रसारक सूची</string>
|
||||
<string name="backup_type_indexer_relays_explainer">पुनःप्रसारक उपयुक्त अन्य लोगों के परिचय तथा पुनःप्रसारक सूचियों को प्राप्त करने के लिए।</string>
|
||||
<string name="backup_type_key_package_relays">समूहचर्चा कुंचिका पुनःप्रसारक</string>
|
||||
<string name="backup_type_key_package_relays_explainer">जहाँ अन्य उन कुंचिकाओं को प्राप्त करते हैं आपको रहस्यीकृत समूहचर्चाओं में जोडने के लिए।</string>
|
||||
<string name="backup_type_mute_list">मौन सूची</string>
|
||||
<string name="backup_type_mute_list_explainer">छिपाता है लोग शब्द विषयसूचक तथा सूत्र उन सब में से जो आप देखते हैं।</string>
|
||||
<string name="backup_type_nutzap_info">नटज्साप प्राप्ती स्थापना विकल्प</string>
|
||||
<string name="backup_type_nutzap_info_explainer">टकसाल तथा कुंचिका जिनका उपयोग अन्य करते हैं आपको नटज्साप भेजने के लिए।</string>
|
||||
<string name="backup_type_other">सूची</string>
|
||||
<string name="backup_type_other_explainer">इस यन्त्र पर अभिलेखित सूची।</string>
|
||||
<string name="backup_type_outbox_inbox_relays">सार्वजनिक पुनःप्रसारक सूची</string>
|
||||
<string name="backup_type_outbox_inbox_relays_explainer">सबको बताता है आपके पत्र कहाँ प्राप्त करें तथा आपको उत्तर तथा उल्लेखों को कहाँ भेजें।</string>
|
||||
<string name="backup_type_payment_targets">भुगतान पते</string>
|
||||
<string name="backup_type_payment_targets_explainer">विधियाँ जिनसे अन्य लोग आपको भुगतान कर सके।</string>
|
||||
<string name="backup_type_private_outbox_relays">निजी पुनःप्रसारक सूची</string>
|
||||
<string name="backup_type_private_outbox_relays_explainer">जहाँ आपके पाण्डुलिपियाँ तथा निजी जानकारी रखे जाते हैं।</string>
|
||||
<string name="backup_type_profile">परिचय</string>
|
||||
<string name="backup_type_profile_explainer">आपका नाम चित्र चरित तथा भुगतान पते। जैसे सब को दिखते हैं वैसे।</string>
|
||||
<string name="backup_type_public_chats">सार्वजनिक चर्चा सूची</string>
|
||||
<string name="backup_type_public_chats_explainer">सार्वजनिक चर्चाएँ जिनसे आप जुडे।</string>
|
||||
<string name="backup_type_relay_feeds">इष्ट पुनःप्रसारक सूचनावलियाँ</string>
|
||||
<string name="backup_type_relay_feeds_explainer">पुनःप्रसारक जिनका आप वीक्षण करते हैं सूचनावलियों के रूप में।</string>
|
||||
<string name="backup_type_relay_groups">समूह सूची</string>
|
||||
<string name="backup_type_relay_groups_explainer">पुनःप्रसारक आधारित समूह जिनसे आप जुडे।</string>
|
||||
<string name="backup_type_search_relays">खोज पुनःप्रसारक सूची</string>
|
||||
<string name="backup_type_search_relays_explainer">उपयुक्त पुनःप्रसारक जब आप खोजते हैं।</string>
|
||||
<string name="backup_type_trust_providers">विश्वाससेवा प्रदाता सूची</string>
|
||||
<string name="backup_type_trust_providers_explainer">सेवाएँ जिनपर आप विश्वास करते है आपके लिए लोगों का सत्यापन तथा श्रेणीकरण करने के लिए।</string>
|
||||
<string name="backup_type_trusted_relays">विश्वसनीय पुनःप्रसारक सूची</string>
|
||||
<string name="backup_type_trusted_relays_explainer">पुनःप्रसारक जिनपर आप पर्याप्त विश्वास करते हैं बिना पूछे उनसे संयोजन करने के लिए।</string>
|
||||
</resources>
|
||||
|
||||
@@ -5287,4 +5287,322 @@
|
||||
<string name="cyberspace_bag_unsigned">Aláírás nélküli, így ez a szerző csak állítás</string>
|
||||
<string name="cyberspace_bag_unknown_kind">Egy %1$d típusú elem, amelyet ez a kliens nem jelenít meg</string>
|
||||
<string name="cyberspace_bag_opaque">%1$d bájt valamiből, amit ez a kliens nem olvas</string>
|
||||
<string name="backup_action_block_again">%1$s újbóli letiltása</string>
|
||||
<string name="backup_action_keep_count">%1$s megtartása</string>
|
||||
<string name="backup_action_rejoin">Újbóli csatlakozás ehhez: %1$s</string>
|
||||
<string name="backup_action_remute">%1$s újbóli némítása</string>
|
||||
<string name="backup_action_restore_count">%1$s visszaállítása</string>
|
||||
<string name="backup_action_restore_feeds">Hírfolyamok visszaállítása</string>
|
||||
<string name="backup_action_restore_places">Helyek visszaállítása</string>
|
||||
<string name="backup_action_restore_profile">Profil visszaállítása</string>
|
||||
<string name="backup_action_restore_providers">Szolgáltatók visszaállítása</string>
|
||||
<string name="backup_action_restore_relays">Átjátszók visszaállítása</string>
|
||||
<string name="backup_action_restore_topics">Témák visszaállítása</string>
|
||||
<string name="backup_action_restore_wallet">Pénztárca visszaállítása</string>
|
||||
<string name="backup_card_accept">Elfogadás</string>
|
||||
<plurals name="backup_card_and_added">
|
||||
<item quantity="one">%1$s és %2$d hozzáadva</item>
|
||||
<item quantity="other">%1$s és %2$d hozzáadva</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_blocked">
|
||||
<item quantity="one">%1$s és %2$d letiltva</item>
|
||||
<item quantity="other">%1$s és %2$d letiltva</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_followed">
|
||||
<item quantity="one">%1$s és %2$d követve</item>
|
||||
<item quantity="other">%1$s és %2$d követve</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_joined">
|
||||
<item quantity="one">%1$s és %2$d csatlakozva</item>
|
||||
<item quantity="other">%1$s és %2$d csatlakozva</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_muted">
|
||||
<item quantity="one">%1$s és %2$d némítva</item>
|
||||
<item quantity="other">%1$s és %2$d némítva</item>
|
||||
</plurals>
|
||||
<string name="backup_card_app_settings">A szinkronizált Amethyst alkalmazásbeállításai egy másik, nem Amethyst alkalmazásban módosultak. Ez problémákat okozhat.</string>
|
||||
<string name="backup_card_concord_emptied">Ön kiürítette a Concord listáját</string>
|
||||
<string name="backup_card_concord_rewritten">Ön módosította a Concord listáját</string>
|
||||
<plurals name="backup_card_dm_relays_lost">
|
||||
<item quantity="one">Ön %1$d privát üzenetátjátszót távolított el</item>
|
||||
<item quantity="other">%1$d privát üzenet átjátszót távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_feeds_removed">
|
||||
<item quantity="one">Ön %1$d kedvenc hírfolyamot távolított el</item>
|
||||
<item quantity="other">%1$d kedvenc hírfolyamot távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_follows_dropped">
|
||||
<item quantity="one">%1$d személyt nem követ többé</item>
|
||||
<item quantity="other">%1$d személyt nem követ többé</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_hashtags_unfollowed">
|
||||
<item quantity="one">Ön %1$d kulcsszót nem követ többé</item>
|
||||
<item quantity="other">%1$d hashtaget nem követ többé</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_indexer_relays_lost">
|
||||
<item quantity="one">Ön %1$d indexelő átjátszót távolított el</item>
|
||||
<item quantity="other">%1$d indexelő átjátszót távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_key_package_relays_lost">
|
||||
<item quantity="one">Ön %1$d csoportos csevegési kulcsátjátszót távolított el</item>
|
||||
<item quantity="other">%1$d csoportcsevegés kulcs átjátszót távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_chats">
|
||||
<item quantity="one">Ön %1$d nyilvános csevegést hagyott el</item>
|
||||
<item quantity="other">%1$d nyilvános csevegést hagyott el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_communities">
|
||||
<item quantity="one">Ön %1$d közösséget hagyott el</item>
|
||||
<item quantity="other">%1$d közösséget hagyott el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_groups">
|
||||
<item quantity="one">Ön %1$d csoportot hagyott el</item>
|
||||
<item quantity="other">%1$d csoportot hagyott el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_rooms">
|
||||
<item quantity="one">Ön %1$d csevegőszobát hagyott el</item>
|
||||
<item quantity="other">%1$d csevegőszobát hagyott el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_mutes_visible">
|
||||
<item quantity="one">Ön %1$d dolog némítását oldotta fel</item>
|
||||
<item quantity="other">%1$d dolog némítását oldotta fel</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_nip65_lost">
|
||||
<item quantity="one">Ön %1$d nyilvános átjátszót távolított el</item>
|
||||
<item quantity="other">%1$d nyilvános átjátszót távolított el</item>
|
||||
</plurals>
|
||||
<string name="backup_card_nutzap_key_removed">Ön eltávolította a nutzap kulcsát</string>
|
||||
<string name="backup_card_nutzap_key_replaced">Ön lecserélte a nutzap kulcsát</string>
|
||||
<plurals name="backup_card_nutzap_mints_removed">
|
||||
<item quantity="one">Ön %1$d nutzap pénzverdét távolított el</item>
|
||||
<item quantity="other">%1$d nutzap pénzverdét távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_offers_removed">
|
||||
<item quantity="one">Ön %1$d BOLT12 ajánlatot távolított el</item>
|
||||
<item quantity="other">%1$d BOLT12 ajánlatot távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_payment_targets_removed">
|
||||
<item quantity="one">Ön %1$d fizetési módot távolított el</item>
|
||||
<item quantity="other">%1$d fizetési módot távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_places_unfollowed">
|
||||
<item quantity="one">Ön %1$d helyet nem követ többé</item>
|
||||
<item quantity="other">%1$d helyet nem követ többé</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_private_outbox_lost">
|
||||
<item quantity="one">Ön %1$d privát átjátszót távolított el</item>
|
||||
<item quantity="other">%1$d privát átjátszót távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_profile_lost_fields">
|
||||
<item quantity="one">Ön %1$d profilmezőt távolított el</item>
|
||||
<item quantity="other">%1$d profilmezőt távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_relay_feeds_lost">
|
||||
<item quantity="one">Ön %1$d átjátszó-hírfolyamot távolított el</item>
|
||||
<item quantity="other">%1$d átjátszó hírfolyamot távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_search_relays_lost">
|
||||
<item quantity="one">Ön %1$d kereső átjátszót távolított el</item>
|
||||
<item quantity="other">%1$d kereső átjátszót távolított el</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trust_services_changed">
|
||||
<item quantity="one">Ön %1$d bizalmi szolgáltatás szolgáltatóját módosította</item>
|
||||
<item quantity="other">%1$d bizalmi szolgáltatás szolgáltatóját változtatta meg</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trusted_lost">
|
||||
<item quantity="one">Ön %1$d átjátszóban nem bízik többé</item>
|
||||
<item quantity="other">%1$d átjátszóban nem bízik többé</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_unblocked">
|
||||
<item quantity="one">Ön %1$d átjátszó letiltását oldotta fel</item>
|
||||
<item quantity="other">%1$d átjátszó blokkolását oldotta fel</item>
|
||||
</plurals>
|
||||
<string name="backup_card_wallet_emptied">Ön kiürítette a Cashu pénztárcáját</string>
|
||||
<string name="backup_card_wallet_rewritten">Ön módosította a Cashu pénztárcáját</string>
|
||||
<string name="backup_conflict_added">Hozzáadva (%1$s)</string>
|
||||
<string name="backup_conflict_changed">Módosítva (%1$s)</string>
|
||||
<string name="backup_conflict_count_added">%1$s hozzáadva</string>
|
||||
<string name="backup_conflict_count_changed">%1$s módosítva</string>
|
||||
<string name="backup_conflict_count_removed">%1$s eltávolítva</string>
|
||||
<string name="backup_conflict_keep_new">Új verzió használata</string>
|
||||
<string name="backup_conflict_private_added">Ön privát (titkosított) elemeket adott hozzá.</string>
|
||||
<string name="backup_conflict_private_changed">Ön privát (titkosított) elemeket is módosított. Ezek itt nem hasonlíthatók össze.</string>
|
||||
<string name="backup_conflict_private_cleared">Ön eltávolította az összes privát (titkosított) elemet.</string>
|
||||
<string name="backup_conflict_relay_read_only">csak olvasható</string>
|
||||
<string name="backup_conflict_relay_read_write">olvasás és írás</string>
|
||||
<string name="backup_conflict_relay_write_only">csak írható</string>
|
||||
<string name="backup_conflict_removed">Eltávolítva (%1$s)</string>
|
||||
<string name="backup_conflict_restore_mine">Mentett verzió visszaállítása</string>
|
||||
<string name="backup_conflict_title">Ön módosította a következőt: %1$s, egy másik alkalmazásban</string>
|
||||
<string name="backup_entry_algo_feed">Hírfolyamok</string>
|
||||
<string name="backup_entry_chat_room">Csevegőszobák</string>
|
||||
<string name="backup_entry_community">Közösségek</string>
|
||||
<string name="backup_entry_hashtag">Kulcsszavak</string>
|
||||
<string name="backup_entry_identity_claim">Kapcsolt identitások</string>
|
||||
<string name="backup_entry_location">Helyek</string>
|
||||
<string name="backup_entry_mint">Pénzverdék</string>
|
||||
<string name="backup_entry_nutzap_key">Nutzap kulcsok</string>
|
||||
<string name="backup_entry_offer">Ajánlatok</string>
|
||||
<string name="backup_entry_other">Egyéb bejegyzések</string>
|
||||
<string name="backup_entry_payment_target">Fizetési címek</string>
|
||||
<string name="backup_entry_person">Személyek</string>
|
||||
<string name="backup_entry_profile_field">Profilmezők</string>
|
||||
<string name="backup_entry_public_chat">Nyilvános csevegések</string>
|
||||
<string name="backup_entry_relay">Átjátszók</string>
|
||||
<string name="backup_entry_relay_group">Csoportok</string>
|
||||
<string name="backup_entry_thread">Beszélgetések</string>
|
||||
<string name="backup_entry_trust_provider">Bizalmi szolgáltatók</string>
|
||||
<string name="backup_entry_word">Szavak</string>
|
||||
<string name="backup_profile_field_about">Névjegy</string>
|
||||
<string name="backup_profile_field_banner">Borító</string>
|
||||
<string name="backup_profile_field_birthday">Születésnap</string>
|
||||
<string name="backup_profile_field_bot">Bot jelölő</string>
|
||||
<string name="backup_profile_field_clink_offer">CLINK-ajánlat</string>
|
||||
<string name="backup_profile_field_display_name">Megjelenített név</string>
|
||||
<string name="backup_profile_field_lud06">LNURL</string>
|
||||
<string name="backup_profile_field_lud16">Lightning-cím</string>
|
||||
<string name="backup_profile_field_name">Felhasználónév</string>
|
||||
<string name="backup_profile_field_nip05">Nostr-cím</string>
|
||||
<string name="backup_profile_field_picture">Kép</string>
|
||||
<string name="backup_profile_field_pronouns">Névmások</string>
|
||||
<string name="backup_profile_field_website">Weboldal</string>
|
||||
<string name="backup_review_allowed_tag">Engedélyezve</string>
|
||||
<string name="backup_review_changed_by_other_app">Módosítva egy másik alkalmazásban · %1$s</string>
|
||||
<string name="backup_review_concord_body">A Concord közösségei Önhöz vannak titkosítva, így itt nem hasonlíthatók össze. A visszaállítás pontosan azt hozza vissza, amit ez az eszköz mentett.</string>
|
||||
<string name="backup_review_demoted_tag">Áthelyezve</string>
|
||||
<string name="backup_review_dropped_count">%1$s elvetve</string>
|
||||
<string name="backup_review_dropped_tag">Elvetve</string>
|
||||
<string name="backup_review_encrypted_added">Ön hozta létre</string>
|
||||
<string name="backup_review_encrypted_changed">Ön módosította</string>
|
||||
<string name="backup_review_encrypted_cleared">Ön kiürítette</string>
|
||||
<string name="backup_review_feed">Hírfolyam</string>
|
||||
<string name="backup_review_gone">Eltűnt</string>
|
||||
<string name="backup_review_hashtags_you_follow">Ön által követett kulcsszavak</string>
|
||||
<string name="backup_review_inbox">Bejövő</string>
|
||||
<string name="backup_review_inbox_explainer">ahol mások elérik Önt</string>
|
||||
<string name="backup_review_joined">csatlakozott</string>
|
||||
<string name="backup_review_kept">megtartva</string>
|
||||
<string name="backup_review_kept_count">%1$s megtartva</string>
|
||||
<string name="backup_review_key_removed">Fogadási kulcs eltávolítva</string>
|
||||
<string name="backup_review_key_replaced">Fogadási kulcs lecserélve</string>
|
||||
<string name="backup_review_key_warning">A nutzapok ehhez az új kulcshoz lesznek kötve. Ha ez az eszköz nem rendelkezik vele, lehet, hogy itt nem tudja beváltani őket.</string>
|
||||
<string name="backup_review_left">elhagyta a csoportot</string>
|
||||
<string name="backup_review_left_tag">Elhagyva</string>
|
||||
<string name="backup_review_listed_tag">Listázva</string>
|
||||
<string name="backup_review_moved_tag">Áthelyezve</string>
|
||||
<string name="backup_review_names_and_more">%1$s és %2$s további</string>
|
||||
<string name="backup_review_new">Új verzió</string>
|
||||
<string name="backup_review_new_count">%1$s új</string>
|
||||
<string name="backup_review_new_count_caption">új</string>
|
||||
<string name="backup_review_new_tag">Új</string>
|
||||
<string name="backup_review_newly_blocked">Újonnan letiltva</string>
|
||||
<string name="backup_review_newly_muted">%1$s újonnan némítva</string>
|
||||
<string name="backup_review_no_longer_blocked">Már nincs letiltva</string>
|
||||
<string name="backup_review_not_set">Nincs beállítva</string>
|
||||
<string name="backup_review_nothing_here">Itt nincs semmi</string>
|
||||
<string name="backup_review_offer">BOLT12 ajánlat</string>
|
||||
<plurals name="backup_review_offers_gone">
|
||||
<item quantity="one">%1$d ajánlat eltávolítva</item>
|
||||
<item quantity="other">%1$d ajánlat eltávolítva</item>
|
||||
</plurals>
|
||||
<string name="backup_review_outbox">Kimenő</string>
|
||||
<string name="backup_review_outbox_explainer">ahol közzétesz</string>
|
||||
<plurals name="backup_review_payment_targets_gone">
|
||||
<item quantity="one">%1$d fizetési mód eltávolítva</item>
|
||||
<item quantity="other">%1$d fizetési mód eltávolítva</item>
|
||||
</plurals>
|
||||
<string name="backup_review_payments_explainer">A fizető emberek csak azt látják, ami ebben a listában van.</string>
|
||||
<string name="backup_review_places_gone">eltűnt helyek</string>
|
||||
<string name="backup_review_places_you_follow">Ön által követett helyek</string>
|
||||
<string name="backup_review_private_added_body">Most már titkosítva vannak, valószínűleg ide kerültek a fenti nyilvános elemek.</string>
|
||||
<string name="backup_review_private_added_title">Ön priváttá tette az elemeket</string>
|
||||
<string name="backup_review_private_changed_body">Titkosítva vannak, így itt nem hasonlíthatók össze.</string>
|
||||
<string name="backup_review_private_changed_title">Ön módosította a privát elemeket</string>
|
||||
<string name="backup_review_private_wiped_body">Titkosítva vannak, így csak Ön láthatja, mik voltak. A visszaállítás mindet visszahozza.</string>
|
||||
<string name="backup_review_private_wiped_title">Ön eltávolította az összes privát elemet</string>
|
||||
<string name="backup_review_receiving_tag">Fogadás</string>
|
||||
<string name="backup_review_renamed">átnevezte</string>
|
||||
<string name="backup_review_renamed_tag">Átnevezve</string>
|
||||
<string name="backup_review_saved">Ezen az eszközön</string>
|
||||
<string name="backup_review_search_people">%1$s személy keresése</string>
|
||||
<string name="backup_review_searching_tag">Keresés</string>
|
||||
<string name="backup_review_service">Szolgáltatás</string>
|
||||
<string name="backup_review_service_followers">Követők</string>
|
||||
<string name="backup_review_service_rank">Rang</string>
|
||||
<string name="backup_review_service_topics">Témák</string>
|
||||
<string name="backup_review_services_changed">%2$s szolgáltatásból %1$s módosult</string>
|
||||
<string name="backup_review_services_changed_explainer">Most már valaki mástól vagy senkitől sem származnak</string>
|
||||
<string name="backup_review_still_blocked">Továbbra is le van tiltva</string>
|
||||
<string name="backup_review_storing_tag">Tárolás</string>
|
||||
<string name="backup_review_tab_dropped">Elvetve · %1$s</string>
|
||||
<string name="backup_review_tab_edited">Szerkesztve · %1$s</string>
|
||||
<string name="backup_review_tab_new">Új · %1$s</string>
|
||||
<string name="backup_review_title_cleared">%1$s törölve</string>
|
||||
<string name="backup_review_title_updated">%1$s frissítve</string>
|
||||
<string name="backup_review_topics_gone">eltűnt témák</string>
|
||||
<string name="backup_review_trust_warning">A látott rangok, követőszámok és a kéretlen tartalomszűrés ezektől a szolgáltatóktól származnak.</string>
|
||||
<string name="backup_review_trusted_tag">Megbízható</string>
|
||||
<string name="backup_review_unblocked">%1$s letiltása feloldva</string>
|
||||
<string name="backup_review_unblocked_explainer">Az Amethyst újra kapcsolódni fog hozzájuk</string>
|
||||
<string name="backup_review_units_tag">Egységek</string>
|
||||
<string name="backup_review_unmuted">%1$s némítása feloldva</string>
|
||||
<string name="backup_review_unmuted_explainer">Ezek újra megjelenhetnek a hírfolyamaiban</string>
|
||||
<string name="backup_review_untrusted_tag">Nem megbízható</string>
|
||||
<string name="backup_review_wallet_body">A saját pénztárca pénzverdéi és kulcsai Önhöz vannak titkosítva, így itt nem hasonlíthatók össze tételesen. A visszaállítás pontosan azt hozza vissza, amit ez az eszköz mentett.</string>
|
||||
<string name="backup_review_was_named">„%1$s” volt</string>
|
||||
<string name="backup_review_words_and_hashtags">Szavak és kulcsszavak</string>
|
||||
<string name="backup_type_app_settings">szinkronizált alkalmazásbeállítások</string>
|
||||
<string name="backup_type_app_settings_explainer">Az eszközök között szinkronizált Amethyst-beállítások. Titkosítva vannak, így csak a jelenlétük hasonlítható össze.</string>
|
||||
<string name="backup_type_blocked_relays">letiltott átjátszólista</string>
|
||||
<string name="backup_type_blocked_relays_explainer">Átjátszók, amelyekhez ez az alkalmazás soha nem kapcsolódik.</string>
|
||||
<string name="backup_type_bolt12_offers">BOLT12 ajánlatok</string>
|
||||
<string name="backup_type_bolt12_offers_explainer">A lightning ajánlatok, amelyeket mások a fizetéshez használnak az Ön számára.</string>
|
||||
<string name="backup_type_cashu_wallet">Cashu pénztárca</string>
|
||||
<string name="backup_type_cashu_wallet_explainer">Az ecash pénztárca beállításai és pénzverdéi. Titkosítva vannak, így csak a jelenlétük hasonlítható össze.</string>
|
||||
<string name="backup_type_communities">közösséglista</string>
|
||||
<string name="backup_type_communities_explainer">Közösségek, amelyekhez csatlakozott.</string>
|
||||
<string name="backup_type_concord_communities">Concord közösséglista</string>
|
||||
<string name="backup_type_concord_communities_explainer">A Concord közösségek, amelyekhez csatlakozott. Titkosítva vannak, így csak a jelenlétük hasonlítható össze.</string>
|
||||
<string name="backup_type_dm_relays">privát üzenet átjátszólista</string>
|
||||
<string name="backup_type_dm_relays_explainer">Ahová mások kézbesítik a privát üzeneteit.</string>
|
||||
<string name="backup_type_ephemeral_chats">rövid életű csevegési lista</string>
|
||||
<string name="backup_type_ephemeral_chats_explainer">Rövid életű csevegőszobák, amelyekhez csatlakozott.</string>
|
||||
<string name="backup_type_favorite_algo_feeds">kedvenc hírfolyamlista</string>
|
||||
<string name="backup_type_favorite_algo_feeds_explainer">Mentett algoritmus-hírfolyamok.</string>
|
||||
<string name="backup_type_follow_list">követési lista</string>
|
||||
<string name="backup_type_follow_list_explainer">Meghatározza, kinek a bejegyzései jelenjenek meg a kezdőlapon.</string>
|
||||
<string name="backup_type_geohashes">követett helyek</string>
|
||||
<string name="backup_type_geohashes_explainer">Helyek, amelyek bejegyzései megjelennek a hírfolyamaiban.</string>
|
||||
<string name="backup_type_hashtags">követett kulcsszavak</string>
|
||||
<string name="backup_type_hashtags_explainer">Kulcsszavak, amelyek bejegyzései megjelennek a hírfolyamban.</string>
|
||||
<string name="backup_type_indexer_relays">indexelő átjátszólista</string>
|
||||
<string name="backup_type_indexer_relays_explainer">Azok az átjátszók, amelyeket mások profiljainak és átjátszólistáinak megtalálásához használnak.</string>
|
||||
<string name="backup_type_key_package_relays">csoportos csevegési kulcsátjátszók</string>
|
||||
<string name="backup_type_key_package_relays_explainer">Ahol mások megtalálják a kulcsokat, hogy titkosított csoportos csevegésekhez adhassák Önt.</string>
|
||||
<string name="backup_type_mute_list">némítási lista</string>
|
||||
<string name="backup_type_mute_list_explainer">Elrejti a személyeket, szavakat, kulcsszavakat és beszélgetéseket mindenből, amit lát.</string>
|
||||
<string name="backup_type_nutzap_info">nutzap fogadási beállítások</string>
|
||||
<string name="backup_type_nutzap_info_explainer">A pénzverdék és a kulcs, amelyeket mások a nutzapok küldéséhez használnak az Ön számára.</string>
|
||||
<string name="backup_type_other">lista</string>
|
||||
<string name="backup_type_other_explainer">Egy listaelem ezen az eszközön mentve.</string>
|
||||
<string name="backup_type_outbox_inbox_relays">nyilvános átjátszólista</string>
|
||||
<string name="backup_type_outbox_inbox_relays_explainer">Megmondja mindenkinek, hol találhatók a bejegyzései, és hová küldjék a válaszokat és említéseket.</string>
|
||||
<string name="backup_type_payment_targets">fizetési címek</string>
|
||||
<string name="backup_type_payment_targets_explainer">A módok, ahogy mások fizethetnek Önnek.</string>
|
||||
<string name="backup_type_private_outbox_relays">privát átjátszólista</string>
|
||||
<string name="backup_type_private_outbox_relays_explainer">Ahol a piszkozatai és privát adatai tárolódnak.</string>
|
||||
<string name="backup_type_profile">profil</string>
|
||||
<string name="backup_type_profile_explainer">Az Ön neve, képe, bemutatkozása és fizetési címei, ahogy mindenki látja őket.</string>
|
||||
<string name="backup_type_public_chats">nyilvános csevegési lista</string>
|
||||
<string name="backup_type_public_chats_explainer">Nyilvános csevegések, amelyekhez csatlakozott.</string>
|
||||
<string name="backup_type_relay_feeds">kedvenc átjátszóhírfolyamok</string>
|
||||
<string name="backup_type_relay_feeds_explainer">Olyan átjátszók, amelyeket hírfolyamként böngész.</string>
|
||||
<string name="backup_type_relay_groups">csoportlista</string>
|
||||
<string name="backup_type_relay_groups_explainer">Átjátszó-alapú csoportok, amelyekhez csatlakozott.</string>
|
||||
<string name="backup_type_search_relays">kereső átjátszólista</string>
|
||||
<string name="backup_type_search_relays_explainer">Kereséskor használt átjátszók.</string>
|
||||
<string name="backup_type_trust_providers">bizalmi szolgáltatólista</string>
|
||||
<string name="backup_type_trust_providers_explainer">A szolgáltatások, amelyekben megbízik, hogy rangsorolják és ellenőrizzék Önnek az embereket.</string>
|
||||
<string name="backup_type_trusted_relays">megbízható átjátszólista</string>
|
||||
<string name="backup_type_trusted_relays_explainer">Átjátszók, amelyekhez kérdezés nélkül kapcsolódhat.</string>
|
||||
</resources>
|
||||
|
||||
@@ -5507,4 +5507,382 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest
|
||||
<string name="cyberspace_bag_unsigned">Brak podpisu, więc autor to tylko domysł</string>
|
||||
<string name="cyberspace_bag_unknown_kind">Element typu %1$d, którego ten klient nie wyświetla</string>
|
||||
<string name="cyberspace_bag_opaque">%1$d bajtów danych, których ten klient nie odczytuje</string>
|
||||
<string name="backup_action_block_again">Zablokuj %1$s ponownie</string>
|
||||
<string name="backup_action_keep_count">Zachowaj %1$s</string>
|
||||
<string name="backup_action_rejoin">Ponów %1$s</string>
|
||||
<string name="backup_action_remute">Ponownie wycisz %1$s</string>
|
||||
<string name="backup_action_restore_count">Przywróć %1$s</string>
|
||||
<string name="backup_action_restore_feeds">Przywróć kanały</string>
|
||||
<string name="backup_action_restore_places">Przywróć miejsca</string>
|
||||
<string name="backup_action_restore_profile">Przywróć profil</string>
|
||||
<string name="backup_action_restore_providers">Przywróć dostawców</string>
|
||||
<string name="backup_action_restore_relays">Przywróć transmitery</string>
|
||||
<string name="backup_action_restore_topics">Przywróć tematy</string>
|
||||
<string name="backup_action_restore_wallet">Przywróć portfel</string>
|
||||
<string name="backup_card_accept">Zaakceptuj</string>
|
||||
<plurals name="backup_card_and_added">
|
||||
<item quantity="one">%1$s i dodano %2$d</item>
|
||||
<item quantity="few">%1$s i dodano %2$d</item>
|
||||
<item quantity="many">%1$s i dodano %2$d</item>
|
||||
<item quantity="other">%1$s i dodano %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_blocked">
|
||||
<item quantity="one">%1$s i zablokowano %2$d</item>
|
||||
<item quantity="few">%1$s i zablokowano %2$d</item>
|
||||
<item quantity="many">%1$s i zablokowano %2$d</item>
|
||||
<item quantity="other">%1$s i zablokowano %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_followed">
|
||||
<item quantity="one">%1$s i obserwowany %2$d</item>
|
||||
<item quantity="few">%1$s i obserwowanych %2$d</item>
|
||||
<item quantity="many">%1$s i obserwowanych %2$d</item>
|
||||
<item quantity="other">%1$s i obserwowane %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_joined">
|
||||
<item quantity="one">%1$s i dołączono do %2$d</item>
|
||||
<item quantity="few">%1$s i dołączono do %2$d</item>
|
||||
<item quantity="many">%1$s i dołączono do %2$d</item>
|
||||
<item quantity="other">%1$s i dołączono do %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_muted">
|
||||
<item quantity="one">%1$s i wyciszony %2$d</item>
|
||||
<item quantity="few">%1$s i wyciszono %2$d</item>
|
||||
<item quantity="many">%1$s i wyciszono %2$d</item>
|
||||
<item quantity="other">%1$s i wyciszone %2$d</item>
|
||||
</plurals>
|
||||
<string name="backup_card_app_settings">Twoje zsynchronizowane ustawienia aplikacji Amethyst zostały zmienione w innej aplikacji, która nie jest Amethystem. To może powodować problemy.</string>
|
||||
<string name="backup_card_concord_emptied">Opróżniłeś swoją listę Concorda</string>
|
||||
<string name="backup_card_concord_rewritten">Zmieniłeś swoją listę Concorda</string>
|
||||
<plurals name="backup_card_dm_relays_lost">
|
||||
<item quantity="one">Usunąłeś %1$d transmiter DM</item>
|
||||
<item quantity="few">Usunąłeś %1$d transmiterów DM</item>
|
||||
<item quantity="many">Usunąłeś %1$d transmiterów DM</item>
|
||||
<item quantity="other">Usunąłeś %1$d transmitery DM</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_feeds_removed">
|
||||
<item quantity="one">Usunąłeś %1$d ulubiony kanał</item>
|
||||
<item quantity="few">Usunąłeś %1$d ulubionych kanałów</item>
|
||||
<item quantity="many">Usunąłeś %1$d ulubionych kanałów</item>
|
||||
<item quantity="other">Usunięto %1$d ulubione kanały</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_follows_dropped">
|
||||
<item quantity="one">Przestałeś obserwować %1$d osobę</item>
|
||||
<item quantity="few">Przestałeś obserwować %1$d osób</item>
|
||||
<item quantity="many">Przestałeś obserwować %1$d osób</item>
|
||||
<item quantity="other">Przestałeś obserwować %1$d osoby</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_hashtags_unfollowed">
|
||||
<item quantity="one">Przestałeś obserwować %1$d hashtag</item>
|
||||
<item quantity="few">Przestałeś obserwować %1$d hashtagów</item>
|
||||
<item quantity="many">Przestałeś obserwować %1$d hashtagów</item>
|
||||
<item quantity="other">Przestałeś obserwować %1$d hashtagi</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_indexer_relays_lost">
|
||||
<item quantity="one">Usunięto %1$d transmiter indeksujący</item>
|
||||
<item quantity="few">Usunięto %1$d transmiterów indeksujących</item>
|
||||
<item quantity="many">Usunięto %1$d transmiterów indeksujących</item>
|
||||
<item quantity="other">Usunięto %1$d transmitery indeksujące</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_key_package_relays_lost">
|
||||
<item quantity="one">Usunięto %1$d transmiter klucza grupowego czatu</item>
|
||||
<item quantity="few">Usunięto %1$d transmiterów klucza grupowego czatu</item>
|
||||
<item quantity="many">Usunięto %1$d transmiterów klucza grupowego czatu</item>
|
||||
<item quantity="other">Usunięto %1$d transmitery klucza grupowego czatu</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_chats">
|
||||
<item quantity="one">Opuściłeś %1$d czat publiczny</item>
|
||||
<item quantity="few">Opuściłeś %1$d czatów publicznych</item>
|
||||
<item quantity="many">Opuściłeś %1$d czatów publicznych</item>
|
||||
<item quantity="other">Opuściłeś %1$d czaty publiczne</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_communities">
|
||||
<item quantity="one">Opuściłeś %1$d społeczność</item>
|
||||
<item quantity="few">Opuściłeś %1$d społeczności</item>
|
||||
<item quantity="many">Opuściłeś %1$d społeczności</item>
|
||||
<item quantity="other">Opuściłeś %1$d społeczności</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_groups">
|
||||
<item quantity="one">Opuściłeś %1$d grupę</item>
|
||||
<item quantity="few">Opuściłeś %1$d grup</item>
|
||||
<item quantity="many">Opuściłeś %1$d grup</item>
|
||||
<item quantity="other">Opuszczono %1$d grupy</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_rooms">
|
||||
<item quantity="one">Opuściłeś %1$d pokój czatu</item>
|
||||
<item quantity="few">Opuściłeś %1$d pokoi czatu</item>
|
||||
<item quantity="many">Opuściłeś %1$d pokoi czatu</item>
|
||||
<item quantity="other">Opuściłeś %1$d pokoje czatu</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_mutes_visible">
|
||||
<item quantity="one">Włączyłeś dźwięk dla %1$d elementu</item>
|
||||
<item quantity="few">Włączyłeś dźwięk dla %1$d elementów</item>
|
||||
<item quantity="many">Włączyłeś dźwięk dla %1$d elementów</item>
|
||||
<item quantity="other">%1$d elementy mają włączony dźwięk</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_nip65_lost">
|
||||
<item quantity="one">Usunąłeś %1$d publiczny transmiter</item>
|
||||
<item quantity="few">Usunąłeś %1$d publicznych transmiterów</item>
|
||||
<item quantity="many">Usunąłeś %1$d publicznych transmiterów</item>
|
||||
<item quantity="other">Usunąłeś %1$d publiczne transmitery</item>
|
||||
</plurals>
|
||||
<string name="backup_card_nutzap_key_removed">Usunąłeś swój klucz nutzap</string>
|
||||
<string name="backup_card_nutzap_key_replaced">Wymieniłeś swój klucz Nutzap</string>
|
||||
<plurals name="backup_card_nutzap_mints_removed">
|
||||
<item quantity="one">Usunięto %1$d nutzap mint</item>
|
||||
<item quantity="few">Usunięto %1$d nutzap mintów</item>
|
||||
<item quantity="many">Usunięto %1$d nutzap mintów</item>
|
||||
<item quantity="other">Usunięto %1$d nutzap minty</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_offers_removed">
|
||||
<item quantity="one">Usunięto %1$d ofertę BOLT12</item>
|
||||
<item quantity="few">Usunięto %1$d ofert BOLT12</item>
|
||||
<item quantity="many">Usunięto %1$d ofert BOLT12</item>
|
||||
<item quantity="other">Usunięto %1$d oferty BOLT12</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_payment_targets_removed">
|
||||
<item quantity="one">Usunięto %1$d sposób na otrzymanie zapłaty</item>
|
||||
<item quantity="few">Usunięto %1$d sposobów otrzymywania zapłaty</item>
|
||||
<item quantity="many">Usunięto %1$d sposobów otrzymywania zapłaty</item>
|
||||
<item quantity="other">Usunięto %1$d sposoby otrzymywania zapłaty</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_places_unfollowed">
|
||||
<item quantity="one">Przestałeś obserwować %1$d miejsce</item>
|
||||
<item quantity="few">Przestałeś obserwować %1$d miejsc</item>
|
||||
<item quantity="many">Przestałeś obserwować %1$d miejsc</item>
|
||||
<item quantity="other">Przestałeś obserwować %1$d miejsca</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_private_outbox_lost">
|
||||
<item quantity="one">Usunięto %1$d prywatny transmiter</item>
|
||||
<item quantity="few">Usunięto %1$d prywatnych transmiterów</item>
|
||||
<item quantity="many">Usunięto %1$d prywatnych transmiterów</item>
|
||||
<item quantity="other">Usunięto %1$d prywatne transmitery</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_profile_lost_fields">
|
||||
<item quantity="one">Usunąłeś %1$d pole profilu</item>
|
||||
<item quantity="few">Usunąłeś %1$d pól profilowych</item>
|
||||
<item quantity="many">Usunąłeś %1$d pól profilowych</item>
|
||||
<item quantity="other">Usunąłeś %1$d pola profilowe</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_relay_feeds_lost">
|
||||
<item quantity="one">Usunięto %1$d kanał transmitera</item>
|
||||
<item quantity="few">Usunięto %1$d kanałów transmitera</item>
|
||||
<item quantity="many">Usunięto %1$d kanałów transmitera</item>
|
||||
<item quantity="other">Usunięto %1$d kanały transmitera</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_search_relays_lost">
|
||||
<item quantity="one">Usunięto %1$d transmiter wyszukiwania</item>
|
||||
<item quantity="few">Usunięto %1$d transmiterów wyszukiwania</item>
|
||||
<item quantity="many">Usunięto %1$d transmiterów wyszukiwania</item>
|
||||
<item quantity="other">Usunięto %1$d transmitery wyszukiwania</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trust_services_changed">
|
||||
<item quantity="one">Zmieniłeś dostawcę %1$d zaufanego serwisu</item>
|
||||
<item quantity="few">Zmieniłeś dostawcę %1$d zaufanych serwisów</item>
|
||||
<item quantity="many">Zmieniłeś dostawcę %1$d zaufanych serwisów</item>
|
||||
<item quantity="other">Zmieniłeś dostawcę %1$d zaufanych serwisów</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trusted_lost">
|
||||
<item quantity="one">Przestałeś ufać %1$d transmiterowi</item>
|
||||
<item quantity="few">Przestałeś ufać %1$d transmiterom</item>
|
||||
<item quantity="many">Przestałeś ufać %1$d transmiterom</item>
|
||||
<item quantity="other">Przestałeś ufać %1$d transmiterom</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_unblocked">
|
||||
<item quantity="one">Odblokowałeś %1$d transmiter</item>
|
||||
<item quantity="few">Odblokowałeś %1$d transmiterów</item>
|
||||
<item quantity="many">Odblokowałeś %1$d transmiterów</item>
|
||||
<item quantity="other">Odblokowałeś %1$d transmitery</item>
|
||||
</plurals>
|
||||
<string name="backup_card_wallet_emptied">Opróżniłeś swój portfel Cashu</string>
|
||||
<string name="backup_card_wallet_rewritten">Zmieniłeś swój portfel Cashu</string>
|
||||
<string name="backup_conflict_added">Dodano (%1$s)</string>
|
||||
<string name="backup_conflict_changed">Zmieniono (%1$s)</string>
|
||||
<string name="backup_conflict_count_added">Dodano %1$s</string>
|
||||
<string name="backup_conflict_count_changed">%1$s zmieniono</string>
|
||||
<string name="backup_conflict_count_removed">Usunięto %1$s</string>
|
||||
<string name="backup_conflict_keep_new">Użyj nowej wersji</string>
|
||||
<string name="backup_conflict_private_added">Dodano prywatne (zaszyfrowane) pozycje.</string>
|
||||
<string name="backup_conflict_private_changed">Zmieniłeś również elementy prywatne (zaszyfrowane). Nie można ich tutaj porównać.</string>
|
||||
<string name="backup_conflict_private_cleared">Usunąłeś wszystkie prywatne (zaszyfrowane) elementy.</string>
|
||||
<string name="backup_conflict_relay_read_only">tylko do odczytu</string>
|
||||
<string name="backup_conflict_relay_read_write">odczyt i zapis</string>
|
||||
<string name="backup_conflict_relay_write_only">tylko do zapisu</string>
|
||||
<string name="backup_conflict_removed">Usunięto (%1$s)</string>
|
||||
<string name="backup_conflict_restore_mine">Przywróć zapisaną wersję</string>
|
||||
<string name="backup_conflict_title">Zmieniłeś %1$s w innej aplikacji</string>
|
||||
<string name="backup_entry_algo_feed">Kanały</string>
|
||||
<string name="backup_entry_chat_room">Czat pokoje</string>
|
||||
<string name="backup_entry_community">Społeczności</string>
|
||||
<string name="backup_entry_hashtag">Hashtagi</string>
|
||||
<string name="backup_entry_identity_claim">Powiązane tożsamości</string>
|
||||
<string name="backup_entry_location">Lokalizacje</string>
|
||||
<string name="backup_entry_mint">Minty</string>
|
||||
<string name="backup_entry_nutzap_key">Klucze Nutzap</string>
|
||||
<string name="backup_entry_offer">Oferty</string>
|
||||
<string name="backup_entry_other">Inne wpisy</string>
|
||||
<string name="backup_entry_payment_target">Adresy płatności</string>
|
||||
<string name="backup_entry_person">Osoby</string>
|
||||
<string name="backup_entry_profile_field">Pola profilu</string>
|
||||
<string name="backup_entry_public_chat">Czaty publiczne</string>
|
||||
<string name="backup_entry_relay">Transmitery</string>
|
||||
<string name="backup_entry_relay_group">Grupy</string>
|
||||
<string name="backup_entry_thread">Wątki</string>
|
||||
<string name="backup_entry_trust_provider">Zaufani dostawcy</string>
|
||||
<string name="backup_entry_word">Słowa</string>
|
||||
<string name="backup_profile_field_about">O profilu</string>
|
||||
<string name="backup_profile_field_banner">Baner</string>
|
||||
<string name="backup_profile_field_birthday">Data urodzin</string>
|
||||
<string name="backup_profile_field_bot">Flaga bota</string>
|
||||
<string name="backup_profile_field_clink_offer">Oferta CLINK</string>
|
||||
<string name="backup_profile_field_display_name">Nazwa wyświetlana</string>
|
||||
<string name="backup_profile_field_lud06">LNURL</string>
|
||||
<string name="backup_profile_field_lud16">Lightning Adres</string>
|
||||
<string name="backup_profile_field_name">Nazwa użytkownika</string>
|
||||
<string name="backup_profile_field_nip05">Adres Nostr</string>
|
||||
<string name="backup_profile_field_picture">Zdjęcie</string>
|
||||
<string name="backup_profile_field_pronouns">Zaimki</string>
|
||||
<string name="backup_profile_field_website">Strona www</string>
|
||||
<string name="backup_review_allowed_tag">Dozwolona</string>
|
||||
<string name="backup_review_changed_by_other_app">Zmieniono w innej aplikacji · %1$s</string>
|
||||
<string name="backup_review_concord_body">Twoje społeczności w Concord są dla Ciebie zaszyfrowane, więc nie można ich tutaj porównać. Przywrócenie danych powoduje przywrócenie dokładnie tego, co zostało zapisane na tym urządzeniu.</string>
|
||||
<string name="backup_review_demoted_tag">Przeniesiona</string>
|
||||
<string name="backup_review_dropped_count">%1$s odrzuconych</string>
|
||||
<string name="backup_review_dropped_tag">Usunięta</string>
|
||||
<string name="backup_review_encrypted_added">Utworzyłeś to</string>
|
||||
<string name="backup_review_encrypted_changed">Zmieniłeś to</string>
|
||||
<string name="backup_review_encrypted_cleared">Opróżniłeś to</string>
|
||||
<string name="backup_review_feed">Kanał</string>
|
||||
<string name="backup_review_gone">Zniknęła</string>
|
||||
<string name="backup_review_hashtags_you_follow">Hashtagi, które obserwujesz</string>
|
||||
<string name="backup_review_inbox">Skrzynka odbiorcza</string>
|
||||
<string name="backup_review_inbox_explainer">gdzie inni docierają do Ciebie</string>
|
||||
<string name="backup_review_joined">dołączył(a)</string>
|
||||
<string name="backup_review_kept">zachowane</string>
|
||||
<string name="backup_review_kept_count">Zachowano %1$s</string>
|
||||
<string name="backup_review_key_removed">Usunięto klucz odbierający</string>
|
||||
<string name="backup_review_key_replaced">Wymieniono klucz odbierający</string>
|
||||
<string name="backup_review_key_warning">Nutzapy zostaną przypisane do tego nowego klucza. Jeśli urządzenie nie posiada tego klucza, może się okazać, że nie będzie można ich tutaj zrealizować.</string>
|
||||
<string name="backup_review_left">zostało</string>
|
||||
<string name="backup_review_left_tag">Zostało</string>
|
||||
<string name="backup_review_listed_tag">Na Liście</string>
|
||||
<string name="backup_review_moved_tag">Przeniesiona</string>
|
||||
<string name="backup_review_names_and_more">%1$s i %2$s więcej</string>
|
||||
<string name="backup_review_new">Nowa wersja</string>
|
||||
<string name="backup_review_new_count">%1$s nowych</string>
|
||||
<string name="backup_review_new_count_caption">nowe</string>
|
||||
<string name="backup_review_new_tag">Nowa</string>
|
||||
<string name="backup_review_newly_blocked">Nowo zablokowana</string>
|
||||
<string name="backup_review_newly_muted">%1$s nowo wyciszonych</string>
|
||||
<string name="backup_review_no_longer_blocked">Nie jest już zablokowana</string>
|
||||
<string name="backup_review_not_set">Nie ustawiono</string>
|
||||
<string name="backup_review_nothing_here">Nic tu nie ma!</string>
|
||||
<string name="backup_review_offer">Oferta BOLT12</string>
|
||||
<plurals name="backup_review_offers_gone">
|
||||
<item quantity="one">%1$d oferta usunięta</item>
|
||||
<item quantity="few">%1$d ofert usunięto</item>
|
||||
<item quantity="many">%1$d ofert usunięto</item>
|
||||
<item quantity="other">%1$d oferty usunięte</item>
|
||||
</plurals>
|
||||
<string name="backup_review_outbox">Skrzynka nadawcza</string>
|
||||
<string name="backup_review_outbox_explainer">gdzie publikujesz</string>
|
||||
<plurals name="backup_review_payment_targets_gone">
|
||||
<item quantity="one">%1$d sposób płatności został usunięty</item>
|
||||
<item quantity="few">%1$d sposobów płatności zostało usuniętych</item>
|
||||
<item quantity="many">%1$d sposobów płatności zostało usuniętych</item>
|
||||
<item quantity="other">%1$d sposoby płatności zostały usunięte</item>
|
||||
</plurals>
|
||||
<string name="backup_review_payments_explainer">Osoby, które Ci płacą, widzą tylko to, co znajduje się na tej liście.</string>
|
||||
<string name="backup_review_places_gone"> miejsca zniknęły</string>
|
||||
<string name="backup_review_places_you_follow">Miejsca które obserwujesz</string>
|
||||
<string name="backup_review_private_added_body">Są teraz zaszyfrowane, co prawdopodobnie wyjaśnia, gdzie podziały się powyższe elementy publiczne.</string>
|
||||
<string name="backup_review_private_added_title">Ustawiłeś te pozycje jako prywatne</string>
|
||||
<string name="backup_review_private_changed_body">Są zaszyfrowane, więc nie można ich tu porównać.</string>
|
||||
<string name="backup_review_private_changed_title">Zmieniłeś prywatne elementy</string>
|
||||
<string name="backup_review_private_wiped_body">Są zaszyfrowane, więc tylko Ty możesz zobaczyć, co to było. Odtworzenie przywróci je wszystkie.</string>
|
||||
<string name="backup_review_private_wiped_title">Usunąłeś wszystkie prywatne elementy</string>
|
||||
<string name="backup_review_receiving_tag">Pobieranie</string>
|
||||
<string name="backup_review_renamed">zmieniono nazwę</string>
|
||||
<string name="backup_review_renamed_tag">Zmieniono nazwę</string>
|
||||
<string name="backup_review_saved">Na tym urządzeniu</string>
|
||||
<string name="backup_review_search_people">Szukaj %1$s osób</string>
|
||||
<string name="backup_review_searching_tag">Szukam</string>
|
||||
<string name="backup_review_service">Serwis</string>
|
||||
<string name="backup_review_service_followers">Obserwujący</string>
|
||||
<string name="backup_review_service_rank">Ranking</string>
|
||||
<string name="backup_review_service_topics">Tematy</string>
|
||||
<string name="backup_review_services_changed">Zmieniono %1$s z %2$s serwisów</string>
|
||||
<string name="backup_review_services_changed_explainer">Teraz pochodzą od kogoś innego albo od nikogo</string>
|
||||
<string name="backup_review_still_blocked">Nadal zablokowana</string>
|
||||
<string name="backup_review_storing_tag">Przechowywanie</string>
|
||||
<string name="backup_review_tab_dropped">Usunięte · %1$s</string>
|
||||
<string name="backup_review_tab_edited">Edytowane · %1$s</string>
|
||||
<string name="backup_review_tab_new">Nowe · %1$s</string>
|
||||
<string name="backup_review_title_cleared">%1$s wyczyszczono</string>
|
||||
<string name="backup_review_title_updated">%1$s zaktualizowano</string>
|
||||
<string name="backup_review_topics_gone">tematy zniknęły</string>
|
||||
<string name="backup_review_trust_warning">Rankingi, liczba obserwujących i filtrowanie spamu, które widzisz, pochodzą od tych dostawców.</string>
|
||||
<string name="backup_review_trusted_tag">Zaufane</string>
|
||||
<string name="backup_review_unblocked">%1$s odblokowane</string>
|
||||
<string name="backup_review_unblocked_explainer">Ametyst ponownie połączy się z nimi</string>
|
||||
<string name="backup_review_units_tag">Jednostek</string>
|
||||
<string name="backup_review_unmuted">%1$s odblokowanych</string>
|
||||
<string name="backup_review_unmuted_explainer">Mogą one ponownie pojawić się w Twoich informacjach</string>
|
||||
<string name="backup_review_untrusted_tag">Niezaufane</string>
|
||||
<string name="backup_review_wallet_body">Minty i klucze w Twoim portfelu są zaszyfrowane dla Ciebie, więc nie można ich tutaj porównać pozycja po pozycji. Przywrócenie danych powoduje przywrócenie dokładnie tego, co zostało zapisane na tym urządzeniu.</string>
|
||||
<string name="backup_review_was_named">było „%1$s”</string>
|
||||
<string name="backup_review_words_and_hashtags">Wyrazy & hasztagi</string>
|
||||
<string name="backup_type_app_settings">zsynchronizowane ustawienia aplikacji</string>
|
||||
<string name="backup_type_app_settings_explainer">Ustawienia Amethyst są synchronizowane na wszystkich Twoich urządzeniach. Są one zaszyfrowane, więc można porównać jedynie sam fakt ich obecności.</string>
|
||||
<string name="backup_type_blocked_relays">lista zablokowanych przekaźników</string>
|
||||
<string name="backup_type_blocked_relays_explainer">Transmitery, z którymi ta aplikacja nigdy się nie łączy.</string>
|
||||
<string name="backup_type_bolt12_offers">Oferta BOLT12</string>
|
||||
<string name="backup_type_bolt12_offers_explainer">Ta możliwość pozwala innym płacić Ci za pomocą Lightning.</string>
|
||||
<string name="backup_type_cashu_wallet">Portfel Cashu</string>
|
||||
<string name="backup_type_cashu_wallet_explainer">Ustawienia portfela ecash oraz minty. Są one zaszyfrowane, więc można porównać jedynie sam fakt ich istnienia.</string>
|
||||
<string name="backup_type_communities">lista społeczności</string>
|
||||
<string name="backup_type_communities_explainer">Społeczności, do których dołączyłeś.</string>
|
||||
<string name="backup_type_concord_communities">Lista społeczności Concord</string>
|
||||
<string name="backup_type_concord_communities_explainer">Społeczności Concord, do których dołączyłeś. Są one zaszyfrowane, więc można porównać jedynie fakt ich istnienia.</string>
|
||||
<string name="backup_type_dm_relays">Lista transmiterów DM</string>
|
||||
<string name="backup_type_dm_relays_explainer">Gdzie inni dostarczają Twoje prywatne wiadomości.</string>
|
||||
<string name="backup_type_ephemeral_chats">lista czatów efemerycznych</string>
|
||||
<string name="backup_type_ephemeral_chats_explainer">Tymczasowe czaty, do których dołączyłeś.</string>
|
||||
<string name="backup_type_favorite_algo_feeds">lista ulubionych kanałów</string>
|
||||
<string name="backup_type_favorite_algo_feeds_explainer">Zapisane przez Ciebie kanały algorytmiczne.</string>
|
||||
<string name="backup_type_follow_list">lista obserwowanych</string>
|
||||
<string name="backup_type_follow_list_explainer">Określa, czyje posty pojawiają się w Twoim kanale głównym.</string>
|
||||
<string name="backup_type_geohashes">obserwowane lokalizacje</string>
|
||||
<string name="backup_type_geohashes_explainer">Miejsca, z których posty pojawiają się na Twoich kanałach.</string>
|
||||
<string name="backup_type_hashtags">obserwowane hashtagi</string>
|
||||
<string name="backup_type_hashtags_explainer">Hashtagi, z których pochodzą posty wyświetlane w Twoich kanałach.</string>
|
||||
<string name="backup_type_indexer_relays">lista transmiterów indeksujących</string>
|
||||
<string name="backup_type_indexer_relays_explainer">Transmitery służące do wyszukiwania profili innych osób oraz list transmiterów.</string>
|
||||
<string name="backup_type_key_package_relays">transmitery kluczy czatu grupowego</string>
|
||||
<string name="backup_type_key_package_relays_explainer">Gdzie inni znajdą klucze do dodawania cię do zaszyfrowanych czatów grupowych.</string>
|
||||
<string name="backup_type_mute_list">lista zablokowanych</string>
|
||||
<string name="backup_type_mute_list_explainer">Ukrywa osoby, słowa, hashtagi i wątki we wszystkich wyświetlanych treściach.</string>
|
||||
<string name="backup_type_nutzap_info">ustawienia odbioru nutzap</string>
|
||||
<string name="backup_type_nutzap_info_explainer">Minty i klucz, które inni używają do wysyłania ci „nutzapów”.</string>
|
||||
<string name="backup_type_other">lista</string>
|
||||
<string name="backup_type_other_explainer">Lista zapisana na tym urządzeniu.</string>
|
||||
<string name="backup_type_outbox_inbox_relays">lista publicznych transmiterów</string>
|
||||
<string name="backup_type_outbox_inbox_relays_explainer">Informuje wszystkich, gdzie mogą znaleźć Twoje posty oraz gdzie mają wysyłać Ci odpowiedzi i wzmianki.</string>
|
||||
<string name="backup_type_payment_targets">adresy płatności</string>
|
||||
<string name="backup_type_payment_targets_explainer">Sposoby, w jakie inni mogą Ci zapłacić.</string>
|
||||
<string name="backup_type_private_outbox_relays">lista prywatnych transmiterów</string>
|
||||
<string name="backup_type_private_outbox_relays_explainer">Gdzie przechowywane są Twoje projekty i prywatne dane.</string>
|
||||
<string name="backup_type_profile">profil</string>
|
||||
<string name="backup_type_profile_explainer">Twoje imię i nazwisko, zdjęcie, biografia oraz adresy do płatności – tak, jak widzą je wszyscy.</string>
|
||||
<string name="backup_type_public_chats">lista czatów publicznych</string>
|
||||
<string name="backup_type_public_chats_explainer">Publiczne czaty, do których dołączyłeś.</string>
|
||||
<string name="backup_type_relay_feeds">ulubione kanały transmitera</string>
|
||||
<string name="backup_type_relay_feeds_explainer">Transmitery, które przeglądasz jako kanały informacyjne.</string>
|
||||
<string name="backup_type_relay_groups">lista grup</string>
|
||||
<string name="backup_type_relay_groups_explainer">Grupy oparte na transmiterach, do których dołączyłeś.</string>
|
||||
<string name="backup_type_search_relays">lista transmiterów wyszukiwania</string>
|
||||
<string name="backup_type_search_relays_explainer">Transmitery używane podczas wyszukiwania.</string>
|
||||
<string name="backup_type_trust_providers">lista zaufanych dostawców</string>
|
||||
<string name="backup_type_trust_providers_explainer">Serwisy, którym ufasz, a które zajmują się klasyfikowaniem i weryfikacją osób w Twoim imieniu.</string>
|
||||
<string name="backup_type_trusted_relays">lista zaufanych transmiterów</string>
|
||||
<string name="backup_type_trusted_relays_explainer">Zaufane transmitery, z którymi bez wahania nawiązujesz połączenie.</string>
|
||||
</resources>
|
||||
|
||||
@@ -5482,4 +5482,574 @@
|
||||
<string name="cyberspace_bag_unsigned">Unsigned, so this author is a claim</string>
|
||||
<string name="cyberspace_bag_unknown_kind">An item of kind %1$d, which this client does not draw</string>
|
||||
<string name="cyberspace_bag_opaque">%1$d bytes of something this client does not read</string>
|
||||
<string name="backup_action_block_again">Block %1$s again</string>
|
||||
<string name="backup_action_keep_count">Keep %1$s</string>
|
||||
<string name="backup_action_rejoin">Rejoin %1$s</string>
|
||||
<string name="backup_action_remute">Re-mute %1$s</string>
|
||||
<string name="backup_action_restore_count">Restore %1$s</string>
|
||||
<string name="backup_action_restore_feeds">Restore feeds</string>
|
||||
<string name="backup_action_restore_places">Restore places</string>
|
||||
<string name="backup_action_restore_profile">Restore profile</string>
|
||||
<string name="backup_action_restore_providers">Restore providers</string>
|
||||
<string name="backup_action_restore_relays">Restore relays</string>
|
||||
<string name="backup_action_restore_topics">Restore topics</string>
|
||||
<string name="backup_action_restore_wallet">Restore wallet</string>
|
||||
<string name="backup_card_accept">Accept</string>
|
||||
<plurals name="backup_card_and_added">
|
||||
<item quantity="one">%1$s and added %2$d</item>
|
||||
<item quantity="other">%1$s and added %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_blocked">
|
||||
<item quantity="one">%1$s and blocked %2$d</item>
|
||||
<item quantity="other">%1$s and blocked %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_followed">
|
||||
<item quantity="one">%1$s and followed %2$d</item>
|
||||
<item quantity="other">%1$s and followed %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_joined">
|
||||
<item quantity="one">%1$s and joined %2$d</item>
|
||||
<item quantity="other">%1$s and joined %2$d</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_and_muted">
|
||||
<item quantity="one">%1$s and muted %2$d</item>
|
||||
<item quantity="other">%1$s and muted %2$d</item>
|
||||
</plurals>
|
||||
<string name="backup_card_app_settings">Your Amethyst synced app settings changed in another app that is not Amethyst. This can create problems.</string>
|
||||
<string name="backup_card_concord_emptied">You emptied your Concord list</string>
|
||||
<string name="backup_card_concord_rewritten">You changed your Concord list</string>
|
||||
<plurals name="backup_card_dm_relays_lost">
|
||||
<item quantity="one">You removed %1$d DM relay</item>
|
||||
<item quantity="other">You removed %1$d DM relays</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_feeds_removed">
|
||||
<item quantity="one">You removed %1$d favorite feed</item>
|
||||
<item quantity="other">You removed %1$d favorite feeds</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_follows_dropped">
|
||||
<item quantity="one">You unfollowed %1$d person</item>
|
||||
<item quantity="other">You unfollowed %1$d people</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_hashtags_unfollowed">
|
||||
<item quantity="one">You unfollowed %1$d hashtag</item>
|
||||
<item quantity="other">You unfollowed %1$d hashtags</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_indexer_relays_lost">
|
||||
<item quantity="one">You removed %1$d indexer relay</item>
|
||||
<item quantity="other">You removed %1$d indexer relays</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_key_package_relays_lost">
|
||||
<item quantity="one">You removed %1$d group-chat key relay</item>
|
||||
<item quantity="other">You removed %1$d group-chat key relays</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_chats">
|
||||
<item quantity="one">You left %1$d public chat</item>
|
||||
<item quantity="other">You left %1$d public chats</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_communities">
|
||||
<item quantity="one">You left %1$d community</item>
|
||||
<item quantity="other">You left %1$d communities</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_groups">
|
||||
<item quantity="one">You left %1$d group</item>
|
||||
<item quantity="other">You left %1$d groups</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_leave_rooms">
|
||||
<item quantity="one">You left %1$d chat room</item>
|
||||
<item quantity="other">You left %1$d chat rooms</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_mutes_visible">
|
||||
<item quantity="one">You unmuted %1$d thing</item>
|
||||
<item quantity="other">You unmuted %1$d things</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_nip65_lost">
|
||||
<item quantity="one">You removed %1$d public relay</item>
|
||||
<item quantity="other">You removed %1$d public relays</item>
|
||||
</plurals>
|
||||
<string name="backup_card_nutzap_key_removed">You removed your nutzap key</string>
|
||||
<string name="backup_card_nutzap_key_replaced">You replaced your nutzap key</string>
|
||||
<plurals name="backup_card_nutzap_mints_removed">
|
||||
<item quantity="one">You removed %1$d nutzap mint</item>
|
||||
<item quantity="other">You removed %1$d nutzap mints</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_offers_removed">
|
||||
<item quantity="one">You removed %1$d BOLT12 offer</item>
|
||||
<item quantity="other">You removed %1$d BOLT12 offers</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_payment_targets_removed">
|
||||
<item quantity="one">You removed %1$d way to get paid</item>
|
||||
<item quantity="other">You removed %1$d ways to get paid</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_places_unfollowed">
|
||||
<item quantity="one">You unfollowed %1$d place</item>
|
||||
<item quantity="other">You unfollowed %1$d places</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_private_outbox_lost">
|
||||
<item quantity="one">You removed %1$d private relay</item>
|
||||
<item quantity="other">You removed %1$d private relays</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_profile_lost_fields">
|
||||
<item quantity="one">You removed %1$d profile field</item>
|
||||
<item quantity="other">You removed %1$d profile fields</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_relay_feeds_lost">
|
||||
<item quantity="one">You removed %1$d relay feed</item>
|
||||
<item quantity="other">You removed %1$d relay feeds</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_search_relays_lost">
|
||||
<item quantity="one">You removed %1$d search relay</item>
|
||||
<item quantity="other">You removed %1$d search relays</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trust_services_changed">
|
||||
<item quantity="one">You changed the provider of %1$d trust service</item>
|
||||
<item quantity="other">You changed the provider of %1$d trust services</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_trusted_lost">
|
||||
<item quantity="one">You stopped trusting %1$d relay</item>
|
||||
<item quantity="other">You stopped trusting %1$d relays</item>
|
||||
</plurals>
|
||||
<plurals name="backup_card_unblocked">
|
||||
<item quantity="one">You unblocked %1$d relay</item>
|
||||
<item quantity="other">You unblocked %1$d relays</item>
|
||||
</plurals>
|
||||
<string name="backup_card_wallet_emptied">You emptied your Cashu wallet</string>
|
||||
<string name="backup_card_wallet_rewritten">You changed your Cashu wallet</string>
|
||||
<string name="backup_conflict_added">Added (%1$s)</string>
|
||||
<string name="backup_conflict_changed">Changed (%1$s)</string>
|
||||
<string name="backup_conflict_count_added">%1$s added</string>
|
||||
<string name="backup_conflict_count_changed">%1$s changed</string>
|
||||
<string name="backup_conflict_count_removed">%1$s removed</string>
|
||||
<string name="backup_conflict_keep_new">Use new version</string>
|
||||
<string name="backup_conflict_private_added">You added private (encrypted) items.</string>
|
||||
<string name="backup_conflict_private_changed">You also changed private (encrypted) items. They can't be compared here.</string>
|
||||
<string name="backup_conflict_private_cleared">You removed all private (encrypted) items.</string>
|
||||
<string name="backup_conflict_relay_read_only">read only</string>
|
||||
<string name="backup_conflict_relay_read_write">read and write</string>
|
||||
<string name="backup_conflict_relay_write_only">write only</string>
|
||||
<string name="backup_conflict_removed">Removed (%1$s)</string>
|
||||
<string name="backup_conflict_restore_mine">Restore saved version</string>
|
||||
<string name="backup_conflict_title">You changed your %1$s in another app</string>
|
||||
<string name="backup_entry_algo_feed">Feeds</string>
|
||||
<string name="backup_entry_chat_room">Chat rooms</string>
|
||||
<string name="backup_entry_community">Communities</string>
|
||||
<string name="backup_entry_hashtag">Hashtags</string>
|
||||
<string name="backup_entry_identity_claim">Linked identities</string>
|
||||
<string name="backup_entry_location">Locations</string>
|
||||
<string name="backup_entry_mint">Mints</string>
|
||||
<string name="backup_entry_nutzap_key">Nutzap keys</string>
|
||||
<string name="backup_entry_offer">Offers</string>
|
||||
<string name="backup_entry_other">Other entries</string>
|
||||
<string name="backup_entry_payment_target">Payment addresses</string>
|
||||
<string name="backup_entry_person">People</string>
|
||||
<string name="backup_entry_profile_field">Profile fields</string>
|
||||
<string name="backup_entry_public_chat">Public chats</string>
|
||||
<string name="backup_entry_relay">Relays</string>
|
||||
<string name="backup_entry_relay_group">Groups</string>
|
||||
<string name="backup_entry_thread">Threads</string>
|
||||
<string name="backup_entry_trust_provider">Trust providers</string>
|
||||
<string name="backup_entry_word">Words</string>
|
||||
<string name="backup_profile_field_about">About</string>
|
||||
<string name="backup_profile_field_banner">Banner</string>
|
||||
<string name="backup_profile_field_birthday">Birthday</string>
|
||||
<string name="backup_profile_field_bot">Bot flag</string>
|
||||
<string name="backup_profile_field_clink_offer">CLINK offer</string>
|
||||
<string name="backup_profile_field_display_name">Display name</string>
|
||||
<string name="backup_profile_field_lud06">LNURL</string>
|
||||
<string name="backup_profile_field_lud16">Lightning address</string>
|
||||
<string name="backup_profile_field_name">Username</string>
|
||||
<string name="backup_profile_field_nip05">Nostr address</string>
|
||||
<string name="backup_profile_field_picture">Picture</string>
|
||||
<string name="backup_profile_field_pronouns">Pronouns</string>
|
||||
<string name="backup_profile_field_website">Website</string>
|
||||
<string name="backup_review_allowed_tag">Allowed</string>
|
||||
<string name="backup_review_changed_by_other_app">Changed in another app · %1$s</string>
|
||||
<string name="backup_review_concord_body">Your Concord communities are encrypted to you, so they can't be compared here. Restoring puts back exactly what this device saved.</string>
|
||||
<string name="backup_review_demoted_tag">Moved</string>
|
||||
<string name="backup_review_dropped_count">%1$s dropped</string>
|
||||
<string name="backup_review_dropped_tag">Dropped</string>
|
||||
<string name="backup_review_encrypted_added">You created it</string>
|
||||
<string name="backup_review_encrypted_changed">You changed it</string>
|
||||
<string name="backup_review_encrypted_cleared">You emptied it</string>
|
||||
<string name="backup_review_feed">Feed</string>
|
||||
<string name="backup_review_gone">Gone</string>
|
||||
<string name="backup_review_hashtags_you_follow">Hashtags you follow</string>
|
||||
<string name="backup_review_inbox">Inbox</string>
|
||||
<string name="backup_review_inbox_explainer">where others reach you</string>
|
||||
<string name="backup_review_joined">joined</string>
|
||||
<string name="backup_review_kept">kept</string>
|
||||
<string name="backup_review_kept_count">%1$s kept</string>
|
||||
<string name="backup_review_key_removed">Receiving key removed</string>
|
||||
<string name="backup_review_key_replaced">Receiving key replaced</string>
|
||||
<string name="backup_review_key_warning">Nutzaps will be locked to this new key. If this device doesn't have it, you may not be able to redeem them here.</string>
|
||||
<string name="backup_review_left">left</string>
|
||||
<string name="backup_review_left_tag">Left</string>
|
||||
<string name="backup_review_listed_tag">Listed</string>
|
||||
<string name="backup_review_moved_tag">Moved</string>
|
||||
<string name="backup_review_names_and_more">%1$s and %2$s more</string>
|
||||
<string name="backup_review_new">New version</string>
|
||||
<string name="backup_review_new_count">%1$s new</string>
|
||||
<string name="backup_review_new_count_caption">new</string>
|
||||
<string name="backup_review_new_tag">New</string>
|
||||
<string name="backup_review_newly_blocked">Newly blocked</string>
|
||||
<string name="backup_review_newly_muted">%1$s newly muted</string>
|
||||
<string name="backup_review_no_longer_blocked">No longer blocked</string>
|
||||
<string name="backup_review_not_set">Not set</string>
|
||||
<string name="backup_review_nothing_here">Nothing here</string>
|
||||
<string name="backup_review_offer">BOLT12 offer</string>
|
||||
<plurals name="backup_review_offers_gone">
|
||||
<item quantity="one">%1$d offer removed</item>
|
||||
<item quantity="other">%1$d offers removed</item>
|
||||
</plurals>
|
||||
<string name="backup_review_outbox">Outbox</string>
|
||||
<string name="backup_review_outbox_explainer">where you publish</string>
|
||||
<plurals name="backup_review_payment_targets_gone">
|
||||
<item quantity="one">%1$d way to pay you removed</item>
|
||||
<item quantity="other">%1$d ways to pay you removed</item>
|
||||
</plurals>
|
||||
<string name="backup_review_payments_explainer">People paying you only see what's in this list.</string>
|
||||
<string name="backup_review_places_gone">places gone</string>
|
||||
<string name="backup_review_places_you_follow">Places you follow</string>
|
||||
<string name="backup_review_private_added_body">They're encrypted now, which is likely where the public items above went.</string>
|
||||
<string name="backup_review_private_added_title">You made items private</string>
|
||||
<string name="backup_review_private_changed_body">They're encrypted, so they can't be compared here.</string>
|
||||
<string name="backup_review_private_changed_title">You changed private items</string>
|
||||
<string name="backup_review_private_wiped_body">They're encrypted, so only you can see what they were. Restoring brings them all back.</string>
|
||||
<string name="backup_review_private_wiped_title">You removed all private items</string>
|
||||
<string name="backup_review_receiving_tag">Receiving</string>
|
||||
<string name="backup_review_renamed">renamed</string>
|
||||
<string name="backup_review_renamed_tag">Renamed</string>
|
||||
<string name="backup_review_saved">On this device</string>
|
||||
<string name="backup_review_search_people">Search %1$s people</string>
|
||||
<string name="backup_review_searching_tag">Searching</string>
|
||||
<string name="backup_review_service">Service</string>
|
||||
<string name="backup_review_service_followers">Followers</string>
|
||||
<string name="backup_review_service_rank">Rank</string>
|
||||
<string name="backup_review_service_topics">Topics</string>
|
||||
<string name="backup_review_services_changed">%1$s of %2$s services changed</string>
|
||||
<string name="backup_review_services_changed_explainer">They now come from someone else, or no one</string>
|
||||
<string name="backup_review_still_blocked">Still blocked</string>
|
||||
<string name="backup_review_storing_tag">Storing</string>
|
||||
<string name="backup_review_tab_dropped">Dropped · %1$s</string>
|
||||
<string name="backup_review_tab_edited">Edited · %1$s</string>
|
||||
<string name="backup_review_tab_new">New · %1$s</string>
|
||||
<string name="backup_review_title_cleared">%1$s cleared</string>
|
||||
<string name="backup_review_title_updated">%1$s updated</string>
|
||||
<string name="backup_review_topics_gone">topics gone</string>
|
||||
<string name="backup_review_trust_warning">Ranks, follower counts and spam filtering you see come from these providers.</string>
|
||||
<string name="backup_review_trusted_tag">Trusted</string>
|
||||
<string name="backup_review_unblocked">%1$s unblocked</string>
|
||||
<string name="backup_review_unblocked_explainer">Amethyst will connect to them again</string>
|
||||
<string name="backup_review_units_tag">Units</string>
|
||||
<string name="backup_review_unmuted">%1$s unmuted</string>
|
||||
<string name="backup_review_unmuted_explainer">These can reach your feeds again</string>
|
||||
<string name="backup_review_untrusted_tag">Untrusted</string>
|
||||
<string name="backup_review_wallet_body">Your wallet's mints and keys are encrypted to you, so they can't be compared item by item here. Restoring puts back exactly what this device saved.</string>
|
||||
<string name="backup_review_was_named">was “%1$s”</string>
|
||||
<string name="backup_review_words_and_hashtags">Words & hashtags</string>
|
||||
<string name="backup_type_app_settings">synced app settings</string>
|
||||
<string name="backup_type_app_settings_explainer">Amethyst settings synced across your devices. They are encrypted, so only their presence can be compared.</string>
|
||||
<string name="backup_type_blocked_relays">blocked relay list</string>
|
||||
<string name="backup_type_blocked_relays_explainer">Relays this app never connects to.</string>
|
||||
<string name="backup_type_bolt12_offers">BOLT12 offers</string>
|
||||
<string name="backup_type_bolt12_offers_explainer">The lightning offers others use to pay you.</string>
|
||||
<string name="backup_type_cashu_wallet">Cashu wallet</string>
|
||||
<string name="backup_type_cashu_wallet_explainer">Your ecash wallet settings and mints. They are encrypted, so only their presence can be compared.</string>
|
||||
<string name="backup_type_communities">community list</string>
|
||||
<string name="backup_type_communities_explainer">The communities you joined.</string>
|
||||
<string name="backup_type_concord_communities">Concord community list</string>
|
||||
<string name="backup_type_concord_communities_explainer">The Concord communities you joined. They are encrypted, so only their presence can be compared.</string>
|
||||
<string name="backup_type_dm_relays">DM relay list</string>
|
||||
<string name="backup_type_dm_relays_explainer">Where others deliver your private messages.</string>
|
||||
<string name="backup_type_ephemeral_chats">ephemeral chat list</string>
|
||||
<string name="backup_type_ephemeral_chats_explainer">The ephemeral chat rooms you joined.</string>
|
||||
<string name="backup_type_favorite_algo_feeds">favorite feeds list</string>
|
||||
<string name="backup_type_favorite_algo_feeds_explainer">The algorithmic feeds you saved.</string>
|
||||
<string name="backup_type_follow_list">follow list</string>
|
||||
<string name="backup_type_follow_list_explainer">Decides whose posts appear in your home feed.</string>
|
||||
<string name="backup_type_geohashes">followed locations</string>
|
||||
<string name="backup_type_geohashes_explainer">Locations whose posts appear in your feeds.</string>
|
||||
<string name="backup_type_hashtags">followed hashtags</string>
|
||||
<string name="backup_type_hashtags_explainer">Hashtags whose posts appear in your feeds.</string>
|
||||
<string name="backup_type_indexer_relays">indexer relay list</string>
|
||||
<string name="backup_type_indexer_relays_explainer">The relays used to find other people's profiles and relay lists.</string>
|
||||
<string name="backup_type_key_package_relays">group-chat key relays</string>
|
||||
<string name="backup_type_key_package_relays_explainer">Where others find the keys to add you to encrypted group chats.</string>
|
||||
<string name="backup_type_mute_list">mute list</string>
|
||||
<string name="backup_type_mute_list_explainer">Hides people, words, hashtags and threads from everything you see.</string>
|
||||
<string name="backup_type_nutzap_info">nutzap receiving settings</string>
|
||||
<string name="backup_type_nutzap_info_explainer">The mints and key others use to send you nutzaps.</string>
|
||||
<string name="backup_type_other">list</string>
|
||||
<string name="backup_type_other_explainer">A list saved on this device.</string>
|
||||
<string name="backup_type_outbox_inbox_relays">public relay list</string>
|
||||
<string name="backup_type_outbox_inbox_relays_explainer">Tells everyone where to find your posts and where to send you replies and mentions.</string>
|
||||
<string name="backup_type_payment_targets">payment addresses</string>
|
||||
<string name="backup_type_payment_targets_explainer">The ways other people can pay you.</string>
|
||||
<string name="backup_type_private_outbox_relays">private relay list</string>
|
||||
<string name="backup_type_private_outbox_relays_explainer">Where your drafts and private data are stored.</string>
|
||||
<string name="backup_type_profile">profile</string>
|
||||
<string name="backup_type_profile_explainer">Your name, picture, bio and payment addresses, as everyone sees them.</string>
|
||||
<string name="backup_type_public_chats">public chat list</string>
|
||||
<string name="backup_type_public_chats_explainer">The public chats you joined.</string>
|
||||
<string name="backup_type_relay_feeds">favorite relay feeds</string>
|
||||
<string name="backup_type_relay_feeds_explainer">The relays you browse as feeds.</string>
|
||||
<string name="backup_type_relay_groups">group list</string>
|
||||
<string name="backup_type_relay_groups_explainer">The relay-based groups you joined.</string>
|
||||
<string name="backup_type_search_relays">search relay list</string>
|
||||
<string name="backup_type_search_relays_explainer">The relays used when you search.</string>
|
||||
<string name="backup_type_trust_providers">trust provider list</string>
|
||||
<string name="backup_type_trust_providers_explainer">The services you trust to rank and verify people for you.</string>
|
||||
<string name="backup_type_trusted_relays">trusted relay list</string>
|
||||
<string name="backup_type_trusted_relays_explainer">Relays you trust to connect to without asking.</string>
|
||||
<string name="cordn_action_delete">Delete</string>
|
||||
<string name="cordn_action_edit">Edit</string>
|
||||
<string name="cordn_action_editing">Editing your message</string>
|
||||
<string name="cordn_action_go_to_message">Go to message</string>
|
||||
<string name="cordn_action_pin">Pin</string>
|
||||
<string name="cordn_action_reply">Reply</string>
|
||||
<string name="cordn_action_unpin">Unpin</string>
|
||||
<string name="cordn_admin_action_failed">That change could not be made.</string>
|
||||
<string name="cordn_admin_coordinator_silent">The coordinator did not answer, so nothing was changed. Try again in a moment.</string>
|
||||
<string name="cordn_admin_no_key_package">%1$s has not published a key package to this coordinator, so they cannot be added yet. Ask them to open cordn on this coordinator first.</string>
|
||||
<string name="cordn_admin_no_self_remove">You cannot remove yourself from a cordn group.</string>
|
||||
<string name="cordn_admin_no_welcome">%1$s could not be given a way into the group, so the add was abandoned.</string>
|
||||
<string name="cordn_admin_not_a_member">%1$s is not in this group.</string>
|
||||
<string name="cordn_admin_someone">That person</string>
|
||||
<string name="cordn_admin_wrong_key_package">This coordinator served a key package that belongs to someone else, so %1$s was not added. Nothing was changed.</string>
|
||||
<string name="cordn_backup_contents_body">Your group encryption keys, your key packages, and every message in those groups. Anyone who opens it can read the conversations. The passphrase is the only thing protecting it once it leaves Amethyst.</string>
|
||||
<string name="cordn_backup_contents_title">What is in the file</string>
|
||||
<string name="cordn_backup_explainer">Your nsec cannot bring cordn groups back. A cordn group lives as encryption state on this device and an ordered stream on a coordinator that cannot read it — lose the device without a backup and the group is gone, including everything already said in it.</string>
|
||||
<string name="cordn_backup_export">Export</string>
|
||||
<string name="cordn_backup_exported">Backup saved.</string>
|
||||
<string name="cordn_backup_failed">That did not work. Check the passphrase and the file.</string>
|
||||
<string name="cordn_backup_passphrase">Passphrase</string>
|
||||
<string name="cordn_backup_restore">Restore</string>
|
||||
<string name="cordn_backup_restore_body">Restoring replaces the cordn groups on this device with the ones in the file. It is for a phone that has taken over from another — not a way to use the same groups on two devices at once.</string>
|
||||
<string name="cordn_backup_restore_confirm_body">Every cordn group now on this device will be removed and replaced by the ones in the file.\n\nDo not restore onto a second phone while the first is still in use. Both would hold the same group keys, and once both have sent a message the group breaks for everyone — silently, and with no way back.</string>
|
||||
<string name="cordn_backup_restore_confirm_title">Replace this device's cordn groups?</string>
|
||||
<string name="cordn_backup_restore_title">Restore</string>
|
||||
<string name="cordn_backup_restored">Restored.</string>
|
||||
<string name="cordn_chat_empty_description">Anything sent here is encrypted for this group. The coordinator relays it without being able to read it.</string>
|
||||
<string name="cordn_chat_empty_title">No messages yet</string>
|
||||
<string name="cordn_chat_unread_divider">New messages</string>
|
||||
<string name="cordn_chat_yesterday">Yesterday</string>
|
||||
<string name="cordn_composer_hint">Message</string>
|
||||
<string name="cordn_coordinators_add_action">Add</string>
|
||||
<string name="cordn_coordinators_add_failed">Could not open that coordinator.</string>
|
||||
<string name="cordn_coordinators_copy_key">Copy the coordinator's npub</string>
|
||||
<string name="cordn_coordinators_discover_action">Look for coordinators</string>
|
||||
<string name="cordn_coordinators_discover_add">Add</string>
|
||||
<string name="cordn_coordinators_discover_explainer">Reads announcements your relays already carry. No coordinator is contacted, so none of them learns you looked.</string>
|
||||
<string name="cordn_coordinators_discover_failed">Could not read announcements</string>
|
||||
<string name="cordn_coordinators_discover_none">Nobody is announcing on your relays.</string>
|
||||
<string name="cordn_coordinators_discover_seen">Announced %1$s ago</string>
|
||||
<string name="cordn_coordinators_discover_seen_on">Last announced %1$s</string>
|
||||
<string name="cordn_coordinators_discover_unheard">Nothing found, and %1$d of your relays did not answer.</string>
|
||||
<string name="cordn_coordinators_explainer">A coordinator orders one group's messages and is the only thing that can. Losing it loses the ordering, and a second one does not mirror the first — so these are named things you choose, not interchangeable relays.</string>
|
||||
<string name="cordn_coordinators_health_down">Not answering — %1$d calls in a row have failed. Groups on it are not syncing.</string>
|
||||
<string name="cordn_coordinators_health_ok">Answering.</string>
|
||||
<string name="cordn_coordinators_health_retrying">A call failed; retrying.</string>
|
||||
<string name="cordn_coordinators_health_unknown">Nothing asked of it yet.</string>
|
||||
<string name="cordn_coordinators_hide_older">Hide the ones that stopped announcing</string>
|
||||
<string name="cordn_coordinators_identify">Ask who it is</string>
|
||||
<string name="cordn_coordinators_key">Coordinator key</string>
|
||||
<string name="cordn_coordinators_label">A name for it (yours, optional)</string>
|
||||
<string name="cordn_coordinators_label_note">This name is yours and stays on this device. A coordinator cannot prove a name, so it is never asked for one.</string>
|
||||
<string name="cordn_coordinators_more">More actions</string>
|
||||
<string name="cordn_coordinators_none">No coordinators yet.</string>
|
||||
<string name="cordn_coordinators_purge">Purge</string>
|
||||
<string name="cordn_coordinators_purge_body">Removing keeps the groups on this device, so adding the coordinator back brings them with it. Purging deletes them: the group keys, the read positions and your key packages all go, and those groups can only be re-entered by a fresh invitation.\n\nThe coordinator is not told and keeps whatever it already had.</string>
|
||||
<string name="cordn_coordinators_purge_title">Purge this coordinator?</string>
|
||||
<string name="cordn_coordinators_relays">%1$s</string>
|
||||
<string name="cordn_coordinators_relays_label">Answers on</string>
|
||||
<string name="cordn_coordinators_relays_more">%1$s +%2$d more</string>
|
||||
<string name="cordn_coordinators_remove">Remove</string>
|
||||
<string name="cordn_coordinators_rename">Rename</string>
|
||||
<string name="cordn_coordinators_server">Says it is: %1$s</string>
|
||||
<string name="cordn_coordinators_server_claim">A coordinator's name and version are strings it chose. Its public key is the only thing that identifies it.</string>
|
||||
<string name="cordn_coordinators_server_silent">Answered, but named nothing.</string>
|
||||
<string name="cordn_coordinators_show_all">Show all %1$d</string>
|
||||
<string name="cordn_coordinators_show_fewer">Show fewer</string>
|
||||
<string name="cordn_coordinators_show_older">Show %1$d that stopped announcing</string>
|
||||
<string name="cordn_coordinators_stale_note">These have not announced in over a month. Creating a group on one that has gone away will fail.</string>
|
||||
<string name="cordn_create_action">Create group</string>
|
||||
<plurals name="cordn_create_action_invite">
|
||||
<item quantity="one">Create and invite %1$d person</item>
|
||||
<item quantity="other">Create and invite %1$d people</item>
|
||||
</plurals>
|
||||
<string name="cordn_create_add_member">Add someone</string>
|
||||
<string name="cordn_create_admin">Admin</string>
|
||||
<plurals name="cordn_create_admin_count">
|
||||
<item quantity="one">%1$d person can add and remove</item>
|
||||
<item quantity="other">%1$d people can add and remove</item>
|
||||
</plurals>
|
||||
<string name="cordn_create_admin_only_me">Only I manage this group</string>
|
||||
<string name="cordn_create_admin_only_me_on">Only you can invite, remove members or change the group's details. You can hand that to someone else later.</string>
|
||||
<string name="cordn_create_coordinator">Coordinator</string>
|
||||
<string name="cordn_create_coordinator_change">Change</string>
|
||||
<string name="cordn_create_coordinator_discover">Find coordinators</string>
|
||||
<string name="cordn_create_coordinator_hide">Done</string>
|
||||
<string name="cordn_create_coordinator_new">Another coordinator</string>
|
||||
<string name="cordn_create_coordinator_pubkey">Coordinator public key (hex or npub)</string>
|
||||
<string name="cordn_create_coordinator_relays">Relays it answers on, one per line</string>
|
||||
<string name="cordn_create_coverage_all">Reaches all %1$d of your people</string>
|
||||
<string name="cordn_create_coverage_partial">Reaches %1$d of %2$d — the rest would be left out</string>
|
||||
<string name="cordn_create_coverage_unknown">Not checked — picking it will ask</string>
|
||||
<string name="cordn_create_description">Description (optional)</string>
|
||||
<string name="cordn_create_egalitarian">Everyone can add and remove</string>
|
||||
<string name="cordn_create_egalitarian_note">Everyone in the group can invite, remove members and change its details. Any member can name admins later, which ends that.</string>
|
||||
<string name="cordn_create_explainer">A cordn group is ordered by one coordinator you choose. Creating the group happens on this device — the coordinator only learns the group exists once you invite someone or send a message.</string>
|
||||
<string name="cordn_create_failed">The group could not be created.</string>
|
||||
<string name="cordn_create_name">Group name</string>
|
||||
<string name="cordn_create_no_coordinator">No coordinator chosen</string>
|
||||
<string name="cordn_create_outcome_explainer">Each invitation is a Welcome left on the coordinator, so they can fail one at a time. Nobody has been notified: they see it next time they open their app.</string>
|
||||
<string name="cordn_create_outcome_failed">The coordinator refused the invitation</string>
|
||||
<string name="cordn_create_outcome_link">Send a link</string>
|
||||
<string name="cordn_create_outcome_no_welcome">Added to the group, but the invitation did not reach them — try again from the group screen</string>
|
||||
<string name="cordn_create_outcome_open">Open the chat</string>
|
||||
<string name="cordn_create_outcome_skipped">No key here, so no Welcome could be left</string>
|
||||
<string name="cordn_create_outcome_title">The group exists</string>
|
||||
<string name="cordn_create_outcome_waiting">Waiting for them</string>
|
||||
<string name="cordn_create_people_done">Done</string>
|
||||
<string name="cordn_create_people_empty">Nobody added yet. A group can be created empty and invitations sent later, but naming people now is what shows which coordinator can reach them.</string>
|
||||
<string name="cordn_create_people_none">Nobody yet — tap to add people</string>
|
||||
<string name="cordn_create_people_note">Naming people now is what tells us which coordinator can reach them. Each one gets a Welcome left on that coordinator, which they pick up next time they open their app.</string>
|
||||
<plurals name="cordn_create_reach_count">
|
||||
<item quantity="one">Reachable on %1$d coordinator</item>
|
||||
<item quantity="other">Reachable on %1$d coordinators</item>
|
||||
</plurals>
|
||||
<string name="cordn_create_reach_none">No key on any coordinator you use</string>
|
||||
<string name="cordn_create_reach_unknown">Not checked yet</string>
|
||||
<string name="cordn_create_step_admins">Who can add and remove</string>
|
||||
<string name="cordn_create_step_name">Name it</string>
|
||||
<string name="cordn_create_step_people">Who is in it</string>
|
||||
<string name="cordn_create_step_where">Where it lives</string>
|
||||
<string name="cordn_create_title">New Cordn group</string>
|
||||
<plurals name="cordn_create_unreachable_count">
|
||||
<item quantity="one">%1$d person cannot be reached by any coordinator you use</item>
|
||||
<item quantity="other">%1$d people cannot be reached by any coordinator you use</item>
|
||||
</plurals>
|
||||
<string name="cordn_create_you">You, always an admin</string>
|
||||
<string name="cordn_delete_confirm_body">Everyone in the group will see this message as withdrawn, and Amethyst will stop showing its text. The coordinator still holds the encrypted copy it was sent as, and anyone who already read it has already read it.</string>
|
||||
<string name="cordn_delete_confirm_title">Withdraw message</string>
|
||||
<string name="cordn_delivery_accepted">Accepted by the coordinator</string>
|
||||
<string name="cordn_exposure_close">Got it</string>
|
||||
<string name="cordn_exposure_open">What this coordinator can see</string>
|
||||
<string name="cordn_group_info">Group info</string>
|
||||
<string name="cordn_group_unavailable">This group is not available. Its coordinator may have been removed.</string>
|
||||
<string name="cordn_group_unavailable_detail">Add a coordinator in Settings to start using cordn groups.</string>
|
||||
<plurals name="cordn_groups_count">
|
||||
<item quantity="one">%1$d group</item>
|
||||
<item quantity="other">%1$d groups</item>
|
||||
</plurals>
|
||||
<string name="cordn_groups_down_note">Nothing is arriving from these groups. Amethyst keeps retrying.</string>
|
||||
<string name="cordn_groups_manage">Coordinators</string>
|
||||
<string name="cordn_groups_none">No cordn groups yet</string>
|
||||
<string name="cordn_groups_none_detail">A cordn group lives on one coordinator that holds its membership and passes messages along, without ever seeing what anyone writes.</string>
|
||||
<string name="cordn_groups_start">Start one</string>
|
||||
<string name="cordn_info_add_member">Add someone</string>
|
||||
<string name="cordn_info_add_member_none">Nobody found by that name.</string>
|
||||
<string name="cordn_info_add_member_note">They can only be added if they published a key package to this coordinator.</string>
|
||||
<string name="cordn_info_add_member_placeholder">Name, npub or name@domain</string>
|
||||
<string name="cordn_info_admin_badge">Admin</string>
|
||||
<plurals name="cordn_info_admins_kept">
|
||||
<item quantity="one">The group's %1$d admin stays as it is.</item>
|
||||
<item quantity="other">The group's %1$d admins stay as they are.</item>
|
||||
</plurals>
|
||||
<string name="cordn_info_coordinator">Coordinator</string>
|
||||
<string name="cordn_info_coordinator_key">Coordinator key</string>
|
||||
<string name="cordn_info_coordinator_nprofile">Coordinator link</string>
|
||||
<string name="cordn_info_copy_nprofile">Copy the coordinator's nprofile</string>
|
||||
<string name="cordn_info_edit_details">Edit details</string>
|
||||
<string name="cordn_info_egalitarian">This group has no admins: everyone can add, remove and rename, permanently.</string>
|
||||
<string name="cordn_info_epoch">Epoch</string>
|
||||
<string name="cordn_info_gid">Group id</string>
|
||||
<string name="cordn_info_has_key_package">Can be added on this coordinator</string>
|
||||
<string name="cordn_info_members">Members</string>
|
||||
<string name="cordn_info_remove_confirm_body">%1$s stops receiving messages from here. They keep what they have already read, and this cannot be undone — they would have to be invited again.</string>
|
||||
<string name="cordn_info_remove_confirm_title">Remove from group?</string>
|
||||
<string name="cordn_info_remove_member">Remove</string>
|
||||
<string name="cordn_info_save">Save</string>
|
||||
<string name="cordn_info_technical">Technical details</string>
|
||||
<string name="cordn_invitations_accept">Join</string>
|
||||
<string name="cordn_invitations_decline">Decline</string>
|
||||
<string name="cordn_invitations_decline_warning">Declining is permanent. Getting back in means being invited again.</string>
|
||||
<string name="cordn_invitations_explainer">Checked when you open this screen, and at no other time — asking a coordinator whether anyone invited you tells it you are here, so Amethyst does not do it in the background.</string>
|
||||
<string name="cordn_invitations_load_failed">Could not read invitations.</string>
|
||||
<plurals name="cordn_invitations_members">
|
||||
<item quantity="one">%1$d person is already in this group</item>
|
||||
<item quantity="other">%1$d people are already in this group</item>
|
||||
</plurals>
|
||||
<string name="cordn_invitations_members_more">+%1$d more</string>
|
||||
<string name="cordn_invitations_no_coordinators">You have no coordinator open. cordn invitations arrive through a coordinator, so there is nowhere to look yet.</string>
|
||||
<string name="cordn_invitations_none">No invitations waiting.</string>
|
||||
<string name="cordn_invitations_refresh">Check again</string>
|
||||
<string name="cordn_invitations_skipped">An invitation was left for another device</string>
|
||||
<string name="cordn_invitations_title">Cordn invitations</string>
|
||||
<string name="cordn_invitations_unreachable">%1$s did not answer</string>
|
||||
<string name="cordn_invitations_via">Through %1$s</string>
|
||||
<string name="cordn_keypackages_disclosure">Publishing signs a record under your own account key. That coordinator then knows this account exists and is invitable — permanently, and whether or not anyone invites you.</string>
|
||||
<string name="cordn_keypackages_explainer">Others can only add you to a cordn group by taking a key package you published to that coordinator. cordn has no other place to keep one, so with none published nobody can invite you — and nothing tells them why.</string>
|
||||
<string name="cordn_keypackages_failed">Could not read the key packages.</string>
|
||||
<string name="cordn_keypackages_last_resort_no">No last-resort package. Once the single-use ones run out, invitations fail.</string>
|
||||
<string name="cordn_keypackages_last_resort_yes">A last-resort package is published, so an invitation can still be made once the single-use ones run out.</string>
|
||||
<plurals name="cordn_keypackages_orphans">
|
||||
<item quantity="one">%1$d package this device cannot open</item>
|
||||
<item quantity="other">%1$d packages this device cannot open</item>
|
||||
</plurals>
|
||||
<string name="cordn_keypackages_orphans_body">The coordinator will hand these to anyone inviting you, but the private half is not on this device — it belongs to another install. If that install is gone, an invitation using one of these produces a welcome nobody can ever open.</string>
|
||||
<string name="cordn_keypackages_publish">Publish one</string>
|
||||
<string name="cordn_keypackages_publish_last_resort">Publish last-resort</string>
|
||||
<plurals name="cordn_keypackages_summary">
|
||||
<item quantity="one">%1$d single-use package available.</item>
|
||||
<item quantity="other">%1$d single-use packages available.</item>
|
||||
</plurals>
|
||||
<string name="cordn_keypackages_topup_note">Once you have published here, Amethyst quietly replaces packages as they are used up. It never publishes the first one for you.</string>
|
||||
<string name="cordn_keypackages_withdraw_all">Withdraw all</string>
|
||||
<string name="cordn_keypackages_withdraw_orphans">Withdraw those</string>
|
||||
<string name="cordn_link_request">Ask to join this group</string>
|
||||
<string name="cordn_link_request_disclosure">This publishes a key package under your own account key and tells the coordinator you want into this group — whether or not anyone answers.</string>
|
||||
<string name="cordn_link_request_failed">Could not ask to join.</string>
|
||||
<string name="cordn_link_request_sent">Asked. A member of the group has to add you; the invitation will show up under cordn invitations.</string>
|
||||
<string name="cordn_link_scan">Scan</string>
|
||||
<string name="cordn_media_download_failed">Could not open that file.</string>
|
||||
<string name="cordn_media_no_server">No media server is set for this account, so there is nowhere to put the file. Pick one in Settings.</string>
|
||||
<string name="cordn_media_unreadable">That file could not be read.</string>
|
||||
<string name="cordn_media_upload_failed">Could not send that file.</string>
|
||||
<plurals name="cordn_member_count">
|
||||
<item quantity="one">%1$d member</item>
|
||||
<item quantity="other">%1$d members</item>
|
||||
</plurals>
|
||||
<string name="cordn_message_deleted">Message deleted</string>
|
||||
<string name="cordn_message_details_coordinator">Coordinator</string>
|
||||
<string name="cordn_message_details_cursor">Cursor</string>
|
||||
<string name="cordn_message_details_sent_at">Sent</string>
|
||||
<string name="cordn_message_details_title">Message details</string>
|
||||
<string name="cordn_message_edited">edited</string>
|
||||
<string name="cordn_pinned_by">Pinned by %1$s</string>
|
||||
<plurals name="cordn_pinned_count">
|
||||
<item quantity="one">%1$d pinned message in this group</item>
|
||||
<item quantity="other">%1$d pinned messages in this group</item>
|
||||
</plurals>
|
||||
<string name="cordn_pinned_next">Next pinned message</string>
|
||||
<string name="cordn_pinned_previous">Previous pinned message</string>
|
||||
<string name="cordn_pinned_show_all">Show all pinned messages</string>
|
||||
<string name="cordn_pinned_title">Pinned messages</string>
|
||||
<string name="cordn_reactions_title">Reactions</string>
|
||||
<string name="cordn_requests_accept">Add</string>
|
||||
<string name="cordn_requests_admin_only">Only an admin can accept. In a group with no admins, that is everyone.</string>
|
||||
<string name="cordn_requests_check">Check for requests</string>
|
||||
<string name="cordn_requests_decline">Dismiss</string>
|
||||
<string name="cordn_requests_failed">Could not read the requests.</string>
|
||||
<string name="cordn_requests_none">Nobody is waiting to join.</string>
|
||||
<string name="cordn_requests_title">Requests to join</string>
|
||||
<string name="cordn_send">Send</string>
|
||||
<string name="cordn_send_failed">That did not send.</string>
|
||||
<string name="cordn_send_no_session">This group's coordinator is not open, so nothing can be sent yet.</string>
|
||||
<string name="cordn_share_copied">Copied</string>
|
||||
<string name="cordn_share_copy">Copy link</string>
|
||||
<string name="cordn_share_explainer">Anyone with this link can ask to join. An admin still has to let them in.</string>
|
||||
<string name="cordn_share_title">Share this group</string>
|
||||
<string name="cordn_voice_play">Play voice note</string>
|
||||
<string name="cordn_voice_record">Record a voice note</string>
|
||||
<string name="cordn_voice_stop">Stop and send</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user