Merge branch 'vitorpamplona:main' into followset-improvements

This commit is contained in:
KotlinGeekDev
2025-10-06 21:25:27 +00:00
committed by GitHub
12 changed files with 178 additions and 113 deletions
@@ -325,6 +325,7 @@ object LocalPreferences {
PrefKeys.DEFAULT_DISCOVERY_FOLLOW_LIST, PrefKeys.DEFAULT_DISCOVERY_FOLLOW_LIST,
settings.defaultDiscoveryFollowList.value, settings.defaultDiscoveryFollowList.value,
) )
putOrRemove(PrefKeys.ZAP_PAYMENT_REQUEST_SERVER, settings.zapPaymentRequest.value?.denormalize()) putOrRemove(PrefKeys.ZAP_PAYMENT_REQUEST_SERVER, settings.zapPaymentRequest.value?.denormalize())
putOrRemove(PrefKeys.LATEST_CONTACT_LIST, settings.backupContactList) putOrRemove(PrefKeys.LATEST_CONTACT_LIST, settings.backupContactList)
@@ -383,7 +384,7 @@ object LocalPreferences {
suspend fun loadAccountConfigFromEncryptedStorage(): AccountSettings? = currentAccount()?.let { loadAccountConfigFromEncryptedStorage(it) } suspend fun loadAccountConfigFromEncryptedStorage(): AccountSettings? = currentAccount()?.let { loadAccountConfigFromEncryptedStorage(it) }
suspend fun saveSharedSettings( fun saveSharedSettings(
sharedSettings: UiSettings, sharedSettings: UiSettings,
prefs: SharedPreferences = encryptedPreferences(), prefs: SharedPreferences = encryptedPreferences(),
) { ) {
@@ -393,7 +394,7 @@ object LocalPreferences {
} }
} }
suspend fun loadSharedSettings(prefs: SharedPreferences = encryptedPreferences()): UiSettings? { fun loadSharedSettings(prefs: SharedPreferences = encryptedPreferences()): UiSettings? {
Log.d("LocalPreferences", "Load shared settings") Log.d("LocalPreferences", "Load shared settings")
with(prefs) { with(prefs) {
return try { return try {
@@ -583,4 +584,15 @@ object LocalPreferences {
remove(key) remove(key)
} }
} }
fun SharedPreferences.Editor.putOrRemove(
key: String,
nwc: Nip47WalletConnect.Nip47URI?,
) {
if (nwc != null) {
putString(key, JsonMapper.toJson(nwc))
} else {
remove(key)
}
}
} }
@@ -297,12 +297,7 @@ object LocalCache : ILocalCache {
observablesByKindAndAuthor[event.kind]?.get(event.pubKey)?.updateIfMatches(event) observablesByKindAndAuthor[event.kind]?.get(event.pubKey)?.updateIfMatches(event)
} }
fun checkGetOrCreateUser(key: String): User? { fun checkGetOrCreateUser(key: String): User? = getOrCreateUser(key)
if (isValidHex(key)) {
return getOrCreateUser(key)
}
return null
}
fun getOrCreateUser(key: HexKey): User { fun getOrCreateUser(key: HexKey): User {
require(isValidHex(key = key)) { "$key is not a valid hex" } require(isValidHex(key = key)) { "$key is not a valid hex" }
@@ -414,11 +409,8 @@ object LocalCache : ILocalCache {
} }
private fun isValidHex(key: String): Boolean { private fun isValidHex(key: String): Boolean {
if (key.isBlank()) return false
if (key.length != 64) return false if (key.length != 64) return false
if (key.contains(':')) return false return Hex.isHex64(key)
return Hex.isHex(key)
} }
fun checkGetOrCreateAddressableNote(key: String): AddressableNote? = fun checkGetOrCreateAddressableNote(key: String): AddressableNote? =
@@ -52,6 +52,9 @@ class AccountsTorStateConnector(
listOf(MutableStateFlow(emptySet())) listOf(MutableStateFlow(emptySet()))
} }
if (dmFlowReady.isEmpty()) {
emit(emptySet())
} else {
emitAll( emitAll(
combine(dmFlowReady) { combine(dmFlowReady) {
val dmRelays = mutableSetOf<NormalizedRelayUrl>() val dmRelays = mutableSetOf<NormalizedRelayUrl>()
@@ -61,6 +64,7 @@ class AccountsTorStateConnector(
dmRelays.toSet() dmRelays.toSet()
}, },
) )
}
}.onEach { }.onEach {
torEvaluatorFlow.dmRelays.tryEmit(it) torEvaluatorFlow.dmRelays.tryEmit(it)
}.stateIn( }.stateIn(
@@ -74,22 +78,26 @@ class AccountsTorStateConnector(
accountsCache.accounts accountsCache.accounts
.debounce(200) .debounce(200)
.transformLatest { snapshot -> .transformLatest { snapshot ->
val dmFlows = snapshot.map { it.value.dmRelayList.flow } val trustedRelayFlows = snapshot.map { it.value.trustedRelays.flow }
val dmFlowReady = val trustedRelayFlowReady =
dmFlows.ifEmpty { trustedRelayFlows.ifEmpty {
listOf(MutableStateFlow(emptySet())) listOf(MutableStateFlow(emptySet()))
} }
if (trustedRelayFlowReady.isEmpty()) {
emit(emptySet())
} else {
emitAll( emitAll(
combine(dmFlowReady) { combine(trustedRelayFlowReady) {
val dmRelays = mutableSetOf<NormalizedRelayUrl>() val trustedRelays = mutableSetOf<NormalizedRelayUrl>()
it.forEach { it.forEach {
dmRelays.addAll(it) trustedRelays.addAll(it)
} }
dmRelays.toSet() trustedRelays.toSet()
}, },
) )
}
}.onEach { }.onEach {
torEvaluatorFlow.trustedRelays.tryEmit(it) torEvaluatorFlow.trustedRelays.tryEmit(it)
}.stateIn( }.stateIn(
@@ -26,6 +26,6 @@ data class TorRelaySettings(
val torType: TorType = TorType.OFF, val torType: TorType = TorType.OFF,
val onionRelaysViaTor: Boolean = true, val onionRelaysViaTor: Boolean = true,
val dmRelaysViaTor: Boolean = false, val dmRelaysViaTor: Boolean = false,
val trustedRelaysViaTor: Boolean = false,
val newRelaysViaTor: Boolean = false, val newRelaysViaTor: Boolean = false,
val trustedRelaysViaTor: Boolean = false,
) )
@@ -61,8 +61,8 @@ class TorRelayState(
torType = torType, torType = torType,
onionRelaysViaTor = onionRelaysViaTor, onionRelaysViaTor = onionRelaysViaTor,
dmRelaysViaTor = dmRelaysViaTor, dmRelaysViaTor = dmRelaysViaTor,
trustedRelaysViaTor = trustedRelaysViaTor,
newRelaysViaTor = newRelaysViaTor, newRelaysViaTor = newRelaysViaTor,
trustedRelaysViaTor = trustedRelaysViaTor,
) )
}.onStart { }.onStart {
emit( emit(
@@ -70,8 +70,8 @@ class TorRelayState(
torType = torSettingsFlow.torType.value, torType = torSettingsFlow.torType.value,
onionRelaysViaTor = torSettingsFlow.onionRelaysViaTor.value, onionRelaysViaTor = torSettingsFlow.onionRelaysViaTor.value,
dmRelaysViaTor = torSettingsFlow.dmRelaysViaTor.value, dmRelaysViaTor = torSettingsFlow.dmRelaysViaTor.value,
trustedRelaysViaTor = torSettingsFlow.trustedRelaysViaTor.value,
newRelaysViaTor = torSettingsFlow.newRelaysViaTor.value, newRelaysViaTor = torSettingsFlow.newRelaysViaTor.value,
trustedRelaysViaTor = torSettingsFlow.trustedRelaysViaTor.value,
), ),
) )
}.flowOn(Dispatchers.Default) }.flowOn(Dispatchers.Default)
@@ -82,8 +82,8 @@ class TorRelayState(
torType = torSettingsFlow.torType.value, torType = torSettingsFlow.torType.value,
onionRelaysViaTor = torSettingsFlow.onionRelaysViaTor.value, onionRelaysViaTor = torSettingsFlow.onionRelaysViaTor.value,
dmRelaysViaTor = torSettingsFlow.dmRelaysViaTor.value, dmRelaysViaTor = torSettingsFlow.dmRelaysViaTor.value,
trustedRelaysViaTor = torSettingsFlow.trustedRelaysViaTor.value,
newRelaysViaTor = torSettingsFlow.newRelaysViaTor.value, newRelaysViaTor = torSettingsFlow.newRelaysViaTor.value,
trustedRelaysViaTor = torSettingsFlow.trustedRelaysViaTor.value,
), ),
) )
@@ -43,25 +43,25 @@ class DualHttpClientManager(
keyCache: EncryptionKeyCache, keyCache: EncryptionKeyCache,
scope: CoroutineScope, scope: CoroutineScope,
) : IHttpClientManager { ) : IHttpClientManager {
val factory = OkHttpClientFactory(keyCache) val factory = OkHttpClientFactory(keyCache, userAgent)
val defaultHttpClient: StateFlow<OkHttpClient> = val defaultHttpClient: StateFlow<OkHttpClient> =
combine(proxyPortProvider, isMobileDataProvider) { proxy, mobile -> combine(proxyPortProvider, isMobileDataProvider) { proxy, mobile ->
factory.buildHttpClient(proxy, mobile, userAgent) factory.buildHttpClient(proxy, mobile)
}.stateIn( }.stateIn(
scope, scope,
SharingStarted.WhileSubscribed(1000), SharingStarted.WhileSubscribed(1000),
factory.buildHttpClient(proxyPortProvider.value, isMobileDataProvider.value, userAgent), factory.buildHttpClient(proxyPortProvider.value, isMobileDataProvider.value),
) )
val defaultHttpClientWithoutProxy: StateFlow<OkHttpClient> = val defaultHttpClientWithoutProxy: StateFlow<OkHttpClient> =
isMobileDataProvider isMobileDataProvider
.map { mobile -> .map { mobile ->
factory.buildHttpClient(mobile, userAgent) factory.buildHttpClient(mobile)
}.stateIn( }.stateIn(
scope, scope,
SharingStarted.WhileSubscribed(1000), SharingStarted.WhileSubscribed(1000),
factory.buildHttpClient(isMobileDataProvider.value, userAgent), factory.buildHttpClient(isMobileDataProvider.value),
) )
fun getCurrentProxy(): Proxy? = defaultHttpClient.value.proxy fun getCurrentProxy(): Proxy? = defaultHttpClient.value.proxy
@@ -30,6 +30,7 @@ import java.time.Duration
class OkHttpClientFactory( class OkHttpClientFactory(
keyCache: EncryptionKeyCache, keyCache: EncryptionKeyCache,
val userAgent: String,
) { ) {
companion object { companion object {
// by picking a random proxy port, the connection will fail as it should. // by picking a random proxy port, the connection will fail as it should.
@@ -74,12 +75,14 @@ class OkHttpClientFactory(
.dispatcher(myDispatcher) .dispatcher(myDispatcher)
.followRedirects(true) .followRedirects(true)
.followSslRedirects(true) .followSslRedirects(true)
.addInterceptor(DefaultContentTypeInterceptor(userAgent))
.addNetworkInterceptor(logging)
.addNetworkInterceptor(keyDecryptor)
.build() .build()
fun buildHttpClient( fun buildHttpClient(
proxy: Proxy?, proxy: Proxy?,
timeoutSeconds: Int, timeoutSeconds: Int,
userAgent: String,
): OkHttpClient { ): OkHttpClient {
val seconds = if (proxy != null) timeoutSeconds * 3 else timeoutSeconds val seconds = if (proxy != null) timeoutSeconds * 3 else timeoutSeconds
return rootClient return rootClient
@@ -88,31 +91,22 @@ class OkHttpClientFactory(
.connectTimeout(Duration.ofSeconds(seconds.toLong())) .connectTimeout(Duration.ofSeconds(seconds.toLong()))
.readTimeout(Duration.ofSeconds(seconds.toLong() * 3)) .readTimeout(Duration.ofSeconds(seconds.toLong() * 3))
.writeTimeout(Duration.ofSeconds(seconds.toLong() * 3)) .writeTimeout(Duration.ofSeconds(seconds.toLong() * 3))
.addInterceptor(DefaultContentTypeInterceptor(userAgent))
.addNetworkInterceptor(logging)
.addNetworkInterceptor(keyDecryptor)
.build() .build()
} }
fun buildHttpClient( fun buildHttpClient(
localSocksProxyPort: Int?, localSocksProxyPort: Int?,
isMobile: Boolean?, isMobile: Boolean?,
userAgent: String,
): OkHttpClient = ): OkHttpClient =
buildHttpClient( buildHttpClient(
buildLocalSocksProxy(localSocksProxyPort), buildLocalSocksProxy(localSocksProxyPort),
buildTimeout(isMobile ?: DEFAULT_IS_MOBILE), buildTimeout(isMobile ?: DEFAULT_IS_MOBILE),
userAgent,
) )
fun buildHttpClient( fun buildHttpClient(isMobile: Boolean?): OkHttpClient =
isMobile: Boolean?,
userAgent: String,
): OkHttpClient =
buildHttpClient( buildHttpClient(
null, null,
buildTimeout(isMobile ?: DEFAULT_IS_MOBILE), buildTimeout(isMobile ?: DEFAULT_IS_MOBILE),
userAgent,
) )
fun buildTimeout(isMobile: Boolean): Int = fun buildTimeout(isMobile: Boolean): Int =
+30 -30
View File
@@ -112,6 +112,7 @@
<string name="post">Příspěvek</string> <string name="post">Příspěvek</string>
<string name="save">Uložit</string> <string name="save">Uložit</string>
<string name="create">Vytvořit</string> <string name="create">Vytvořit</string>
<string name="rename">Přejmenovat</string>
<string name="cancel">Zrušit</string> <string name="cancel">Zrušit</string>
<string name="failed_to_upload_the_image">Selhalo nahrávání obrázku</string> <string name="failed_to_upload_the_image">Selhalo nahrávání obrázku</string>
<string name="relay_address">Adresa relé</string> <string name="relay_address">Adresa relé</string>
@@ -443,6 +444,31 @@
<string name="follow_list_aroundme">Kolem mě</string> <string name="follow_list_aroundme">Kolem mě</string>
<string name="follow_list_global">Globální</string> <string name="follow_list_global">Globální</string>
<string name="follow_list_mute_list">Seznam ztlumení</string> <string name="follow_list_mute_list">Seznam ztlumení</string>
<string name="follow_sets">Sady sledování</string>
<string name="labeled_bookmarks">Označené záložky</string>
<string name="general_bookmarks">Obecné záložky</string>
<string name="follow_set_type_public">Veřejné</string>
<string name="follow_set_type_private">Soukromé</string>
<string name="follow_set_type_mixed">Smíšené</string>
<string name="follow_set_empty_feed_msg">Zdá se, že zatím nemáte žádné sady sledování.\nKlepněte níže pro obnovení nebo použijte tlačítko přidat k vytvoření nové.</string>
<string name="follow_set_add_author_from_note_action">Přidat autora do sady sledování</string>
<string name="follow_set_profile_actions_menu_description">Přidat nebo odebrat uživatele ze seznamů, nebo vytvořit nový seznam s tímto uživatelem.</string>
<string name="follow_set_type_description">Ikona pro seznam %1$s</string>
<string name="follow_set_presence_indicator">"%1$s je v tomto seznamu"</string>
<string name="follow_set_absence_indicator">"%1$s není v tomto seznamu"</string>
<string name="follow_set_man_dialog_title">Vaše sady sledování</string>
<string name="follow_set_empty_dialog_msg">Nebyly nalezeny žádné sady sledování, nebo žádné nemáte. Klepněte níže pro obnovení nebo použijte menu pro vytvoření nové.</string>
<string name="follow_set_error_dialog_msg">Došlo k problému při načítání: %1$s</string>
<string name="follow_set_creation_menu_title">Vytvořit nový seznam</string>
<string name="follow_set_creation_item_label">Vytvořit nový seznam %1$s s uživatelem</string>
<string name="follow_set_creation_item_description">Vytvoří %1$s sadu sledování a přidá do ní %2$s.</string>
<string name="follow_set_creation_dialog_title">Nový seznam %1$s</string>
<string name="follow_set_creation_name_label">Název sady</string>
<string name="follow_set_creation_desc_label">Popis sady (volitelné)</string>
<string name="follow_set_creation_action_btn_label">Vytvořit sadu</string>
<string name="follow_set_rename_btn_label">Přejmenovat sadu</string>
<string name="follow_set_rename_dialog_indicator_first_part">Přejmenováváte z </string>
<string name="follow_set_rename_dialog_indicator_second_part"> na..</string>
<string name="connect_through_your_orbot_setup_short">Výchozí port je 9050</string> <string name="connect_through_your_orbot_setup_short">Výchozí port je 9050</string>
<string name="connect_through_your_orbot_setup_markdown"> ## Připojte se přes Tor s Orbotem <string name="connect_through_your_orbot_setup_markdown"> ## Připojte se přes Tor s Orbotem
\n\n1. Nainstalujte [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) \n\n1. Nainstalujte [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android)
@@ -830,6 +856,8 @@
<string name="media_compression_quality_medium">Střední</string> <string name="media_compression_quality_medium">Střední</string>
<string name="media_compression_quality_high">Vysoká</string> <string name="media_compression_quality_high">Vysoká</string>
<string name="media_compression_quality_uncompressed">Bez komprese</string> <string name="media_compression_quality_uncompressed">Bez komprese</string>
<string name="video_codec_h265_label">Použít kodek H.265/HEVC</string>
<string name="video_codec_h265_description">Lepší kvalita při menší velikosti souboru, ale ne všechna zařízení podporují přehrávání H.265.</string>
<string name="edit_draft">Upravit koncept</string> <string name="edit_draft">Upravit koncept</string>
<string name="login_with_qr_code">Přihlášení pomocí QR kódu</string> <string name="login_with_qr_code">Přihlášení pomocí QR kódu</string>
<string name="route">Trasa</string> <string name="route">Trasa</string>
@@ -1012,6 +1040,8 @@
<string name="torrent_download">Stáhnout</string> <string name="torrent_download">Stáhnout</string>
<string name="torrent_failure">Nepodařilo se otevřít soubor</string> <string name="torrent_failure">Nepodařilo se otevřít soubor</string>
<string name="torrent_no_apps">Pro otevření a stažení souboru nejsou nainstalovány žádné torrent aplikace.</string> <string name="torrent_no_apps">Pro otevření a stažení souboru nejsou nainstalovány žádné torrent aplikace.</string>
<string name="torrent_no_info">Událost nemá dostatek informací pro vytvoření magnet odkazu</string>
<string name="my_lists_and_sets">Moje seznamy/sady</string>
<string name="select_list_to_filter">Vyberte seznam pro filtrování kanálu</string> <string name="select_list_to_filter">Vyberte seznam pro filtrování kanálu</string>
<string name="temporary_account">Odhlásit se na zámek zařízení</string> <string name="temporary_account">Odhlásit se na zámek zařízení</string>
<string name="private_message">Soukromá zpráva</string> <string name="private_message">Soukromá zpráva</string>
@@ -1033,35 +1063,5 @@
<string name="would_you_like_to_send_the_recent_crash_report_to_amethyst_in_a_dm_no_personal_information_will_be_shared">Chcete poslat poslední záznam o pádu do Amethystu v soukromé zprávě? Žádné osobní údaje nebudou sdíleny</string> <string name="would_you_like_to_send_the_recent_crash_report_to_amethyst_in_a_dm_no_personal_information_will_be_shared">Chcete poslat poslední záznam o pádu do Amethystu v soukromé zprávě? Žádné osobní údaje nebudou sdíleny</string>
<string name="crashreport_found_send">Odeslat</string> <string name="crashreport_found_send">Odeslat</string>
<string name="this_message_will_disappear_in_days">Tato zpráva zmizí za %1$d dní</string> <string name="this_message_will_disappear_in_days">Tato zpráva zmizí za %1$d dní</string>
<string name="follow_sets">Sady sledování</string>
<string name="labeled_bookmarks">Označené záložky</string>
<string name="general_bookmarks">Obecné záložky</string>
<string name="follow_set_type_public">Veřejné</string>
<string name="follow_set_type_private">Soukromé</string>
<string name="follow_set_type_mixed">Smíšené</string>
<string name="follow_set_empty_feed_msg">Zdá se, že zatím nemáte žádné sady sledování.\nKlepněte níže pro obnovení nebo použijte tlačítko přidat k vytvoření nové.</string>
<string name="follow_set_add_author_from_note_action">Přidat autora do sady sledování</string>
<string name="follow_set_profile_actions_menu_description">Přidat nebo odebrat uživatele ze seznamů, nebo vytvořit nový seznam s tímto uživatelem.</string>
<string name="follow_set_type_description">Ikona pro seznam %1$s</string>
<string name="follow_set_presence_indicator">%1$s je v tomto seznamu</string>
<string name="follow_set_absence_indicator">%1$s není v tomto seznamu</string>
<string name="follow_set_man_dialog_title">Vaše sady sledování</string>
<string name="follow_set_empty_dialog_msg">Nebyly nalezeny žádné sady sledování, nebo žádné nemáte. Klepněte níže pro obnovení nebo použijte menu pro vytvoření nové.</string>
<string name="follow_set_error_dialog_msg">Došlo k problému při načítání: %1$s</string>
<string name="follow_set_creation_menu_title">Vytvořit nový seznam</string>
<string name="follow_set_creation_item_label">Vytvořit nový seznam %1$s s uživatelem</string>
<string name="follow_set_creation_item_description">Vytvoří %1$s sadu sledování a přidá do ní %2$s.</string>
<string name="follow_set_creation_dialog_title">Nový seznam %1$s</string>
<string name="follow_set_creation_name_label">Název sady</string>
<string name="follow_set_creation_desc_label">Popis sady (volitelné)</string>
<string name="follow_set_creation_action_btn_label">Vytvořit sadu</string>
<string name="follow_set_rename_btn_label">Přejmenovat sadu</string>
<string name="follow_set_rename_dialog_indicator_first_part">Přejmenováváte z </string>
<string name="follow_set_rename_dialog_indicator_second_part"> na..</string>
<string name="rename">Přejmenovat</string>
<string name="torrent_no_info">Událost nemá dostatek informací pro vytvoření magnet odkazu</string>
<string name="my_lists_and_sets">Moje seznamy/sady</string>
<string name="select_signer">Vybrat podepisovatele</string> <string name="select_signer">Vybrat podepisovatele</string>
<string name="video_codec_h265_label">Použít kodek H.265/HEVC</string>
<string name="video_codec_h265_description">Lepší kvalita při menší velikosti souboru, ale ne všechna zařízení podporují přehrávání H.265.</string>
</resources> </resources>
+30 -30
View File
@@ -112,6 +112,7 @@
<string name="post">Beitrag</string> <string name="post">Beitrag</string>
<string name="save">Speichern</string> <string name="save">Speichern</string>
<string name="create">Erstellen</string> <string name="create">Erstellen</string>
<string name="rename">Umbenennen</string>
<string name="cancel">Abbrechen</string> <string name="cancel">Abbrechen</string>
<string name="failed_to_upload_the_image">Fehler beim Hochladen des Bildes</string> <string name="failed_to_upload_the_image">Fehler beim Hochladen des Bildes</string>
<string name="relay_address">Relay-Adresse</string> <string name="relay_address">Relay-Adresse</string>
@@ -449,6 +450,31 @@ anz der Bedingungen ist erforderlich</string>
<string name="follow_list_aroundme">In der Nähe</string> <string name="follow_list_aroundme">In der Nähe</string>
<string name="follow_list_global">Weltweit</string> <string name="follow_list_global">Weltweit</string>
<string name="follow_list_mute_list">Stummliste</string> <string name="follow_list_mute_list">Stummliste</string>
<string name="follow_sets">Folge-Sets</string>
<string name="labeled_bookmarks">Markierte Lesezeichen</string>
<string name="general_bookmarks">Allgemeine Lesezeichen</string>
<string name="follow_set_type_public">Öffentlich</string>
<string name="follow_set_type_private">Privat</string>
<string name="follow_set_type_mixed">Gemischt</string>
<string name="follow_set_empty_feed_msg">Es scheint, dass du noch keine Folge-Sets hast.\nTippe unten zum Aktualisieren oder verwende die Plus-Taste, um ein neues zu erstellen.</string>
<string name="follow_set_add_author_from_note_action">Autor zum Folge-Set hinzufügen</string>
<string name="follow_set_profile_actions_menu_description">Benutzer zu Listen hinzufügen oder entfernen, oder eine neue Liste mit diesem Benutzer erstellen.</string>
<string name="follow_set_type_description">Symbol für %1$s-Liste</string>
<string name="follow_set_presence_indicator">"%1$s ist in dieser Liste"</string>
<string name="follow_set_absence_indicator">"%1$s ist nicht in dieser Liste"</string>
<string name="follow_set_man_dialog_title">Deine Folge-Sets</string>
<string name="follow_set_empty_dialog_msg">Keine Folge-Sets gefunden oder du hast keine. Tippe unten zum Aktualisieren oder verwende das Menü, um eines zu erstellen.</string>
<string name="follow_set_error_dialog_msg">Beim Abrufen ist ein Problem aufgetreten: %1$s</string>
<string name="follow_set_creation_menu_title">Neue Liste erstellen</string>
<string name="follow_set_creation_item_label">Neue %1$s-Liste mit Benutzer erstellen</string>
<string name="follow_set_creation_item_description">Erstellt ein %1$s-Folge-Set und fügt %2$s hinzu.</string>
<string name="follow_set_creation_dialog_title">Neue %1$s-Liste</string>
<string name="follow_set_creation_name_label">Set-Name</string>
<string name="follow_set_creation_desc_label">Set-Beschreibung (optional)</string>
<string name="follow_set_creation_action_btn_label">Set erstellen</string>
<string name="follow_set_rename_btn_label">Set umbenennen</string>
<string name="follow_set_rename_dialog_indicator_first_part">Du benennst um von </string>
<string name="follow_set_rename_dialog_indicator_second_part"> zu..</string>
<string name="connect_through_your_orbot_setup_short">Standard-Port ist 9050</string> <string name="connect_through_your_orbot_setup_short">Standard-Port ist 9050</string>
<string name="connect_through_your_orbot_setup_markdown"> ## Über Tor mit Orbot verbinden <string name="connect_through_your_orbot_setup_markdown"> ## Über Tor mit Orbot verbinden
\n\n1. Installiere [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) \n\n1. Installiere [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android)
@@ -835,6 +861,8 @@ anz der Bedingungen ist erforderlich</string>
<string name="media_compression_quality_medium">Mittel</string> <string name="media_compression_quality_medium">Mittel</string>
<string name="media_compression_quality_high">Hoch</string> <string name="media_compression_quality_high">Hoch</string>
<string name="media_compression_quality_uncompressed">Ohne Kompression</string> <string name="media_compression_quality_uncompressed">Ohne Kompression</string>
<string name="video_codec_h265_label">H.265/HEVC-Codec verwenden</string>
<string name="video_codec_h265_description">Bessere Qualität bei kleinerer Dateigröße, aber nicht alle Geräte unterstützen die H.265-Wiedergabe.</string>
<string name="edit_draft">Entwurf bearbeiten</string> <string name="edit_draft">Entwurf bearbeiten</string>
<string name="login_with_qr_code">Einloggen mit QR-Code</string> <string name="login_with_qr_code">Einloggen mit QR-Code</string>
<string name="route">Route</string> <string name="route">Route</string>
@@ -1017,6 +1045,8 @@ anz der Bedingungen ist erforderlich</string>
<string name="torrent_download">Herunterladen</string> <string name="torrent_download">Herunterladen</string>
<string name="torrent_failure">Fehler beim Öffnen der Datei</string> <string name="torrent_failure">Fehler beim Öffnen der Datei</string>
<string name="torrent_no_apps">Keine Torrent-Apps installiert, um die Datei zu öffnen und herunterzuladen.</string> <string name="torrent_no_apps">Keine Torrent-Apps installiert, um die Datei zu öffnen und herunterzuladen.</string>
<string name="torrent_no_info">Das Ereignis enthält nicht genügend Informationen, um einen Magnetlink zu erstellen</string>
<string name="my_lists_and_sets">Meine Listen/Sets</string>
<string name="select_list_to_filter">Liste zum Filtern des Feeds auswählen</string> <string name="select_list_to_filter">Liste zum Filtern des Feeds auswählen</string>
<string name="temporary_account">Beim Sperren des Geräts abmelden</string> <string name="temporary_account">Beim Sperren des Geräts abmelden</string>
<string name="private_message">Private Nachricht</string> <string name="private_message">Private Nachricht</string>
@@ -1038,35 +1068,5 @@ anz der Bedingungen ist erforderlich</string>
<string name="would_you_like_to_send_the_recent_crash_report_to_amethyst_in_a_dm_no_personal_information_will_be_shared">Möchten Sie den letzten Absturzbericht per Direktnachricht an Amethyst senden? Es werden keine persönlichen Daten weitergegeben</string> <string name="would_you_like_to_send_the_recent_crash_report_to_amethyst_in_a_dm_no_personal_information_will_be_shared">Möchten Sie den letzten Absturzbericht per Direktnachricht an Amethyst senden? Es werden keine persönlichen Daten weitergegeben</string>
<string name="crashreport_found_send">Senden</string> <string name="crashreport_found_send">Senden</string>
<string name="this_message_will_disappear_in_days">Diese Nachricht verschwindet in %1$d Tagen</string> <string name="this_message_will_disappear_in_days">Diese Nachricht verschwindet in %1$d Tagen</string>
<string name="follow_sets">Folge-Sets</string>
<string name="labeled_bookmarks">Markierte Lesezeichen</string>
<string name="general_bookmarks">Allgemeine Lesezeichen</string>
<string name="follow_set_type_public">Öffentlich</string>
<string name="follow_set_type_private">Privat</string>
<string name="follow_set_type_mixed">Gemischt</string>
<string name="follow_set_empty_feed_msg">Es scheint, dass du noch keine Folge-Sets hast.\nTippe unten zum Aktualisieren oder verwende die Plus-Taste, um ein neues zu erstellen.</string>
<string name="follow_set_add_author_from_note_action">Autor zum Folge-Set hinzufügen</string>
<string name="follow_set_profile_actions_menu_description">Benutzer zu Listen hinzufügen oder entfernen, oder eine neue Liste mit diesem Benutzer erstellen.</string>
<string name="follow_set_type_description">Symbol für %1$s-Liste</string>
<string name="follow_set_presence_indicator">%1$s ist in dieser Liste</string>
<string name="follow_set_absence_indicator">%1$s ist nicht in dieser Liste</string>
<string name="follow_set_man_dialog_title">Deine Folge-Sets</string>
<string name="follow_set_empty_dialog_msg">Keine Folge-Sets gefunden oder du hast keine. Tippe unten zum Aktualisieren oder verwende das Menü, um eines zu erstellen.</string>
<string name="follow_set_error_dialog_msg">Beim Abrufen ist ein Problem aufgetreten: %1$s</string>
<string name="follow_set_creation_menu_title">Neue Liste erstellen</string>
<string name="follow_set_creation_item_label">Neue %1$s-Liste mit Benutzer erstellen</string>
<string name="follow_set_creation_item_description">Erstellt ein %1$s-Folge-Set und fügt %2$s hinzu.</string>
<string name="follow_set_creation_dialog_title">Neue %1$s-Liste</string>
<string name="follow_set_creation_name_label">Set-Name</string>
<string name="follow_set_creation_desc_label">Set-Beschreibung (optional)</string>
<string name="follow_set_creation_action_btn_label">Set erstellen</string>
<string name="follow_set_rename_btn_label">Set umbenennen</string>
<string name="follow_set_rename_dialog_indicator_first_part">Du benennst um von </string>
<string name="follow_set_rename_dialog_indicator_second_part"> zu..</string>
<string name="rename">Umbenennen</string>
<string name="torrent_no_info">Das Ereignis enthält nicht genügend Informationen, um einen Magnetlink zu erstellen</string>
<string name="my_lists_and_sets">Meine Listen/Sets</string>
<string name="select_signer">Signierer auswählen</string> <string name="select_signer">Signierer auswählen</string>
<string name="video_codec_h265_label">H.265/HEVC-Codec verwenden</string>
<string name="video_codec_h265_description">Bessere Qualität bei kleinerer Dateigröße, aber nicht alle Geräte unterstützen die H.265-Wiedergabe.</string>
</resources> </resources>
@@ -860,6 +860,8 @@
<string name="media_compression_quality_medium">Közepes</string> <string name="media_compression_quality_medium">Közepes</string>
<string name="media_compression_quality_high">Magas</string> <string name="media_compression_quality_high">Magas</string>
<string name="media_compression_quality_uncompressed">Tömörítetlen</string> <string name="media_compression_quality_uncompressed">Tömörítetlen</string>
<string name="video_codec_h265_label">H.265/HEVC-kodek használata</string>
<string name="video_codec_h265_description">Jobb minőség kisebb fájlméret mellett, de nem minden eszköz támogatja a H.265 lejátszást.</string>
<string name="edit_draft">Piszkozat szerkesztése</string> <string name="edit_draft">Piszkozat szerkesztése</string>
<string name="login_with_qr_code">Bejelentkezés QR-kóddal</string> <string name="login_with_qr_code">Bejelentkezés QR-kóddal</string>
<string name="route">Útvonal</string> <string name="route">Útvonal</string>
@@ -6,9 +6,14 @@
<string name="channel_image">Kanāla attēls</string> <string name="channel_image">Kanāla attēls</string>
<string name="group_picture">Grupas attēls</string> <string name="group_picture">Grupas attēls</string>
<string name="unknown">Nezināms</string> <string name="unknown">Nezināms</string>
<string name="unknown_author">Nezināms autors</string>
<string name="copy_text">Kopēt tekstu</string> <string name="copy_text">Kopēt tekstu</string>
<string name="copy_user_pubkey">Kopēt autora ID</string>
<string name="block_report">Bloķēt / Sūdzēties</string> <string name="block_report">Bloķēt / Sūdzēties</string>
<string name="block_hide_user"><![CDATA[Bloķēt un paslēpt lietotāju]]></string> <string name="block_hide_user"><![CDATA[Bloķēt un paslēpt lietotāju]]></string>
<string name="report_impersonation">Sūdzēties par uzdošanos kā cita persona</string>
<string name="report_malware">Sūdzēties par ļaunprogrammatūru</string>
<string name="malware">Ļaunprogrammatūra</string>
<string name="view_count">Skatījumi</string> <string name="view_count">Skatījumi</string>
<string name="edited">rediģēts</string> <string name="edited">rediģēts</string>
<string name="add">Pievienot</string> <string name="add">Pievienot</string>
@@ -20,15 +25,22 @@
<string name="profile">Profils</string> <string name="profile">Profils</string>
<string name="pay">Maksāt</string> <string name="pay">Maksāt</string>
<string name="secret_visible_text_placeholder">😎</string> <string name="secret_visible_text_placeholder">😎</string>
<string name="secret_add_to_text">Pievienot ierakstam</string>
<string name="new_channel">Jauns kanāls</string> <string name="new_channel">Jauns kanāls</string>
<string name="channel_name">Kanāla nosaukums</string> <string name="channel_name">Kanāla nosaukums</string>
<string name="picture_url">Attēla URL</string> <string name="picture_url">Attēla URL</string>
<string name="description">Apraksts</string> <string name="description">Apraksts</string>
<string name="about_us">"Par mums.. "</string>
<string name="post">Ieraksts</string>
<string name="save">Saglabāt</string> <string name="save">Saglabāt</string>
<string name="create">Izveidot</string> <string name="create">Izveidot</string>
<string name="cancel">Atcelt</string> <string name="cancel">Atcelt</string>
<string name="failed_to_upload_the_image">Neizdevās augšupielādēt attēlu</string>
<string name="posts">Ieraksti</string>
<string name="bytes">Baiti</string> <string name="bytes">Baiti</string>
<string name="errors">Kļūdas</string> <string name="errors">Kļūdas</string>
<string name="username">Lietotājvārds</string>
<string name="my_username">Mans lietotājvārds</string>
<string name="about_me">Par mani</string> <string name="about_me">Par mani</string>
<string name="ln_address">LN adrese</string> <string name="ln_address">LN adrese</string>
<string name="upload_image">Augšupielādēt attēlu</string> <string name="upload_image">Augšupielādēt attēlu</string>
@@ -37,19 +49,25 @@
<string name="notes">Piezīmes</string> <string name="notes">Piezīmes</string>
<string name="replies">Atbildes</string> <string name="replies">Atbildes</string>
<string name="gallery">Galerija</string> <string name="gallery">Galerija</string>
<string name="follows">"Seko"</string>
<string name="follow">Sekot</string> <string name="follow">Sekot</string>
<string name="unblock">Atbloķēt</string> <string name="unblock">Atbloķēt</string>
<string name="unblock_user">Atbloķēt lietotāju</string> <string name="unblock_user">Atbloķēt lietotāju</string>
<string name="npub_hex_username">"npub, lietotājvārds, teksts"</string>
<string name="app_logo">Lietotnes logo</string> <string name="app_logo">Lietotnes logo</string>
<string name="ncryptsec_password">parole, lai atvērtu atslēgu</string>
<string name="show_password">Rādīt paroli</string> <string name="show_password">Rādīt paroli</string>
<string name="hide_password">Slēpt paroli</string> <string name="hide_password">Slēpt paroli</string>
<string name="password_is_required">Ir nepieciešama parole</string>
<string name="create_account">Izveidot kontu</string> <string name="create_account">Izveidot kontu</string>
<string name="create_a_new_account">Izveidot jaunu kontu</string> <string name="create_a_new_account">Izveidot jaunu kontu</string>
<string name="generate_a_new_key">Ģenerēt jaunu atslēgu</string> <string name="generate_a_new_key">Ģenerēt jaunu atslēgu</string>
<string name="loading_account">Ielādē kontu</string>
<string name="refresh">Atsvaidzināt</string> <string name="refresh">Atsvaidzināt</string>
<string name="description_to">aprakstu uz</string> <string name="description_to">aprakstu uz</string>
<string name="and_picture_to">un attēlu uz</string> <string name="and_picture_to">un attēlu uz</string>
<string name="channel_created">Kanāls izveidots</string> <string name="channel_created">Kanāls izveidots</string>
<string name="posts_received">saņemtie ieraksti</string>
<string name="remove">Noņemt</string> <string name="remove">Noņemt</string>
<string name="translations_auto">Automātiski</string> <string name="translations_auto">Automātiski</string>
<string name="translations_to">uz</string> <string name="translations_to">uz</string>
@@ -57,11 +75,19 @@
<string name="nip_05">Nostr adrese</string> <string name="nip_05">Nostr adrese</string>
<string name="never">nekad</string> <string name="never">nekad</string>
<string name="now">tagad</string> <string name="now">tagad</string>
<string name="report_nudity_porn">Sūdzēties par kailumu / porno</string>
<string name="account_backup_tips3_md" tools:ignore="Typos"> Papildu drošībai variet šifrēt atslēgu ar paroli. Šī atslēga sāksies ar **ncryptsec1** virkni un to nevarēs izmantot bez šīs paroles.
\n\nJa jūs aizmirsīsiet paroli, vairs nevarēsiet atgūt savu atslēgu.
</string>
<string name="biometric_error">Kļūda</string> <string name="biometric_error">Kļūda</string>
<string name="account_switch_add_account_dialog_title">Pievienot jaunu kontu</string> <string name="account_switch_add_account_dialog_title">Pievienot jaunu kontu</string>
<string name="drawer_accounts">Konti</string> <string name="drawer_accounts">Konti</string>
<string name="account_switch_select_account">Atlasīt kontu</string> <string name="account_switch_select_account">Atlasīt kontu</string>
<string name="account_switch_add_account_btn">Pievienot jaunu kontu</string> <string name="account_switch_add_account_btn">Pievienot jaunu kontu</string>
<string name="account_switch_active_account">Pašreizējais konts</string>
<string name="account_switch_has_private_key">Ar privāto atslēgu</string>
<string name="account_switch_pubkey_only">Tikai lasīšana, bez privātās atslēgas</string>
<string name="quick_action_copy_user_id">Autora ID</string>
<string name="quick_action_copy_text">Kopēt tekstu</string> <string name="quick_action_copy_text">Kopēt tekstu</string>
<string name="quick_action_delete">Dzēst</string> <string name="quick_action_delete">Dzēst</string>
<string name="quick_action_follow">Sekot</string> <string name="quick_action_follow">Sekot</string>
@@ -69,6 +95,7 @@
<string name="quick_action_delete_dialog_btn">Dzēst</string> <string name="quick_action_delete_dialog_btn">Dzēst</string>
<string name="quick_action_block">@string/block_only</string> <string name="quick_action_block">@string/block_only</string>
<string name="quick_action_delete_button">Dzēst</string> <string name="quick_action_delete_button">Dzēst</string>
<string name="report_dialog_malware">@string/malware</string>
<string name="report_dialog_block_hide_user_btn"><![CDATA[@string/block_hide_user]]></string> <string name="report_dialog_block_hide_user_btn"><![CDATA[@string/block_hide_user]]></string>
<string name="report_dialog_select_reason_label">Iemesls</string> <string name="report_dialog_select_reason_label">Iemesls</string>
<string name="report_dialog_title">Bloķēt un sūdzēties</string> <string name="report_dialog_title">Bloķēt un sūdzēties</string>
@@ -79,25 +106,46 @@
<string name="content_description_add_image">Pievienot attēlu</string> <string name="content_description_add_image">Pievienot attēlu</string>
<string name="content_description_add_video">Pievienot video</string> <string name="content_description_add_video">Pievienot video</string>
<string name="content_description_add_document">Pievienot dokumentu</string> <string name="content_description_add_document">Pievienot dokumentu</string>
<string name="set_preferred_media_servers">Iestatiet vēlamos multivides augšupielādes serverus.</string>
<string name="uploading_state_uploading">Augšupielādē</string> <string name="uploading_state_uploading">Augšupielādē</string>
<string name="uploading_state_downloading">Lejupielādē</string> <string name="uploading_state_downloading">Lejupielādē</string>
<string name="uploading_state_error">Kļūda</string> <string name="uploading_state_error">Kļūda</string>
<string name="connect_via_tor2">Tor iestatījumi</string> <string name="connect_via_tor2">Tor iestatījumi</string>
<string name="yes"></string> <string name="yes"></string>
<string name="no"></string> <string name="no"></string>
<string name="follow_list_selection">Sekot saraksts</string>
<string name="follow_set_type_description">Ikona %1$s sarakstam</string>
<string name="follow_set_creation_menu_title">Izveidot jaunu sarakstu</string>
<string name="follow_set_creation_dialog_title">Jaunais %1$s saraksts</string>
<string name="follow_set_creation_name_label">Kolekcijas nosaukums</string>
<string name="follow_set_creation_desc_label">Kolekcijas apraksts (neobligāti, pēc izvēles)</string>
<string name="follow_set_creation_action_btn_label">Izveidot kolekciju</string>
<string name="follow_set_rename_btn_label">Pārsaukt kolekciju</string>
<string name="follow_set_rename_dialog_indicator_first_part">Jūs taisāties pārsaukt no </string>
<string name="follow_set_rename_dialog_indicator_second_part"> uz..</string>
<string name="connect_through_your_orbot_setup_short">Noklusējuma ports ir 9050</string> <string name="connect_through_your_orbot_setup_short">Noklusējuma ports ir 9050</string>
<string name="invalid_port_number">Nederīgs porta numurs</string> <string name="invalid_port_number">Nederīgs porta numurs</string>
<string name="show_sensitive_content_explainer">Parāda brīdinājuma ziņojumu, ja autors atzīmējis ierakstu kā jutīgu</string>
<string name="version">Versija</string> <string name="version">Versija</string>
<string name="countries">Valstis</string> <string name="countries">Valstis</string>
<string name="languages">Valodas</string> <string name="languages">Valodas</string>
<string name="tags">Birkas</string> <string name="tags">Birkas</string>
<string name="auth">Autorizācija</string>
<string name="followed_tags">Birkas, kurām sekoju</string>
<string name="community_approved_posts">Apstiprinātie ieraksti</string>
<string name="preferences">Lietotnes iestatījumi</string>
<string name="user_preferences">Lietotāja iestatījumi</string>
<string name="application_preferences">@string/preferences</string>
<string name="language">Valoda</string> <string name="language">Valoda</string>
<string name="theme">Motīvs</string> <string name="theme">Motīvs</string>
<string name="messages_cant_upload_title">Nevar augšupielādēt</string> <string name="messages_cant_upload_title">Nevar augšupielādēt</string>
<string name="rules">Noteikumi</string> <string name="rules">Noteikumi</string>
<string name="community_description">Par mums</string>
<string name="error_dialog_button_ok">Labi</string> <string name="error_dialog_button_ok">Labi</string>
<string name="active_for_search">Meklēt</string> <string name="active_for_search">Meklēt</string>
<string name="zap_split_search_and_add_user_placeholder">Lietotājvārds vai parādāmais vārds</string>
<string name="automatically_show_profile_picture">Profila attēls</string> <string name="automatically_show_profile_picture">Profila attēls</string>
<string name="error_dialog_pay_invoice_error">Nevarēja samaksāt rēķinu</string>
<string name="classifieds_category">Kategorija</string> <string name="classifieds_category">Kategorija</string>
<string name="classifieds_category_clothing">Apģērbs</string> <string name="classifieds_category_clothing">Apģērbs</string>
<string name="classifieds_category_electronics">Elektronika</string> <string name="classifieds_category_electronics">Elektronika</string>
@@ -106,12 +154,19 @@
<string name="classifieds_category_sports">Sports</string> <string name="classifieds_category_sports">Sports</string>
<string name="classifieds_category_art">Māksla</string> <string name="classifieds_category_art">Māksla</string>
<string name="classifieds_category_food">Ēdiens</string> <string name="classifieds_category_food">Ēdiens</string>
<string name="failed_to_upload_media_no_details">Neizdevās augšupielādēt multivides datni</string>
<string name="failed_to_upload_media">Augšupielādes kļūda: %1$s</string> <string name="failed_to_upload_media">Augšupielādes kļūda: %1$s</string>
<string name="could_not_download_from_the_server">Nevarēja lejupielādēt augšupielādēto multivides datni no servera</string>
<string name="failed_to_upload_to_server_with_message">Neizdevās augšupielādēt %1$s: %2$s</string>
<string name="failed_to_upload_with_message">Neizdevās augšupielādēt: %1$s</string> <string name="failed_to_upload_with_message">Neizdevās augšupielādēt: %1$s</string>
<string name="route_search">Meklēt</string> <string name="route_search">Meklēt</string>
<string name="route_notifications">Paziņojumi</string> <string name="route_notifications">Paziņojumi</string>
<string name="new_post">Jauns ieraksts</string>
<string name="thank_you">Paldies!</string> <string name="thank_you">Paldies!</string>
<string name="edit_post">Rediģēt ierakstu</string>
<string name="message_to_author">Izmaiņu kopsavilkums</string>
<string name="accessibility_download_for_offline">@string/torrent_download</string> <string name="accessibility_download_for_offline">@string/torrent_download</string>
<string name="accessibility_play_username">Atskaņot lietotājvārdu ar skaņu</string>
<string name="torrent_file">Torrenta datne</string> <string name="torrent_file">Torrenta datne</string>
<string name="torrent_download">Lejupielādēt</string> <string name="torrent_download">Lejupielādēt</string>
<string name="torrent_no_apps">Nav uzstādītas torrent lietotnes, kas atvērtu un lejupielādētu datni.</string> <string name="torrent_no_apps">Nav uzstādītas torrent lietotnes, kas atvērtu un lejupielādētu datni.</string>
@@ -860,6 +860,8 @@
<string name="media_compression_quality_medium">中等质量</string> <string name="media_compression_quality_medium">中等质量</string>
<string name="media_compression_quality_high">高质量</string> <string name="media_compression_quality_high">高质量</string>
<string name="media_compression_quality_uncompressed">未压缩</string> <string name="media_compression_quality_uncompressed">未压缩</string>
<string name="video_codec_h265_label">使用 H.265/HEVC 编解码器</string>
<string name="video_codec_h265_description">文件较小而质量更佳,但不是所有设备都支持 H.265 播放。</string>
<string name="edit_draft">编辑草稿</string> <string name="edit_draft">编辑草稿</string>
<string name="login_with_qr_code">使用二维码登录</string> <string name="login_with_qr_code">使用二维码登录</string>
<string name="route">路径</string> <string name="route">路径</string>