Compare commits

..
262 changed files with 8996 additions and 6310 deletions
Generated
+2 -2
View File
@@ -5830,9 +5830,9 @@ dependencies = [
[[package]]
name = "yoke-derive"
version = "0.8.3"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33811428bee40dbceb6d545e95754741d17a6aef9a4849f0fd62e2ba4f412a78"
checksum = "ec8ebde2db3681e8c9980cc27822030e68752690ddfa9473e739aeb4dbde6d71"
dependencies = [
"proc-macro2",
"quote",
+5 -1
View File
@@ -160,7 +160,6 @@ MEILI_MASTER_KEY=CHANGE_ME
# api.pwnedpasswords.com.
#FLUXER_BREACHED_PASSWORD_CHECK_ENABLED=false
#FLUXER_BLOCKLIST_FEEDS_ENABLED=false
#FLUXER_IPINFO_API_KEY=
# A local path, or an s3:// URL read with the S3 credentials of this file.
#FLUXER_GEOIP_DB_PATH=
@@ -449,6 +448,11 @@ FLUXER_DISCOVERY_ENABLED=true
#FLUXER_SEAWEEDFS_GOMEMLIMIT=1536MiB
#FLUXER_SEAWEEDFS_TELEMETRY=false
# Volumes SeaweedFS creates at once when a bucket needs space. Each reserves 1 GB
# of free disk from the start, and SeaweedFS's own default of 7 fills a small
# disk before every bucket has one, so uploads fail with no free volumes left.
#FLUXER_SEAWEEDFS_VOLUME_GROWTH=1
# Node sizes its heap from the container limit by default. Leave these unset
# unless you need to pin it. A heap ceiling above the container limit gets the
# container OOM-killed instead of reporting a heap error. The values below are
+1 -1
View File
@@ -33,7 +33,6 @@ x-fluxer-env: &fluxer-env
FLUXER_APP_ORIGIN_ALIASES: ${FLUXER_APP_ORIGIN_ALIASES:-}
FLUXER_BREACHED_PASSWORD_CHECK_ENABLED: ${FLUXER_BREACHED_PASSWORD_CHECK_ENABLED:-}
FLUXER_BLOCKLIST_FEEDS_ENABLED: ${FLUXER_BLOCKLIST_FEEDS_ENABLED:-}
FLUXER_IPINFO_API_KEY: ${FLUXER_IPINFO_API_KEY:-}
FLUXER_GEOIP_DB_PATH: ${FLUXER_GEOIP_DB_PATH:-}
FLUXER_API_ENDPOINT: ${FLUXER_API_ENDPOINT:-}
@@ -354,6 +353,7 @@ services:
memory: ${FLUXER_SEAWEEDFS_MEMORY_LIMIT:-2gb}
environment:
GOMEMLIMIT: ${FLUXER_SEAWEEDFS_GOMEMLIMIT:-1536MiB}
WEED_MASTER_VOLUME_GROWTH_COPY_1: ${FLUXER_SEAWEEDFS_VOLUME_GROWTH:-1}
command: ["server", "-s3", "-dir=/data", "-master.telemetry=${FLUXER_SEAWEEDFS_TELEMETRY:-false}"]
volumes:
- seaweedfs-data:/data
+15 -6
View File
@@ -1251,7 +1251,7 @@
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
}
},
"description": "Add a value to a blocklist. The request body is the shape the blocklist named by list_type accepts, and the value is validated and canonicalized for that blocklist. Adding an IP address that is on the instance exemption list, or that IPInfo reports as a high blast-radius carrier NAT, is refused with 400 IP_BAN_DECLINED and recorded in the audit log.",
"description": "Add a value to a blocklist. The request body is the shape the blocklist named by list_type accepts, and the value is validated and canonicalized for that blocklist. Adding an IP address that is on the instance exemption list is refused with 400 IP_BAN_DECLINED and recorded in the audit log.",
"security": [{"adminApiKey": []}],
"parameters": [
{
@@ -5435,7 +5435,7 @@
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
}
},
"description": "Queue a worker job that delivers the same content to every listed user as a direct message from the system account. Progress is observable through the Jobs admin resource (task_type=sendSystemDm), and an in-flight broadcast is stopped by cancelling that job. Requires SYSTEM_DM_SEND permission.",
"description": "Queue a worker job that delivers the same content to every listed user, or to every user when all_users is set, as a direct message from the system account. Progress is observable through the Jobs admin resource (task_type=sendSystemDm), and an in-flight broadcast is stopped by cancelling that job. Requires SYSTEM_DM_SEND permission.",
"security": [{"adminApiKey": []}],
"requestBody": {
"required": true,
@@ -10150,20 +10150,25 @@
"description": "Message content to send to each recipient"
},
"user_ids": {
"description": "Recipient user IDs. Each receives the same content as a system DM.",
"minItems": 1,
"maxItems": 10000,
"type": "array",
"items": {"$ref": "#/components/schemas/SnowflakeType"},
"description": "Recipient user IDs. Each receives the same content as a system DM."
"items": {"$ref": "#/components/schemas/SnowflakeType"}
},
"all_users": {
"description": "Send to every user account, skipping bots, system accounts, and deleted or disabled accounts",
"type": "boolean"
}
},
"required": ["content", "user_ids"]
"required": ["content"]
},
"SendSystemDmResponse": {
"type": "object",
"properties": {
"recipient_count": {
"description": "Number of recipients the worker job was queued to deliver to",
"nullable": true,
"description": "Number of recipients the worker job was queued to deliver to, or null when sending to all users",
"allOf": [{"$ref": "#/components/schemas/Int32Type"}]
}
},
@@ -10659,6 +10664,7 @@
"feature_custom_notification_sounds",
"feature_early_access",
"feature_global_expressions",
"feature_guild_create",
"feature_higher_video_quality",
"feature_per_guild_profiles",
"feature_voice_entrance_sounds",
@@ -10966,6 +10972,7 @@
"single_community_guild_id": {"nullable": true, "type": "string"},
"direct_messages_disabled": {"type": "boolean"},
"direct_messages_locked": {"type": "boolean"},
"guild_create_access": {"type": "boolean"},
"premium_mode": {"type": "string", "enum": ["mirror", "everyone"]},
"services": {
"type": "object",
@@ -11003,6 +11010,7 @@
"single_community_guild_id",
"direct_messages_disabled",
"direct_messages_locked",
"guild_create_access",
"premium_mode",
"services",
"services_resolved",
@@ -11523,6 +11531,7 @@
"direct_messages_disabled": {"type": "boolean"},
"direct_messages_locked": {"type": "boolean", "enum": [false]},
"premium_mode": {"type": "string", "enum": ["mirror", "everyone"]},
"guild_create_access": {"type": "boolean"},
"services": {
"nullable": true,
"type": "object",
+17
View File
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
use crate::templates::components::tooltip::{Hint, HintLink};
pub fn limit_key_hint(key: &str) -> Option<Hint<'static>> {
match key {
"feature_guild_create" => Some(Hint {
name: Some("Community Creation Access"),
body: "Admins with the wildcard ACL can always create communities.",
link: Some(HintLink::new(
"/instance-config#community-creation",
"Community creation policy",
)),
}),
_ => None,
}
}
+7 -2
View File
@@ -8,13 +8,18 @@ use super::types::SendSystemDmResponse;
impl AdminApiClient {
pub async fn send_system_dm(
&self,
user_ids: &[String],
user_ids: Option<&[String]>,
content: &str,
) -> ApiResult<SendSystemDmResponse> {
let body = generated_types::SendSystemDmRequest {
content: generated_types::SendSystemDmRequestContent::try_from(content)
.map_err(|e| ApiError::Parse(e.to_string()))?,
user_ids: user_ids.iter().map(|id| snowflake(id)).collect(),
user_ids: user_ids
.unwrap_or_default()
.iter()
.map(|id| snowflake(id))
.collect(),
all_users: user_ids.is_none().then_some(true),
};
let response = self
.generated()
@@ -43,6 +43,8 @@ pub struct InstancePolicyResponse {
pub direct_messages_locked: bool,
#[serde(default)]
pub premium_mode: PremiumMode,
#[serde(default = "default_guild_create_access")]
pub guild_create_access: bool,
#[serde(default)]
pub services: InstanceServicesOverrides,
#[serde(default)]
@@ -51,6 +53,10 @@ pub struct InstancePolicyResponse {
pub services_available: InstanceServicesAvailable,
}
fn default_guild_create_access() -> bool {
true
}
impl Default for InstancePolicyResponse {
fn default() -> Self {
Self {
@@ -59,6 +65,7 @@ impl Default for InstancePolicyResponse {
direct_messages_disabled: false,
direct_messages_locked: false,
premium_mode: PremiumMode::Everyone,
guild_create_access: default_guild_create_access(),
services: InstanceServicesOverrides::default(),
services_resolved: InstanceServicesResolved::default(),
services_available: InstanceServicesAvailable::default(),
@@ -656,6 +663,8 @@ pub struct InstancePolicyUpdateRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub direct_messages_disabled: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub guild_create_access: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub premium_mode: Option<PremiumMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub services: Option<InstanceServicesUpdateRequest>,
+1 -1
View File
@@ -4,5 +4,5 @@ use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct SendSystemDmResponse {
pub recipient_count: i64,
pub recipient_count: Option<i64>,
}
+1
View File
@@ -2,6 +2,7 @@
pub mod acl;
pub mod admin_flags;
pub mod admin_hints;
pub mod api;
pub mod config;
pub mod fonts;
+2 -1
View File
@@ -171,7 +171,8 @@ pub(crate) async fn system_dms_post(
let flash = if let Some(content) = content.as_deref()
&& !user_ids.is_empty()
{
match client.send_system_dm(&user_ids, content).await {
let recipients = (user_ids != ["*"]).then_some(user_ids.as_slice());
match client.send_system_dm(recipients, content).await {
Ok(_) => FlashData::success("System DM sent"),
Err(error) => {
tracing::warn!(%error, "admin API request failed: send system DM");
+5 -4
View File
@@ -734,6 +734,9 @@ fn build_policy_update(form: &MultiValueForm) -> InstanceConfigUpdateRequest {
let direct_messages_disabled = form
.first("policy_direct_messages_disabled")
.map(|value| value == "true");
let guild_create_access = form
.first("policy_guild_create_access")
.map(|value| value == "true");
let premium_mode = match form.first("policy_premium_mode") {
Some("mirror") => Some(PremiumMode::Mirror),
Some("everyone") => Some(PremiumMode::Everyone),
@@ -745,6 +748,7 @@ fn build_policy_update(form: &MultiValueForm) -> InstanceConfigUpdateRequest {
single_community_enabled: None,
single_community_name: None,
direct_messages_disabled,
guild_create_access,
premium_mode,
services,
}),
@@ -875,10 +879,7 @@ fn build_single_community_update(enabled: bool) -> InstanceConfigUpdateRequest {
InstanceConfigUpdateRequest {
policy: Some(InstancePolicyUpdateRequest {
single_community_enabled: Some(enabled),
single_community_name: None,
direct_messages_disabled: None,
premium_mode: None,
services: None,
..Default::default()
}),
..Default::default()
}
+25
View File
@@ -238,3 +238,28 @@ input:disabled + .checkbox-custom {
border: 2px solid transparent;
background-clip: content-box;
}
:target {
padding: 0.5rem;
border-radius: 0.25rem;
scroll-margin-top: 6rem;
animation: target-pulse 700ms ease-in-out 3;
}
@keyframes target-pulse {
0%,
100% {
background-color: transparent;
}
50% {
background-color: hsl(242 70% 55% / 0.18);
}
}
@media (prefers-reduced-motion: reduce) {
:target {
background-color: hsl(242 70% 55% / 0.12);
animation: none;
}
}
@@ -21,6 +21,7 @@ pub mod resource_link;
pub mod section_card;
pub mod stack;
pub mod table;
pub mod tooltip;
pub mod typography;
pub mod user_display;
pub mod user_profile_badges;
@@ -0,0 +1,93 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
use super::icons::paperclip_icon;
use maud::{Markup, html};
use std::sync::atomic::{AtomicUsize, Ordering};
static HINT_TOGGLE_ID: AtomicUsize = AtomicUsize::new(0);
pub struct HintLink<'a> {
href: &'a str,
label: &'a str,
}
impl<'a> HintLink<'a> {
pub fn new(href: &'a str, label: &'a str) -> Self {
debug_assert!(
href.starts_with('/'),
"hint link href must be admin-absolute: {href:?}"
);
debug_assert!(
href.contains('#'),
"hint link href should point at an anchor: {href:?}"
);
debug_assert!(!label.trim().is_empty(), "hint link needs a label");
Self { href, label }
}
}
pub struct Hint<'a> {
pub name: Option<&'a str>,
pub body: &'a str,
pub link: Option<HintLink<'a>>,
}
pub fn info(base: &str, hint: &Hint<'_>) -> Markup {
let aria_label = match hint.name {
Some(name) => format!("About {name}"),
None => "More information".to_owned(),
};
let toggle_id = format!(
"hint-toggle-{}",
HINT_TOGGLE_ID.fetch_add(1, Ordering::Relaxed)
);
html! {
span class="group relative inline-flex items-center" {
input type="checkbox" id=(toggle_id) class="peer sr-only";
label for=(toggle_id) tabindex="0" aria-label=(aria_label)
class="flex h-4 w-4 shrink-0 cursor-pointer items-center justify-center rounded-full \
font-semibold text-brand-primary leading-none active:scale-97 \
hover:text-brand-primary-dark" {
"?"
}
label for=(toggle_id) aria-hidden="true"
class="invisible fixed inset-0 z-20 cursor-default peer-checked:visible" {}
div class="invisible absolute bottom-full left-2 z-30 w-64 pb-3 pl-2 opacity-0 \
transition-[opacity,visibility] duration-200 ease-out motion-reduce:transition-none \
group-hover:visible group-hover:opacity-100 \
group-focus-within:visible group-focus-within:opacity-100 \
peer-checked:visible peer-checked:opacity-100" {
div class="rounded-lg border border-neutral-200 bg-white p-3 text-neutral-600 \
text-xs shadow-lg" {
@if let Some(name) = hint.name {
p class="font-semibold text-neutral-900" { (name) }
}
p class=[hint.name.is_some().then_some("mt-1")] { (hint.body) }
@if let Some(link) = &hint.link {
a href={(base) (link.href)} hx-boost="false"
class="mt-2 inline-flex items-center gap-1 text-blue-600 hover:underline" {
(paperclip_icon(""))(link.label)
}
}
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::HintLink;
#[test]
#[should_panic(expected = "anchor")]
fn rejects_a_link_that_points_at_no_anchor() {
let _ = HintLink::new("/instance-config", "Instance policy");
}
#[test]
#[should_panic(expected = "label")]
fn rejects_a_link_with_no_label() {
let _ = HintLink::new("/instance-config#community-creation", " ");
}
}
@@ -245,6 +245,7 @@ fn policy_config_section(
(single_community_form(base, csrf_token, policy))
(direct_messages_form(base, csrf_token, policy))
(premium_mode_form(base, csrf_token, policy, premium_name))
(community_creation_form(base, csrf_token, policy))
(services_form(base, csrf_token, policy))
}
},
@@ -364,6 +365,37 @@ fn premium_mode_form(
}
}
fn community_creation_form(
base: &str,
csrf_token: &str,
policy: &InstancePolicyResponse,
) -> Markup {
html! {
div id="community-creation" class="space-y-4 border-t border-neutral-200 pt-6" {
h3 class="text-sm font-semibold text-neutral-900" { "Community creation" }
form method="post" action={(base) "/instance-config?action=update_policy"} {
(csrf_input(csrf_token))
div class="space-y-4" {
(select_input("policy_guild_create_access", "Who can create communities", &[
("true", "Everyone"),
("false", "Restricted"),
], if policy.guild_create_access { "true" } else { "false" }))
p class="text-xs text-neutral-500" {
"When restricted, only admins with the wildcard ACL and users matched by a "
a href={(base) "/limit-config"} class="text-blue-600 hover:underline" {
"limit rule"
}
" that grants Community Creation Access can create communities."
}
(form_actions(html! {
(submit_button("Save community creation policy"))
}))
}
}
}
}
}
fn service_select(name: &str, label: &str, override_value: Option<bool>, resolved: bool) -> Markup {
let selected = match override_value {
None => "inherit",
@@ -2,6 +2,7 @@
use crate::{
acl::{self, INSTANCE_LIMIT_CONFIG_UPDATE},
admin_hints,
api::types::{LimitConfigResponse, LimitKeyMetadata, LimitRule},
config::AdminConfig,
middleware::auth::AuthContext,
@@ -9,6 +10,7 @@ use crate::{
components::{
form::{FORM_INPUT_CLASS, csrf_input, danger_button, form_actions, submit_button},
page_container::{card_with_header, page_header},
tooltip,
},
layout::admin_layout,
},
@@ -208,7 +210,7 @@ fn rule_editor(
@for category in CATEGORY_ORDER {
@let keys = keys_for_category(response, category);
@if !keys.is_empty() {
(category_section(response, rule, category, &keys, can_update))
(category_section(&config.base_path, response, rule, category, &keys, can_update))
}
}
@if can_update {
@@ -274,6 +276,7 @@ fn keys_for_category(response: &LimitConfigResponse, category: &str) -> Vec<Stri
}
fn category_section(
base: &str,
response: &LimitConfigResponse,
rule: &LimitRule,
category: &str,
@@ -292,7 +295,7 @@ fn category_section(
div class="space-y-4" {
@for key in keys {
@if let Some(metadata) = response.metadata.get(key) {
(limit_field(response, rule, key, metadata, can_update))
(limit_field(base, response, rule, key, metadata, can_update))
}
}
}
@@ -301,6 +304,7 @@ fn category_section(
}
fn limit_field(
base: &str,
response: &LimitConfigResponse,
rule: &LimitRule,
key: &str,
@@ -319,9 +323,10 @@ fn limit_field(
.as_ref()
.is_some_and(|fields| fields.iter().any(|field| field == key));
if metadata.is_toggle {
toggle_field(key, metadata, current_value, modified, can_update)
toggle_field(base, key, metadata, current_value, modified, can_update)
} else {
numeric_field(
base,
key,
metadata,
current_value,
@@ -333,6 +338,7 @@ fn limit_field(
}
fn toggle_field(
base: &str,
key: &str,
metadata: &LimitKeyMetadata,
current_value: Option<u64>,
@@ -343,7 +349,7 @@ fn toggle_field(
html! {
div class={(field_class(modified, false))} {
div class="flex-1 space-y-1" {
(field_label_row(key, metadata, modified))
(field_label_row(base, key, metadata, modified))
p class="text-xs text-neutral-500" { (metadata.description) }
}
div class="shrink-0" {
@@ -369,6 +375,7 @@ fn toggle_field(
}
fn numeric_field(
base: &str,
key: &str,
metadata: &LimitKeyMetadata,
current_value: Option<u64>,
@@ -385,7 +392,7 @@ fn numeric_field(
html! {
div class={(field_class(modified, true))} {
div class="flex flex-wrap items-center justify-between gap-2" {
(field_label_row(key, metadata, modified))
(field_label_row(base, key, metadata, modified))
}
p class="text-xs text-neutral-500" {
(metadata.description)
@@ -417,10 +424,13 @@ fn numeric_field(
}
}
fn field_label_row(key: &str, metadata: &LimitKeyMetadata, modified: bool) -> Markup {
fn field_label_row(base: &str, key: &str, metadata: &LimitKeyMetadata, modified: bool) -> Markup {
html! {
div class="flex flex-wrap items-center gap-2" {
label for=(key) class="font-medium text-neutral-900 text-sm" { (metadata.label) }
@if let Some(hint) = admin_hints::limit_key_hint(key) {
(tooltip::info(base, &hint))
}
span class=(scope_class(&metadata.scope)) { (scope_label(&metadata.scope)) }
@if modified {
span class="rounded bg-neutral-100 px-1.5 py-0.5 text-neutral-700 text-xs" { "Modified" }
@@ -58,7 +58,7 @@ pub fn system_dm_page(
(form_field_group(
"Recipient user IDs", "system-dm-user-ids",
true, None,
Some("One per line. Snowflake IDs only."),
Some("One per line. Snowflake IDs only, or a single * to send to every user."),
html! {
textarea id="system-dm-user-ids" name="user_ids"
required rows="10"
@@ -461,6 +461,7 @@ fn deserialize_instance_config_response_with_unknown_keys() {
"single_community_guild_id": null,
"direct_messages_disabled": false,
"direct_messages_locked": false,
"guild_create_access": false,
"premium_mode": "mirror",
"services": {
"gif_enabled": true,
+1 -4
View File
@@ -11,13 +11,10 @@
},
"dependencies": {
"@aws-sdk/client-s3": "catalog:",
"@pkgs/cassandra": "workspace:*",
"@fluxer/geo_utils": "workspace:*",
"@fluxer/instance_bootstrap": "workspace:*",
"@fluxer/ip_utils": "workspace:*",
"@pkgs/postgres": "workspace:*",
"maxmind": "catalog:",
"zod": "catalog:"
"maxmind": "catalog:"
},
"devDependencies": {
"@types/node": "catalog:",
@@ -1,60 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {ICassandraClient} from '@pkgs/cassandra/src/Client';
import type {IpInfoCache} from '@pkgs/geoip/src/IpInfoService';
const TABLE = 'ipinfo_cache';
const SELECT_CQL = `SELECT payload FROM ${TABLE} WHERE cache_key = :cache_key LIMIT 1;`;
const INSERT_WITH_TTL_CQL = `INSERT INTO ${TABLE} (cache_key, payload) VALUES (:cache_key, :payload) USING TTL :ttl;`;
const INSERT_DEFAULT_TTL_CQL = `INSERT INTO ${TABLE} (cache_key, payload) VALUES (:cache_key, :payload);`;
interface CassandraIpInfoCacheOptions {
client?: ICassandraClient;
getClient?: () => ICassandraClient;
}
export function createCassandraIpInfoCache(options: CassandraIpInfoCacheOptions): IpInfoCache {
return {
async get<T>(key: string): Promise<T | null> {
try {
const client = options.client ?? options.getClient?.();
if (!client) {
return null;
}
const result = await client.execute({cql: SELECT_CQL, params: {cache_key: key}});
const row = result.first();
if (!row) return null;
const payload = row.get('payload');
if (typeof payload !== 'string') return null;
return JSON.parse(payload) as T;
} catch {
return null;
}
},
async set<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {
let payload: string;
try {
payload = JSON.stringify(value);
} catch {
return;
}
try {
const client = options.client ?? options.getClient?.();
if (!client) {
return;
}
if (ttlSeconds != null && Number.isFinite(ttlSeconds) && ttlSeconds > 0) {
await client.execute({
cql: INSERT_WITH_TTL_CQL,
params: {cache_key: key, payload, ttl: ttlSeconds},
});
} else {
await client.execute({
cql: INSERT_DEFAULT_TTL_CQL,
params: {cache_key: key, payload},
});
}
} catch {}
},
};
}
@@ -1,119 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {randomUUID} from 'node:crypto';
import type {ICassandraClient} from '@pkgs/cassandra/src/Client';
import type {IpInfoRequestAuditEvent, IpInfoRequestAuditLogger} from '@pkgs/geoip/src/IpInfoService';
const TABLE = 'ipinfo_requests_by_hour';
const INSERT_CQL = `INSERT INTO ${TABLE} (
bucket_date,
bucket_hour,
requested_at,
event_id,
source,
reason,
ip,
cache_key,
request_url,
http_status,
outcome,
available,
risk_note,
latency_ms,
response_ip,
country_code,
asn,
is_anonymous,
is_tor,
is_vpn,
is_proxy,
is_residential_proxy,
metadata_json
) VALUES (
:bucket_date,
:bucket_hour,
:requested_at,
:event_id,
:source,
:reason,
:ip,
:cache_key,
:request_url,
:http_status,
:outcome,
:available,
:risk_note,
:latency_ms,
:response_ip,
:country_code,
:asn,
:is_anonymous,
:is_tor,
:is_vpn,
:is_proxy,
:is_residential_proxy,
:metadata_json
);`;
interface CassandraIpInfoRequestAuditOptions {
client?: ICassandraClient;
getClient?: () => ICassandraClient;
}
export function createCassandraIpInfoRequestAuditLogger(
options: CassandraIpInfoRequestAuditOptions,
): IpInfoRequestAuditLogger {
return {
async record(event: IpInfoRequestAuditEvent): Promise<void> {
try {
const client = options.client ?? options.getClient?.();
if (!client) {
return;
}
await client.execute({
cql: INSERT_CQL,
params: {
bucket_date: formatUtcDate(event.requestedAt),
bucket_hour: event.requestedAt.getUTCHours(),
requested_at: event.requestedAt,
event_id: randomUUID(),
source: event.source,
reason: event.reason,
ip: event.ip,
cache_key: event.cacheKey,
request_url: event.requestUrl,
http_status: event.httpStatus,
outcome: event.outcome,
available: event.available,
risk_note: event.note,
latency_ms: event.latencyMs,
response_ip: event.responseIp,
country_code: event.countryCode,
asn: event.asnNumber,
is_anonymous: event.isAnonymous,
is_tor: event.isTor,
is_vpn: event.isVpn,
is_proxy: event.isProxy,
is_residential_proxy: event.isResidentialProxy,
metadata_json: serializeMetadata(event.metadata),
},
});
} catch {}
},
};
}
function formatUtcDate(value: Date): string {
return value.toISOString().slice(0, 10);
}
function serializeMetadata(metadata: IpInfoRequestAuditEvent['metadata']): string | null {
if (!metadata || Object.keys(metadata).length === 0) {
return null;
}
try {
return JSON.stringify(metadata);
} catch {
return null;
}
}
-506
View File
@@ -1,506 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {getSameIpDecisionKey} from '@fluxer/ip_utils/src/IpAddress';
import {z} from 'zod';
const IPINFO_BASE_URL = 'https://api.ipinfo.io/lookup';
const FETCH_TIMEOUT_MS = 3000;
const CACHE_KEY_PREFIX = 'ipinfo:max:';
const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/u;
const POSITIVE_CACHE_TTL_SECONDS = 7 * 24 * 60 * 60;
const NEGATIVE_CACHE_TTL_SECONDS = 14 * 24 * 60 * 60;
const FAILURE_TTL_REQUEST_FAILED_SECONDS = 60;
const FAILURE_TTL_HTTP_ERROR_SECONDS = 300;
const FAILURE_TTL_QUOTA_SECONDS = 900;
const FAILURE_TTL_SCHEMA_MISMATCH_SECONDS = 600;
export interface IpInfoGeoBlock {
countryCode: string | null;
countryName: string | null;
continent: string | null;
continentCode: string | null;
region: string | null;
regionCode: string | null;
city: string | null;
postalCode: string | null;
timezone: string | null;
latitude: number | null;
longitude: number | null;
accuracyRadiusKm: number | null;
}
export interface IpInfoAsnBlock {
asn: string | null;
number: number | null;
name: string | null;
domain: string | null;
type: string | null;
}
export interface IpInfoMobileBlock {
name: string | null;
mcc: string | null;
mnc: string | null;
}
export interface IpInfoAnonymousBlock {
isAnonymous: boolean;
providerName: string | null;
isVpn: boolean;
isProxy: boolean;
isResidentialProxy: boolean;
isTor: boolean;
isRelay: boolean;
percentDaysSeen: number | null;
}
export interface IpInfoFlags {
isAnycast: boolean;
isHosting: boolean;
isMobile: boolean;
isSatellite: boolean;
}
export interface IpInfoLookupResult {
ip: string;
available: boolean;
note: string;
geo: IpInfoGeoBlock;
asn: IpInfoAsnBlock;
mobile: IpInfoMobileBlock;
anonymous: IpInfoAnonymousBlock;
flags: IpInfoFlags;
}
export interface IpInfoCache {
get<T>(key: string): Promise<T | null>;
set<T>(key: string, value: T, ttlSeconds?: number): Promise<void>;
}
export interface CachedIpInfoFailure extends IpInfoLookupResult {
cachedFailure: true;
failureOutcome: 'http_error' | 'request_failed' | 'schema_mismatch';
failureHttpStatus: number | null;
cachedAtMs: number;
}
export function isCachedIpInfoFailure(value: unknown): value is CachedIpInfoFailure {
return typeof value === 'object' && value !== null && (value as {available?: unknown}).available === false;
}
function failureCacheTtlSeconds(outcome: CachedIpInfoFailure['failureOutcome'], httpStatus: number | null): number {
if (outcome === 'request_failed') return FAILURE_TTL_REQUEST_FAILED_SECONDS;
if (outcome === 'schema_mismatch') return FAILURE_TTL_SCHEMA_MISMATCH_SECONDS;
if (httpStatus === 402 || httpStatus === 403 || httpStatus === 429) return FAILURE_TTL_QUOTA_SECONDS;
return FAILURE_TTL_HTTP_ERROR_SECONDS;
}
export interface IpInfoLookupContext {
source?: string;
reason?: string;
metadata?: Record<string, string | number | boolean | null>;
}
export interface IpInfoRequestAuditEvent {
requestedAt: Date;
ip: string;
cacheKey: string;
source: string;
reason: string | null;
metadata?: Record<string, string | number | boolean | null>;
outcome: 'http_success' | 'http_error' | 'request_failed' | 'schema_mismatch';
httpStatus: number | null;
available: boolean;
note: string;
latencyMs: number;
requestUrl: string;
responseIp: string | null;
countryCode: string | null;
asnNumber: number | null;
isAnonymous: boolean;
isTor: boolean;
isVpn: boolean;
isProxy: boolean;
isResidentialProxy: boolean;
}
export interface IpInfoRequestAuditLogger {
record(event: IpInfoRequestAuditEvent): Promise<void>;
}
interface IpInfoServiceContext {
apiKey: string;
cache: IpInfoCache;
auditLogger?: IpInfoRequestAuditLogger;
}
export interface IpInfoService {
lookup(ip: string, context?: IpInfoLookupContext): Promise<IpInfoLookupResult>;
}
const IpInfoDateSchema = z.string().regex(ISO_DATE_REGEX);
const RawIpInfoGeoSchema = z.object({
city: z.string().optional(),
region: z.string().optional(),
region_code: z.string().optional(),
country: z.string().optional(),
country_code: z.string().optional(),
continent: z.string().optional(),
continent_code: z.string().optional(),
latitude: z.number().optional(),
longitude: z.number().optional(),
timezone: z.string().optional(),
postal_code: z.string().optional(),
dma_code: z.string().optional(),
geoname_id: z.string().optional(),
radius: z.number().int().optional(),
last_changed: IpInfoDateSchema.optional(),
});
const RawIpInfoAsSchema = z.object({
asn: z.string().optional(),
name: z.string().optional(),
domain: z.string().optional(),
type: z.string().optional(),
last_changed: IpInfoDateSchema.optional(),
});
const RawIpInfoMobileSchema = z.object({
name: z.string().optional(),
mcc: z.string().optional(),
mnc: z.string().optional(),
});
const RawIpInfoAnonymousSchema = z.object({
name: z.string().optional(),
last_seen: IpInfoDateSchema.optional(),
percent_days_seen: z.number().int().optional(),
is_proxy: z.boolean().optional(),
is_relay: z.boolean().optional(),
is_tor: z.boolean().optional(),
is_vpn: z.boolean().optional(),
is_res_proxy: z.boolean().optional(),
});
const RawIpInfoResponseSchema = z.object({
ip: z.string(),
hostname: z.string().optional(),
geo: RawIpInfoGeoSchema,
as: RawIpInfoAsSchema,
mobile: RawIpInfoMobileSchema.optional(),
anonymous: RawIpInfoAnonymousSchema,
is_anonymous: z.boolean().optional(),
is_anycast: z.boolean().optional(),
is_hosting: z.boolean().optional(),
is_mobile: z.boolean().optional(),
is_satellite: z.boolean().optional(),
});
type RawIpInfoResponse = z.infer<typeof RawIpInfoResponseSchema>;
export function createIpInfoService(ctx: IpInfoServiceContext): IpInfoService {
const inflight: Map<string, Promise<IpInfoLookupResult>> = new Map();
return {
async lookup(ip: string, context?: IpInfoLookupContext): Promise<IpInfoLookupResult> {
const cacheKey = `${CACHE_KEY_PREFIX}${getSameIpDecisionKey(ip) ?? ip}`;
const cached = await ctx.cache.get<IpInfoLookupResult>(cacheKey);
if (cached !== null) {
if (isCachedIpInfoFailure(cached)) {
return unavailable(ip, cached.note);
}
return {...cached, ip};
}
const existing = inflight.get(cacheKey);
if (existing) {
const result = await existing;
return {...result, ip};
}
const requestedAt = new Date();
const startedAt = Date.now();
const requestUrl = `${IPINFO_BASE_URL}/${encodeURIComponent(ip)}`;
const fetchUrl = `${requestUrl}?token=${encodeURIComponent(ctx.apiKey)}`;
const finalize = async (params: {
result: IpInfoLookupResult;
outcome: IpInfoRequestAuditEvent['outcome'];
httpStatus: number | null;
}): Promise<IpInfoLookupResult> => {
await ctx.auditLogger
?.record({
requestedAt,
ip,
cacheKey,
source: context?.source ?? 'unknown',
reason: context?.reason ?? null,
metadata: context?.metadata,
outcome: params.outcome,
httpStatus: params.httpStatus,
available: params.result.available,
note: params.result.note,
latencyMs: Date.now() - startedAt,
requestUrl,
responseIp: params.result.available ? params.result.ip : null,
countryCode: params.result.geo.countryCode,
asnNumber: params.result.asn.number,
isAnonymous: params.result.anonymous.isAnonymous,
isTor: params.result.anonymous.isTor,
isVpn: params.result.anonymous.isVpn,
isProxy: params.result.anonymous.isProxy,
isResidentialProxy: params.result.anonymous.isResidentialProxy,
})
.catch(() => {});
return params.result;
};
const performLookup = async (): Promise<IpInfoLookupResult> => {
const finalizeFailure = async (params: {
result: IpInfoLookupResult;
outcome: CachedIpInfoFailure['failureOutcome'];
httpStatus: number | null;
}): Promise<IpInfoLookupResult> => {
const entry: CachedIpInfoFailure = {
...params.result,
cachedFailure: true,
failureOutcome: params.outcome,
failureHttpStatus: params.httpStatus,
cachedAtMs: Date.now(),
};
await ctx.cache
.set(cacheKey, entry, failureCacheTtlSeconds(params.outcome, params.httpStatus))
.catch(() => {});
return finalize(params);
};
const controller = new AbortController();
const timer = setTimeout(() => {
controller.abort(new DOMException('The operation was aborted due to timeout', 'TimeoutError'));
}, FETCH_TIMEOUT_MS);
timer.unref();
let payload: unknown;
try {
const res = await fetch(fetchUrl, {
signal: controller.signal,
headers: {Accept: 'application/json'},
});
if (!res.ok) {
return finalizeFailure({
result: unavailable(ip, `IPInfo HTTP ${res.status}`),
outcome: 'http_error',
httpStatus: res.status,
});
}
payload = await res.json();
} catch (err) {
const detail = err instanceof Error ? err.message : String(err);
return finalizeFailure({
result: unavailable(ip, `IPInfo request failed: ${detail}`),
outcome: 'request_failed',
httpStatus: null,
});
} finally {
clearTimeout(timer);
controller.abort();
}
const parsedResponse = RawIpInfoResponseSchema.safeParse(payload);
if (!parsedResponse.success) {
return finalizeFailure({
result: unavailable(ip, formatSchemaMismatch(parsedResponse.error)),
outcome: 'schema_mismatch',
httpStatus: 200,
});
}
const result = parseIpInfoResponse(parsedResponse.data);
const ttl = result.anonymous.isAnonymous ? POSITIVE_CACHE_TTL_SECONDS : NEGATIVE_CACHE_TTL_SECONDS;
await ctx.cache.set(cacheKey, result, ttl).catch(() => {});
return finalize({
result,
outcome: 'http_success',
httpStatus: 200,
});
};
const promise: Promise<IpInfoLookupResult> = performLookup().finally(() => {
if (inflight.get(cacheKey) === promise) {
inflight.delete(cacheKey);
}
});
inflight.set(cacheKey, promise);
return promise;
},
};
}
export function createUnavailableIpInfoService(reason = 'IPInfo not configured'): IpInfoService {
return {
async lookup(ip: string): Promise<IpInfoLookupResult> {
return unavailable(ip, reason);
},
};
}
function unavailable(ip: string, reason: string): IpInfoLookupResult {
return {
ip,
available: false,
note: reason,
geo: emptyGeo(),
asn: emptyAsn(),
mobile: emptyMobile(),
anonymous: emptyAnonymous(),
flags: emptyFlags(),
};
}
function emptyGeo(): IpInfoGeoBlock {
return {
countryCode: null,
countryName: null,
continent: null,
continentCode: null,
region: null,
regionCode: null,
city: null,
postalCode: null,
timezone: null,
latitude: null,
longitude: null,
accuracyRadiusKm: null,
};
}
function emptyAsn(): IpInfoAsnBlock {
return {asn: null, number: null, name: null, domain: null, type: null};
}
function emptyMobile(): IpInfoMobileBlock {
return {name: null, mcc: null, mnc: null};
}
function emptyAnonymous(): IpInfoAnonymousBlock {
return {
isAnonymous: false,
providerName: null,
isVpn: false,
isProxy: false,
isResidentialProxy: false,
isTor: false,
isRelay: false,
percentDaysSeen: null,
};
}
function emptyFlags(): IpInfoFlags {
return {isAnycast: false, isHosting: false, isMobile: false, isSatellite: false};
}
function parseIpInfoResponse(raw: RawIpInfoResponse): IpInfoLookupResult {
const geo = raw.geo;
const anon = raw.anonymous;
const isAnonymous =
raw.is_anonymous === true ||
anon.is_res_proxy === true ||
anon.is_vpn === true ||
anon.is_proxy === true ||
anon.is_tor === true ||
anon.is_relay === true;
return {
ip: raw.ip,
available: true,
note: describeAnonymity(isAnonymous, anon),
geo: {
countryCode: normalizeCountryCode(geo.country_code),
countryName: geo.country ?? null,
continent: geo?.continent ?? null,
continentCode: normalizeContinentCode(geo.continent_code),
region: geo.region ?? null,
regionCode: normalizeRegionCode(geo.region_code),
city: geo.city ?? null,
postalCode: geo.postal_code ?? null,
timezone: geo.timezone ?? null,
latitude: normalizeCoordinate(geo.latitude),
longitude: normalizeCoordinate(geo.longitude),
accuracyRadiusKm: typeof geo?.radius === 'number' && Number.isFinite(geo.radius) ? geo.radius : null,
},
asn: parseAsnBlock(raw.as),
mobile: {
name: raw.mobile?.name ?? null,
mcc: raw.mobile?.mcc ?? null,
mnc: raw.mobile?.mnc ?? null,
},
anonymous: {
isAnonymous,
providerName: anon?.name ?? null,
isVpn: anon?.is_vpn === true,
isProxy: anon?.is_proxy === true,
isResidentialProxy: anon?.is_res_proxy === true,
isTor: anon?.is_tor === true,
isRelay: anon?.is_relay === true,
percentDaysSeen: typeof anon?.percent_days_seen === 'number' ? anon.percent_days_seen : null,
},
flags: {
isAnycast: raw.is_anycast === true,
isHosting: raw.is_hosting === true,
isMobile: raw.is_mobile === true,
isSatellite: raw.is_satellite === true,
},
};
}
function formatSchemaMismatch(error: z.ZodError): string {
const issue = error.issues[0];
if (!issue) {
return 'IPInfo response schema mismatch';
}
const path = issue.path.length > 0 ? issue.path.join('.') : '<root>';
return `IPInfo response schema mismatch at ${path}: ${issue.message}`;
}
function parseAsnBlock(as: RawIpInfoResponse['as']): IpInfoAsnBlock {
const raw = as?.asn ?? null;
const numeric = raw ? Number(raw.replace(/^AS/i, '')) : Number.NaN;
return {
asn: raw,
number: Number.isFinite(numeric) ? numeric : null,
name: as?.name ?? null,
domain: as?.domain ?? null,
type: as?.type ?? null,
};
}
function describeAnonymity(isAnonymous: boolean, anon: RawIpInfoResponse['anonymous']): string {
if (!isAnonymous) {
return 'IPInfo: IP is not anonymous';
}
if (!anon) {
return 'IPInfo: anonymous IP';
}
const flags: Array<string> = [];
if (anon.is_res_proxy) flags.push('residential proxy');
if (anon.is_vpn) flags.push('VPN');
if (anon.is_proxy) flags.push('proxy');
if (anon.is_tor) flags.push('Tor');
if (anon.is_relay) flags.push('relay');
const provider = anon.name ? ` (provider: ${anon.name})` : '';
const seen = anon.percent_days_seen != null ? `, seen ${anon.percent_days_seen}% of days` : '';
return `IPInfo: anonymous IP${provider} — ${flags.join(', ')}${seen}`;
}
function normalizeCountryCode(value: string | undefined): string | null {
if (!value) {
return null;
}
const normalized = value.trim().toUpperCase();
return /^[A-Z]{2}$/u.test(normalized) ? normalized : null;
}
function normalizeContinentCode(value: string | undefined): string | null {
if (!value) {
return null;
}
const normalized = value.trim().toUpperCase();
return /^[A-Z]{2}$/u.test(normalized) ? normalized : null;
}
function normalizeRegionCode(value: string | undefined): string | null {
if (!value) {
return null;
}
const normalized = value.trim().toUpperCase();
return normalized.length > 0 ? normalized : null;
}
function normalizeCoordinate(value: number | undefined): number | null {
return typeof value === 'number' && Number.isFinite(value) ? value : null;
}
@@ -1,153 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {randomUUID} from 'node:crypto';
import type {IpInfoCache, IpInfoRequestAuditEvent, IpInfoRequestAuditLogger} from '@pkgs/geoip/src/IpInfoService';
import {type IPostgresClient, quoteIdentifier} from '@pkgs/postgres/src/Client';
interface PostgresIpInfoOptions {
client?: IPostgresClient;
getClient?: () => IPostgresClient;
onError?: (error: unknown, operation: string) => void;
}
const VALUE_SEPARATOR = '\u001f';
export const IPINFO_CACHE_TTL_SECONDS = 14 * 24 * 60 * 60;
export const IPINFO_REQUEST_AUDIT_TTL_SECONDS = 90 * 24 * 60 * 60;
function getClient(options: PostgresIpInfoOptions): IPostgresClient | null {
return options.client ?? options.getClient?.() ?? null;
}
function valueKey(value: unknown): string {
return JSON.stringify(value);
}
function rowKey(values: ReadonlyArray<unknown>): string {
return values.map(valueKey).join(VALUE_SEPARATOR);
}
function table(client: IPostgresClient): string {
return quoteIdentifier(client.kvTable());
}
async function upsertKvRow(
client: IPostgresClient,
tableName: string,
partitionKey: string,
key: string,
row: Record<string, unknown>,
ttlSeconds: number,
): Promise<void> {
const expiresAt = new Date(Date.now() + ttlSeconds * 1000);
await client.query(
`INSERT INTO ${table(client)} (table_name, partition_key, row_key, row_data, expires_at, updated_at)
VALUES ($1, $2, $3, $4::jsonb, $5, now())
ON CONFLICT (table_name, row_key)
DO UPDATE SET partition_key = EXCLUDED.partition_key, row_data = EXCLUDED.row_data, expires_at = EXCLUDED.expires_at, updated_at = now()`,
[tableName, partitionKey, key, JSON.stringify(row), expiresAt],
);
}
export function createPostgresIpInfoCache(options: PostgresIpInfoOptions): IpInfoCache {
return {
async get<T>(key: string): Promise<T | null> {
try {
const client = getClient(options);
if (!client) return null;
const result = await client.query<{row_data: {payload?: string}}>(
`SELECT row_data FROM ${table(client)} WHERE table_name = $1 AND row_key = $2 AND (expires_at IS NULL OR expires_at > now()) LIMIT 1`,
['ipinfo_cache', rowKey([key])],
);
const payload = result.rows[0]?.row_data?.payload;
return typeof payload === 'string' ? (JSON.parse(payload) as T) : null;
} catch (error) {
options.onError?.(error, 'ipinfo_cache_get');
return null;
}
},
async set<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {
let payload: string;
try {
payload = JSON.stringify(value);
} catch (error) {
options.onError?.(error, 'ipinfo_cache_serialize');
return;
}
try {
const client = getClient(options);
if (!client) return;
await upsertKvRow(
client,
'ipinfo_cache',
rowKey([key]),
rowKey([key]),
{cache_key: key, payload},
ttlSeconds != null && Number.isFinite(ttlSeconds) && ttlSeconds > 0 ? ttlSeconds : IPINFO_CACHE_TTL_SECONDS,
);
} catch (error) {
options.onError?.(error, 'ipinfo_cache_set');
}
},
};
}
export function createPostgresIpInfoRequestAuditLogger(options: PostgresIpInfoOptions): IpInfoRequestAuditLogger {
return {
async record(event: IpInfoRequestAuditEvent): Promise<void> {
try {
const client = getClient(options);
if (!client) return;
const bucketDate = formatUtcDate(event.requestedAt);
const bucketHour = event.requestedAt.getUTCHours();
const eventId = randomUUID();
await upsertKvRow(
client,
'ipinfo_requests_by_hour',
rowKey([bucketDate, bucketHour]),
rowKey([bucketDate, bucketHour, event.requestedAt.toISOString(), eventId]),
{
bucket_date: bucketDate,
bucket_hour: bucketHour,
requested_at: event.requestedAt.toISOString(),
event_id: eventId,
source: event.source,
reason: event.reason,
ip: event.ip,
cache_key: event.cacheKey,
request_url: event.requestUrl,
http_status: event.httpStatus,
outcome: event.outcome,
available: event.available,
risk_note: event.note,
latency_ms: event.latencyMs,
response_ip: event.responseIp,
country_code: event.countryCode,
asn: event.asnNumber,
is_anonymous: event.isAnonymous,
is_tor: event.isTor,
is_vpn: event.isVpn,
is_proxy: event.isProxy,
is_residential_proxy: event.isResidentialProxy,
metadata_json: serializeMetadata(event.metadata),
},
IPINFO_REQUEST_AUDIT_TTL_SECONDS,
);
} catch (error) {
options.onError?.(error, 'ipinfo_request_audit_record');
}
},
};
}
function formatUtcDate(value: Date): string {
return value.toISOString().slice(0, 10);
}
function serializeMetadata(metadata: IpInfoRequestAuditEvent['metadata']): string | null {
if (!metadata || Object.keys(metadata).length === 0) return null;
try {
return JSON.stringify(metadata);
} catch {
return null;
}
}
@@ -1,35 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {IpInfoCache} from '@pkgs/geoip/src/IpInfoService';
const DEFAULT_HOT_TTL_SECONDS = 10 * 60;
interface TieredIpInfoCacheOptions {
hot: IpInfoCache;
cold: IpInfoCache;
hotTtlSeconds?: number;
skipColdWrite?: (value: unknown) => boolean;
}
export function createTieredIpInfoCache(opts: TieredIpInfoCacheOptions): IpInfoCache {
const hotTtl = opts.hotTtlSeconds ?? DEFAULT_HOT_TTL_SECONDS;
return {
async get<T>(key: string): Promise<T | null> {
const hit = await opts.hot.get<T>(key).catch(() => null);
if (hit !== null) return hit;
const cold = await opts.cold.get<T>(key).catch(() => null);
if (cold === null) return null;
if (opts.skipColdWrite?.(cold) === true) return cold;
void opts.hot.set(key, cold, hotTtl).catch(() => {});
return cold;
},
async set<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {
const effectiveHotTtl = Math.max(1, Math.min(hotTtl, ttlSeconds ?? hotTtl));
const writes: Array<Promise<void>> = [opts.hot.set(key, value, effectiveHotTtl).catch(() => {})];
if (opts.skipColdWrite?.(value) !== true) {
writes.push(opts.cold.set(key, value, ttlSeconds).catch(() => {}));
}
await Promise.all(writes);
},
};
}
-3
View File
@@ -259,9 +259,6 @@ export function buildAPIConfigFromMaster(master: MasterConfig): APIConfig {
}
: undefined,
},
ipinfo: {
apiKey: master.integrations.ipinfo.api_key || undefined,
},
blocklistFeeds: {
enabled: master.integrations.blocklist_feeds.enabled ?? !master.instance.self_hosted,
},
+7 -10
View File
@@ -41,7 +41,6 @@ import type {StoreEntitlementService} from '@app/api/store_billing/StoreEntitlem
import type {UserService} from '@app/api/user/services/UserService';
import type {VoiceRepository} from '@app/api/voice/VoiceRepository';
import type {SendSystemDmResponse} from '@fluxer/schema/src/domains/admin/AdminSchemas';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
import type Stripe from 'stripe';
export class AdminService {
@@ -81,7 +80,6 @@ export class AdminService {
private readonly applicationRepository: IApplicationRepository,
private readonly stripe: Stripe | null = null,
private readonly jobLedger: IJobLedgerRepository,
private readonly ipInfoService: IpInfoService,
private readonly storeEntitlementService: StoreEntitlementService,
) {
const {users, gateway, worker, snowflake} = this.apiContext.services;
@@ -94,7 +92,6 @@ export class AdminService {
apiContext: this.apiContext,
adminRepository: this.adminRepository,
auditService: this.auditService,
ipInfoService: this.ipInfoService,
});
this.userService = new AdminUserService({
apiContext: this.apiContext,
@@ -181,20 +178,20 @@ export class AdminService {
}
async sendSystemDm(
data: {content: string; userIds: Array<string>},
data: {content: string; recipients: {kind: 'all'} | {kind: 'list'; userIds: Array<string>}},
adminUserId: UserID,
auditLogReason: string | null,
): Promise<SendSystemDmResponse> {
const recipientCount = data.recipients.kind === 'all' ? null : data.recipients.userIds.length;
await this.apiContext.services.worker.addJob(
'sendSystemDm',
{
content: data.content,
user_ids: data.userIds,
},
data.recipients.kind === 'all'
? {content: data.content, all_users: true}
: {content: data.content, user_ids: data.recipients.userIds},
{requireLedger: true},
);
const metadata = new Map<string, string>([
['recipient_count', data.userIds.length.toString()],
['recipient_count', recipientCount === null ? 'all' : recipientCount.toString()],
['content_length', data.content.length.toString()],
]);
await this.auditService.createAuditLog({
@@ -205,6 +202,6 @@ export class AdminService {
auditLogReason,
metadata,
});
return {recipient_count: data.userIds.length};
return {recipient_count: recipientCount};
}
}
@@ -338,7 +338,7 @@ export function BanAdminController(app: HonoApp) {
tags: ['Admin'],
requestSchema: AdminBlocklistEntryCreateRequest,
description:
'Add a value to a blocklist. The request body is the shape the blocklist named by list_type accepts, and the value is validated and canonicalized for that blocklist. Adding an IP address that is on the instance exemption list, or that IPInfo reports as a high blast-radius carrier NAT, is refused with 400 IP_BAN_DECLINED and recorded in the audit log.',
'Add a value to a blocklist. The request body is the shape the blocklist named by list_type accepts, and the value is validated and canonicalized for that blocklist. Adding an IP address that is on the instance exemption list is refused with 400 IP_BAN_DECLINED and recorded in the audit log.',
}),
async (ctx) => {
const adminService = ctx.get('adminService');
@@ -124,6 +124,7 @@ async function buildInstanceConfigResponse(): Promise<InstanceConfigResponse> {
single_community_guild_id: policy.single_community_guild_id,
direct_messages_disabled: policy.direct_messages_disabled,
direct_messages_locked: policy.direct_messages_locked,
guild_create_access: policy.guild_create_access,
premium_mode: policy.premium_mode,
services: {
gif_enabled: policy.gif_enabled,
@@ -831,6 +832,9 @@ function planInstancePolicyPatch(
patch.direct_messages_locked = true;
}
}
if (policy.guild_create_access !== undefined && policy.guild_create_access !== current.guild_create_access) {
patch.guild_create_access = policy.guild_create_access;
}
if (policy.services) {
if (policy.services.gif_enabled !== undefined) {
patch.gif_enabled = policy.services.gif_enabled ?? null;
@@ -23,7 +23,7 @@ export function SystemDmAdminController(app: HonoApp) {
security: 'adminApiKey',
tags: 'Admin',
description:
'Queue a worker job that delivers the same content to every listed user as a direct message from the system account. Progress is observable through the Jobs admin resource (task_type=sendSystemDm), and an in-flight broadcast is stopped by cancelling that job. Requires SYSTEM_DM_SEND permission.',
'Queue a worker job that delivers the same content to every listed user, or to every user when all_users is set, as a direct message from the system account. Progress is observable through the Jobs admin resource (task_type=sendSystemDm), and an in-flight broadcast is stopped by cancelling that job. Requires SYSTEM_DM_SEND permission.',
}),
async (ctx) => {
const adminService = ctx.get('adminService');
@@ -31,7 +31,12 @@ export function SystemDmAdminController(app: HonoApp) {
const auditLogReason = ctx.get('auditLogReason');
const payload = ctx.req.valid('json');
const result = await adminService.sendSystemDm(
{content: payload.content, userIds: payload.user_ids.map((id) => id.toString())},
{
content: payload.content,
recipients: payload.all_users
? {kind: 'all'}
: {kind: 'list', userIds: (payload.user_ids ?? []).map((id) => id.toString())},
},
adminUserId,
auditLogReason,
);
@@ -4,7 +4,6 @@ import type {ApiContext} from '@app/api/ApiContext';
import type {IAdminRepository} from '@app/api/admin/IAdminRepository';
import type {AdminAuditService} from '@app/api/admin/services/AdminAuditService';
import {createUserID, type UserID} from '@app/api/BrandedTypes';
import {getIpBanBlastRadiusVerdict, isSingleIpBanCandidate} from '@app/api/ban/IpBanCgnatGuard';
import {isIpBanExempt} from '@app/api/ban/IpBanExemptions';
import {
BANNED_AVATAR_HASHES_REFRESH_CHANNEL,
@@ -18,7 +17,6 @@ import {
} from '@app/api/constants/ContentModeration';
import {IP_BAN_REFRESH_CHANNEL} from '@app/api/constants/IpBan';
import type {BannedProfileSubstringScope} from '@app/api/database/types/AdminArchiveTypes';
import {Logger} from '@app/api/Logger';
import {bannedAvatarHashCache} from '@app/api/middleware/BannedAvatarHashCache';
import {fileShaCache} from '@app/api/middleware/FileShaCache';
import {ipBanCache} from '@app/api/middleware/IpBanMiddleware';
@@ -34,13 +32,11 @@ import {InputValidationError} from '@fluxer/errors/src/domains/core/InputValidat
import {NotFoundError} from '@fluxer/errors/src/domains/core/NotFoundError';
import {UnknownUserError} from '@fluxer/errors/src/domains/user/UnknownUserError';
import type {AdminBlocklistListType} from '@fluxer/schema/src/domains/admin/AdminBlocklistSchemas';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
interface AdminBanManagementServiceDeps {
apiContext: ApiContext;
adminRepository: IAdminRepository;
auditService: AdminAuditService;
ipInfoService: IpInfoService;
}
interface AdminBlocklistEntry {
@@ -146,20 +142,6 @@ export class AdminBanManagementService {
message: 'This IP address is on the instance exemption list',
});
}
if (await this.shouldSkipIpBanForCgnat(data.ip)) {
await auditService.createAuditLog({
adminUserId,
targetType: 'ip',
targetId: BigInt(0),
action: 'ban_ip_skipped_cgnat',
auditLogReason,
metadata: new Map([['ip', data.ip]]),
});
throw new BadRequestError({
code: APIErrorCodes.IP_BAN_DECLINED,
message: 'This IP address is a high blast-radius carrier network',
});
}
await adminRepository.banIp(data.ip);
ipBanCache.ban(data.ip);
await cacheService.publish(IP_BAN_REFRESH_CHANNEL, 'refresh');
@@ -200,25 +182,6 @@ export class AdminBanManagementService {
return {banned};
}
private async shouldSkipIpBanForCgnat(ip: string): Promise<boolean> {
if (!isSingleIpBanCandidate(ip)) {
return false;
}
try {
const {cgnat: highRisk} = await getIpBanBlastRadiusVerdict(ip, this.deps.ipInfoService, {
source: 'admin.ip_ban',
reason: 'pre_write_cgnat_guard',
});
if (highRisk) {
Logger.warn({ip}, 'Skipping IP ban because IPInfo indicates high CGNAT blast-radius risk');
}
return highRisk;
} catch (error) {
Logger.warn({error, ip}, 'IPInfo CGNAT guard failed while adding IP ban');
return false;
}
}
async banEmail(
data: {
email: string;
@@ -1,170 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {ApiContext} from '@app/api/ApiContext';
import type {IAdminRepository} from '@app/api/admin/IAdminRepository';
import type {AdminAuditService} from '@app/api/admin/services/AdminAuditService';
import {AdminBanManagementService} from '@app/api/admin/services/AdminBanManagementService';
import {createUserID} from '@app/api/BrandedTypes';
import {resetIpBanExemptionsForTesting} from '@app/api/ban/IpBanExemptions';
import {getConfig} from '@app/api/Config';
import {ipBanCache} from '@app/api/middleware/IpBanMiddleware';
import {APIErrorCodes} from '@fluxer/constants/src/ApiErrorCodes';
import {BadRequestError} from '@fluxer/errors/src/domains/core/BadRequestError';
import type {IpInfoLookupResult, IpInfoService} from '@pkgs/geoip/src/IpInfoService';
import {afterEach, beforeEach, describe, expect, it} from 'vitest';
const ADMIN_ID = createUserID(42n);
const EXEMPT_IP = '10.0.0.1';
const CARRIER_IP = '198.51.100.7';
const LOOKUP_FAILURE_IP = '203.0.113.9';
interface AuditCall {
action: string;
metadata: Map<string, string> | undefined;
}
function ipInfoResult(overrides: Partial<IpInfoLookupResult> = {}): IpInfoLookupResult {
return {
ip: CARRIER_IP,
available: true,
note: 'test',
geo: {
countryCode: 'US',
countryName: 'United States',
continent: 'North America',
continentCode: 'NA',
region: null,
regionCode: null,
city: null,
postalCode: null,
timezone: null,
latitude: null,
longitude: null,
accuracyRadiusKm: null,
},
asn: {
asn: 'AS64500',
number: 64500,
name: 'Test Carrier',
domain: null,
type: null,
},
mobile: {
name: null,
mcc: null,
mnc: null,
},
anonymous: {
isAnonymous: false,
providerName: null,
isVpn: false,
isProxy: false,
isResidentialProxy: false,
isTor: false,
isRelay: false,
percentDaysSeen: null,
},
flags: {
isAnycast: false,
isHosting: false,
isMobile: false,
isSatellite: false,
},
...overrides,
};
}
function createBanManagementService(lookup: (ip: string) => Promise<IpInfoLookupResult>) {
const bannedIps: Array<string> = [];
const auditCalls: Array<AuditCall> = [];
const adminRepository = {
banIp: async (ip: string) => {
bannedIps.push(ip);
},
};
const auditService = {
createAuditLog: async ({action, metadata}: AuditCall) => {
auditCalls.push({action, metadata});
},
};
const ipInfoService = {lookup: (ip: string) => lookup(ip)};
const apiContext = {
services: {
cache: {
publish: async () => {},
},
},
};
const service = new AdminBanManagementService({
apiContext: apiContext as unknown as ApiContext,
adminRepository: adminRepository as unknown as IAdminRepository,
auditService: auditService as unknown as AdminAuditService,
ipInfoService: ipInfoService as unknown as IpInfoService,
});
return {service, bannedIps, auditCalls};
}
describe('AdminBanManagementService banIp guards', () => {
let originalExemptIps: Array<string>;
beforeEach(() => {
const config = getConfig();
originalExemptIps = config.ipBanExemptIps;
config.ipBanExemptIps = [EXEMPT_IP];
resetIpBanExemptionsForTesting();
});
afterEach(() => {
ipBanCache.unban(LOOKUP_FAILURE_IP);
getConfig().ipBanExemptIps = originalExemptIps;
resetIpBanExemptionsForTesting();
});
it('refuses an exempt address with IP_BAN_DECLINED and writes no ban row', async () => {
const {service, bannedIps, auditCalls} = createBanManagementService(async () => ipInfoResult());
const error = await service.banIp({ip: EXEMPT_IP}, ADMIN_ID, null).then(
() => null,
(caught: unknown) => caught,
);
expect(error).toBeInstanceOf(BadRequestError);
expect((error as BadRequestError).code).toBe(APIErrorCodes.IP_BAN_DECLINED);
expect((error as BadRequestError).status).toBe(400);
expect(bannedIps).toEqual([]);
expect(auditCalls.map((call) => call.action)).toEqual(['ban_ip_skipped_exempt']);
expect(auditCalls[0].metadata?.get('ip')).toBe(EXEMPT_IP);
});
it('refuses a high blast-radius carrier address with IP_BAN_DECLINED and writes no ban row', async () => {
const {service, bannedIps, auditCalls} = createBanManagementService(async () =>
ipInfoResult({
mobile: {name: 'Example Mobile', mcc: '001', mnc: '01'},
flags: {isAnycast: false, isHosting: false, isMobile: true, isSatellite: false},
}),
);
const error = await service.banIp({ip: CARRIER_IP}, ADMIN_ID, null).then(
() => null,
(caught: unknown) => caught,
);
expect(error).toBeInstanceOf(BadRequestError);
expect((error as BadRequestError).code).toBe(APIErrorCodes.IP_BAN_DECLINED);
expect((error as BadRequestError).status).toBe(400);
expect(bannedIps).toEqual([]);
expect(auditCalls.map((call) => call.action)).toEqual(['ban_ip_skipped_cgnat']);
expect(auditCalls[0].metadata?.get('ip')).toBe(CARRIER_IP);
});
it('still writes the ban when the IPInfo lookup fails', async () => {
const {service, bannedIps, auditCalls} = createBanManagementService(async () => {
throw new Error('ipinfo is unreachable');
});
await expect(service.banIp({ip: LOOKUP_FAILURE_IP}, ADMIN_ID, null)).resolves.toBeUndefined();
expect(bannedIps).toEqual([LOOKUP_FAILURE_IP]);
expect(auditCalls.map((call) => call.action)).toEqual(['ban_ip']);
});
});
@@ -10,83 +10,24 @@ import {
type TestAccount,
} from '@app/api/auth/tests/AuthTestUtils';
import {createUserID} from '@app/api/BrandedTypes';
import {setInjectedIpInfoService} from '@app/api/middleware/ServiceMiddleware';
import {getAdminRepository} from '@app/api/middleware/ServiceSingletons';
import {type ApiTestHarness, createApiTestHarness} from '@app/api/test/ApiTestHarness';
import {HTTP_STATUS} from '@app/api/test/TestConstants';
import {createBuilder} from '@app/api/test/TestRequestBuilder';
import {UserRepository} from '@app/api/user/repositories/UserRepository';
import {DeletionReasons} from '@fluxer/constants/src/Core';
import type {IpInfoLookupResult} from '@pkgs/geoip/src/IpInfoService';
import {afterEach, beforeEach, describe, expect, test} from 'vitest';
function createUniqueTestIp(): string {
return `198.51.${randomInt(0, 256)}.${randomInt(1, 255)}`;
}
function ipInfoResult(ip: string, overrides: Partial<IpInfoLookupResult> = {}): IpInfoLookupResult {
return {
ip,
available: true,
note: 'test',
geo: {
countryCode: 'US',
countryName: 'United States',
continent: 'North America',
continentCode: 'NA',
region: null,
regionCode: null,
city: null,
postalCode: null,
timezone: null,
latitude: null,
longitude: null,
accuracyRadiusKm: null,
},
asn: {
asn: 'AS64500',
number: 64500,
name: 'Test ISP',
domain: null,
type: null,
},
mobile: {
name: null,
mcc: null,
mnc: null,
},
anonymous: {
isAnonymous: false,
providerName: null,
isVpn: false,
isProxy: false,
isResidentialProxy: false,
isTor: false,
isRelay: false,
percentDaysSeen: null,
},
flags: {
isAnycast: false,
isHosting: false,
isMobile: false,
isSatellite: false,
},
...overrides,
};
}
describe('Admin Deletion Queue', () => {
let harness: ApiTestHarness;
beforeEach(async () => {
harness = await createApiTestHarness();
setInjectedIpInfoService({
async lookup(ip: string) {
return ipInfoResult(ip);
},
});
});
afterEach(async () => {
setInjectedIpInfoService(undefined);
await harness?.shutdown();
});
test('admin scheduling queues deletion and rescheduling replaces the old Cassandra row', async () => {
@@ -0,0 +1,157 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {TestAccount} from '@app/api/auth/tests/AuthTestUtils';
import {createTestAccount, setUserACLs} from '@app/api/auth/tests/AuthTestUtils';
import {getConfig} from '@app/api/Config';
import type {ApiTestHarness} from '@app/api/test/ApiTestHarness';
import {createApiTestHarness} from '@app/api/test/ApiTestHarness';
import {HTTP_STATUS} from '@app/api/test/TestConstants';
import {createBuilder} from '@app/api/test/TestRequestBuilder';
import {AdminACLs} from '@fluxer/constants/src/AdminACLs';
import {APIErrorCodes} from '@fluxer/constants/src/ApiErrorCodes';
import type {LimitConfigSnapshot} from '@fluxer/limits/src/LimitTypes';
import type {InstanceConfigResponse} from '@fluxer/schema/src/domains/admin/AdminSchemas';
import type {GuildResponse} from '@fluxer/schema/src/domains/guild/GuildResponseSchemas';
import {afterAll, beforeAll, beforeEach, describe, expect, it} from 'vitest';
const COMMUNITY_CREATOR_TRAIT = 'community_creator';
interface LimitConfigReadResponse {
limit_config: LimitConfigSnapshot;
}
describe('guild creation access on a self-hosted instance', () => {
let harness: ApiTestHarness;
beforeAll(async () => {
harness = await createApiTestHarness();
});
beforeEach(async () => {
await harness.reset();
});
afterAll(async () => {
await harness.shutdown();
});
const asSelfHosted = async <T>(run: () => Promise<T>): Promise<T> => {
const config = getConfig();
const originalSelfHosted = config.instance.selfHosted;
config.instance.selfHosted = true;
try {
return await run();
} finally {
config.instance.selfHosted = originalSelfHosted;
}
};
const createAdmin = async (): Promise<TestAccount> =>
await setUserACLs(harness, await createTestAccount(harness), [
AdminACLs.AUTHENTICATE,
AdminACLs.INSTANCE_CONFIG_VIEW,
AdminACLs.INSTANCE_CONFIG_UPDATE,
AdminACLs.INSTANCE_LIMIT_CONFIG_VIEW,
AdminACLs.INSTANCE_LIMIT_CONFIG_UPDATE,
AdminACLs.USER_UPDATE_TRAITS,
]);
const createMember = async (): Promise<TestAccount> =>
await setUserACLs(harness, await createTestAccount(harness), []);
const setGuildCreateAccess = async (admin: TestAccount, enabled: boolean): Promise<void> => {
const updated = await createBuilder<InstanceConfigResponse>(harness, admin.token)
.patch('/admin/instance/config')
.body({policy: {guild_create_access: enabled}})
.execute();
expect(updated.policy.guild_create_access).toBe(enabled);
};
const readInstanceConfig = async (admin: TestAccount): Promise<InstanceConfigResponse> =>
await createBuilder<InstanceConfigResponse>(harness, admin.token).get('/admin/instance/config').execute();
const createGuild = (account: TestAccount, name: string) =>
createBuilder<GuildResponse>(harness, account.token).post('/guilds').body({name});
const grantGuildCreateToTrait = async (admin: TestAccount, trait: string): Promise<void> => {
const current = await createBuilder<LimitConfigReadResponse>(harness, admin.token)
.get('/admin/limit-config')
.expect(HTTP_STATUS.OK)
.execute();
await createBuilder(harness, admin.token)
.put('/admin/limit-config')
.body({
limit_config: {
traitDefinitions: [...current.limit_config.traitDefinitions, trait],
rules: [
...current.limit_config.rules,
{id: `grant_${trait}`, filters: {traits: [trait]}, limits: {feature_guild_create: 1}},
],
},
})
.expect(HTTP_STATUS.OK)
.execute();
};
const grantTrait = async (admin: TestAccount, account: TestAccount, trait: string): Promise<void> => {
await createBuilder(harness, admin.token)
.put(`/admin/users/${account.userId}/traits`)
.body({traits: [trait]})
.expect(HTTP_STATUS.OK)
.execute();
};
it('allows guild creation while the community creation policy is at its default', async () => {
const admin = await createAdmin();
expect((await readInstanceConfig(admin)).policy.guild_create_access).toBe(true);
const member = await createMember();
await asSelfHosted(async () => {
const guild = await createGuild(member, 'Default policy community').execute();
expect(guild.id).toBeTruthy();
});
});
it('stores a disabled policy and rejects guild creation for a member without a grant', async () => {
const admin = await createAdmin();
await setGuildCreateAccess(admin, false);
expect((await readInstanceConfig(admin)).policy.guild_create_access).toBe(false);
const member = await createMember();
await asSelfHosted(async () => {
await createGuild(member, 'Denied community')
.expect(HTTP_STATUS.FORBIDDEN, APIErrorCodes.GUILD_CREATION_PERMISSION_REQUIRED)
.execute();
});
});
it('allows guild creation only once a member holds the trait the grant rule targets', async () => {
const admin = await createAdmin();
await setGuildCreateAccess(admin, false);
await grantGuildCreateToTrait(admin, COMMUNITY_CREATOR_TRAIT);
const member = await createMember();
await asSelfHosted(async () => {
await createGuild(member, 'Ungranted community')
.expect(HTTP_STATUS.FORBIDDEN, APIErrorCodes.GUILD_CREATION_PERMISSION_REQUIRED)
.execute();
});
await grantTrait(admin, member, COMMUNITY_CREATOR_TRAIT);
await asSelfHosted(async () => {
const guild = await createGuild(member, 'Granted community').execute();
expect(guild.id).toBeTruthy();
});
});
it('allows guild creation for a member holding a wildcard ACL while the policy is disabled', async () => {
const admin = await createAdmin();
await setGuildCreateAccess(admin, false);
const member = await setUserACLs(harness, await createTestAccount(harness), [AdminACLs.WILDCARD]);
await asSelfHosted(async () => {
const guild = await createGuild(member, 'Wildcard community').execute();
expect(guild.id).toBeTruthy();
});
});
});
-80
View File
@@ -1,80 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {parseIpBanEntry} from '@app/api/utils/IpRangeUtils';
import {getSameIpDecisionKey} from '@fluxer/ip_utils/src/IpAddress';
import type {IpInfoLookupResult, IpInfoService} from '@pkgs/geoip/src/IpInfoService';
const VERDICT_CACHE_TTL_MS = 60 * 60 * 1000;
interface IpBanBlastRadiusVerdict {
cgnat: boolean;
sharedAccess: boolean;
}
interface CachedVerdict {
expiresAtMs: number;
verdict: IpBanBlastRadiusVerdict;
}
const verdictCache = new Map<string, CachedVerdict>();
function isAnonymousAccess(result: IpInfoLookupResult): boolean {
return (
result.anonymous.isAnonymous ||
result.anonymous.isVpn ||
result.anonymous.isProxy ||
result.anonymous.isResidentialProxy ||
result.anonymous.isTor ||
result.anonymous.isRelay
);
}
export function isHighCgnatBlastRadiusRisk(result: IpInfoLookupResult): boolean {
if (!result.available || result.flags.isHosting || isAnonymousAccess(result)) {
return false;
}
const asnType = result.asn.type?.trim().toLowerCase() ?? null;
return result.flags.isMobile || result.mobile.name !== null || asnType === 'mobile';
}
export function isHighSharedAccessBlastRadiusRisk(result: IpInfoLookupResult): boolean {
if (result.flags.isHosting || isAnonymousAccess(result)) {
return false;
}
const asnType = result.asn.type?.trim().toLowerCase() ?? null;
return result.flags.isAnycast || result.flags.isSatellite || asnType === 'education';
}
export function isSingleIpBanCandidate(value: string): boolean {
return parseIpBanEntry(value)?.type === 'single';
}
export async function getIpBanBlastRadiusVerdict(
ip: string,
ipInfoService: IpInfoService,
context: {
source: string;
reason: string;
},
): Promise<IpBanBlastRadiusVerdict> {
const now = Date.now();
const cacheKey = getSameIpDecisionKey(ip) ?? ip;
const cached = verdictCache.get(cacheKey);
if (cached && cached.expiresAtMs > now) {
return cached.verdict;
}
const result = await ipInfoService.lookup(ip, {
source: context.source,
reason: context.reason,
metadata: {policy: 'ip_ban_cgnat_guard'},
});
const verdict: IpBanBlastRadiusVerdict = {
cgnat: isHighCgnatBlastRadiusRisk(result),
sharedAccess: isHighSharedAccessBlastRadiusRisk(result),
};
verdictCache.set(cacheKey, {
verdict,
expiresAtMs: now + VERDICT_CACHE_TTL_MS,
});
return verdict;
}
@@ -1,45 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {Config} from '@app/api/Config';
import {Logger} from '@app/api/Logger';
import {getDefaultCassandraClient} from '@pkgs/cassandra/src/Client';
import {createCassandraIpInfoCache} from '@pkgs/geoip/src/CassandraIpInfoCache';
import {createCassandraIpInfoRequestAuditLogger} from '@pkgs/geoip/src/CassandraIpInfoRequestAudit';
import {type IpInfoCache, type IpInfoRequestAuditLogger, isCachedIpInfoFailure} from '@pkgs/geoip/src/IpInfoService';
import {createPostgresIpInfoCache, createPostgresIpInfoRequestAuditLogger} from '@pkgs/geoip/src/PostgresIpInfoKv';
import {createTieredIpInfoCache} from '@pkgs/geoip/src/TieredIpInfoCache';
import {getDefaultPostgresClient} from '@pkgs/postgres/src/Client';
interface BuildIpInfoCacheOptions {
hot: IpInfoCache;
}
export function buildIpInfoCache(options: BuildIpInfoCacheOptions): IpInfoCache {
if (Config.database.backend === 'postgres') {
return createTieredIpInfoCache({
hot: options.hot,
cold: createPostgresIpInfoCache({
getClient: getDefaultPostgresClient,
onError: (error, operation) => Logger.warn({error, operation}, 'Postgres IPInfo cache operation failed'),
}),
skipColdWrite: isCachedIpInfoFailure,
});
}
return createTieredIpInfoCache({
hot: options.hot,
cold: createCassandraIpInfoCache({getClient: getDefaultCassandraClient}),
skipColdWrite: isCachedIpInfoFailure,
});
}
export function buildIpInfoRequestAuditLogger(): IpInfoRequestAuditLogger {
if (Config.database.backend === 'postgres') {
return createPostgresIpInfoRequestAuditLogger({
getClient: getDefaultPostgresClient,
onError: (error, operation) => Logger.warn({error, operation}, 'Postgres IPInfo audit operation failed'),
});
}
return createCassandraIpInfoRequestAuditLogger({
getClient: getDefaultCassandraClient,
});
}
@@ -1,162 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {
isHighCgnatBlastRadiusRisk,
isHighSharedAccessBlastRadiusRisk,
isSingleIpBanCandidate,
} from '@app/api/ban/IpBanCgnatGuard';
import type {IpInfoLookupResult} from '@pkgs/geoip/src/IpInfoService';
import {describe, expect, it} from 'vitest';
function ipInfoResult(overrides: Partial<IpInfoLookupResult> = {}): IpInfoLookupResult {
return {
ip: '198.51.100.1',
available: true,
note: 'test',
geo: {
countryCode: 'US',
countryName: 'United States',
continent: 'North America',
continentCode: 'NA',
region: null,
regionCode: null,
city: null,
postalCode: null,
timezone: null,
latitude: null,
longitude: null,
accuracyRadiusKm: null,
},
asn: {
asn: 'AS64500',
number: 64500,
name: 'Test ISP',
domain: null,
type: null,
},
mobile: {
name: null,
mcc: null,
mnc: null,
},
anonymous: {
isAnonymous: false,
providerName: null,
isVpn: false,
isProxy: false,
isResidentialProxy: false,
isTor: false,
isRelay: false,
percentDaysSeen: null,
},
flags: {
isAnycast: false,
isHosting: false,
isMobile: false,
isSatellite: false,
},
...overrides,
};
}
describe('IpBanCgnatGuard', () => {
it('only treats single IP ban entries as CGNAT guard candidates', () => {
expect(isSingleIpBanCandidate('198.51.100.10')).toBe(true);
expect(isSingleIpBanCandidate('198.51.100.0/24')).toBe(false);
});
it('flags mobile carrier IPs as high blast-radius risk', () => {
expect(
isHighCgnatBlastRadiusRisk(
ipInfoResult({
mobile: {name: 'Example Mobile', mcc: '001', mnc: '01'},
flags: {isAnycast: false, isHosting: false, isMobile: true, isSatellite: false},
}),
),
).toBe(true);
});
it('does not exempt hosting or anonymous infrastructure', () => {
expect(
isHighCgnatBlastRadiusRisk(
ipInfoResult({
flags: {isAnycast: false, isHosting: true, isMobile: true, isSatellite: false},
}),
),
).toBe(false);
expect(
isHighCgnatBlastRadiusRisk(
ipInfoResult({
anonymous: {
isAnonymous: true,
providerName: 'Example VPN',
isVpn: true,
isProxy: false,
isResidentialProxy: false,
isTor: false,
isRelay: false,
percentDaysSeen: null,
},
flags: {isAnycast: false, isHosting: false, isMobile: true, isSatellite: false},
}),
),
).toBe(false);
});
it('flags satellite, anycast and education networks as high blast-radius risk', () => {
expect(
isHighSharedAccessBlastRadiusRisk(
ipInfoResult({
flags: {isAnycast: false, isHosting: false, isMobile: false, isSatellite: true},
}),
),
).toBe(true);
expect(
isHighSharedAccessBlastRadiusRisk(
ipInfoResult({
flags: {isAnycast: true, isHosting: false, isMobile: false, isSatellite: false},
}),
),
).toBe(true);
expect(
isHighSharedAccessBlastRadiusRisk(
ipInfoResult({asn: {asn: 'AS64500', number: 64500, name: 'Test University', domain: null, type: 'education'}}),
),
).toBe(true);
});
it('does not flag ordinary residential networks as shared-access risk', () => {
expect(isHighSharedAccessBlastRadiusRisk(ipInfoResult())).toBe(false);
});
it('does not treat shared-access networks as CGNAT risk', () => {
expect(
isHighCgnatBlastRadiusRisk(
ipInfoResult({
flags: {isAnycast: false, isHosting: false, isMobile: false, isSatellite: true},
}),
),
).toBe(false);
});
it('does not exempt hosting or anonymous shared-access infrastructure', () => {
expect(
isHighSharedAccessBlastRadiusRisk(
ipInfoResult({
flags: {isAnycast: true, isHosting: true, isMobile: false, isSatellite: false},
}),
),
).toBe(false);
expect(
isHighSharedAccessBlastRadiusRisk(
ipInfoResult({
anonymous: {
isAnonymous: true,
providerName: 'Example VPN',
isVpn: true,
isProxy: false,
isResidentialProxy: false,
isTor: false,
isRelay: false,
percentDaysSeen: null,
},
flags: {isAnycast: false, isHosting: false, isMobile: false, isSatellite: true},
}),
),
).toBe(false);
});
});
@@ -1,210 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {server} from '@app/api/test/msw/server';
import type {
CachedIpInfoFailure,
IpInfoCache,
IpInfoRequestAuditEvent,
IpInfoRequestAuditLogger,
} from '@pkgs/geoip/src/IpInfoService';
import {createIpInfoService} from '@pkgs/geoip/src/IpInfoService';
import {delay, HttpResponse, http} from 'msw';
import {describe, expect, it} from 'vitest';
interface RecordedSet {
key: string;
value: unknown;
ttlSeconds: number | undefined;
}
interface RecordingCache {
cache: IpInfoCache;
sets: Array<RecordedSet>;
}
function createRecordingCache(): RecordingCache {
const store = new Map<string, unknown>();
const sets: Array<RecordedSet> = [];
return {
sets,
cache: {
async get<T>(key: string): Promise<T | null> {
return (store.get(key) as T | undefined) ?? null;
},
async set<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {
store.set(key, value);
sets.push({key, value, ttlSeconds});
},
},
};
}
function createRecordingAuditLogger(): {logger: IpInfoRequestAuditLogger; events: Array<IpInfoRequestAuditEvent>} {
const events: Array<IpInfoRequestAuditEvent> = [];
return {
events,
logger: {
async record(event: IpInfoRequestAuditEvent): Promise<void> {
events.push(event);
},
},
};
}
function useLookupHandler(handler: () => Response | Promise<Response>): {count: () => number} {
let calls = 0;
server.use(
http.get('https://api.ipinfo.io/lookup/:ip', async () => {
calls += 1;
return await handler();
}),
);
return {count: () => calls};
}
function successPayload(ip: string, anonymous: Record<string, boolean> = {}): Response {
return HttpResponse.json({
ip,
geo: {country_code: 'US', country: 'United States'},
as: {asn: 'AS64500', name: 'Test ISP'},
anonymous,
});
}
describe('IpInfoService caching', () => {
it('negative-caches an HTTP error and serves the second lookup without a request', async () => {
const requests = useLookupHandler(() => new HttpResponse(null, {status: 500}));
const {cache, sets} = createRecordingCache();
const service = createIpInfoService({apiKey: 'token', cache});
const first = await service.lookup('203.0.113.1');
const second = await service.lookup('203.0.113.1');
expect(first.available).toBe(false);
expect(second.available).toBe(false);
expect(requests.count()).toBe(1);
expect(sets).toHaveLength(1);
expect(sets[0]?.ttlSeconds).toBe(300);
});
it('negative-caches a request failure for a short window', async () => {
useLookupHandler(async () => {
await delay(5000);
return successPayload('203.0.113.2');
});
const {cache, sets} = createRecordingCache();
const service = createIpInfoService({apiKey: 'token', cache});
const result = await service.lookup('203.0.113.2');
expect(result.available).toBe(false);
expect(sets[0]?.ttlSeconds).toBe(60);
expect((sets[0]?.value as CachedIpInfoFailure)?.failureOutcome).toBe('request_failed');
});
it('negative-caches a schema mismatch', async () => {
useLookupHandler(() => HttpResponse.json({}));
const {cache, sets} = createRecordingCache();
const service = createIpInfoService({apiKey: 'token', cache});
const result = await service.lookup('203.0.113.3');
expect(result.available).toBe(false);
expect(sets[0]?.ttlSeconds).toBe(600);
expect((sets[0]?.value as CachedIpInfoFailure)?.failureOutcome).toBe('schema_mismatch');
expect((sets[0]?.value as CachedIpInfoFailure)?.failureHttpStatus).toBe(200);
});
it('negative-caches a quota rejection for longer', async () => {
useLookupHandler(() => new HttpResponse(null, {status: 429}));
const {cache, sets} = createRecordingCache();
const service = createIpInfoService({apiKey: 'token', cache});
await service.lookup('203.0.113.4');
expect(sets[0]?.ttlSeconds).toBe(900);
});
it('returns a cached failure as a clean unavailable result', async () => {
useLookupHandler(() => new HttpResponse(null, {status: 500}));
const {cache} = createRecordingCache();
const service = createIpInfoService({apiKey: 'token', cache});
await service.lookup('203.0.113.6');
const cached = await service.lookup('203.0.113.6');
expect(cached).not.toHaveProperty('cachedFailure');
expect(cached).not.toHaveProperty('failureOutcome');
expect(cached).not.toHaveProperty('failureHttpStatus');
expect(cached).not.toHaveProperty('cachedAtMs');
expect(cached.ip).toBe('203.0.113.6');
expect(cached.note).toBe('IPInfo HTTP 500');
});
it('writes a cached failure that older readers can still consume', async () => {
useLookupHandler(() => new HttpResponse(null, {status: 500}));
const {cache, sets} = createRecordingCache();
const service = createIpInfoService({apiKey: 'token', cache});
await service.lookup('203.0.113.7');
const entry = sets[0]?.value as CachedIpInfoFailure;
expect(entry.cachedFailure).toBe(true);
expect(entry.failureOutcome).toBe('http_error');
expect(entry.failureHttpStatus).toBe(500);
expect(typeof entry.cachedAtMs).toBe('number');
const legacyView = {...entry, ip: '203.0.113.7'};
expect(legacyView.available).toBe(false);
expect(legacyView.geo.countryCode).toBeNull();
expect(legacyView.asn.number).toBeNull();
expect(legacyView.mobile.name).toBeNull();
expect(legacyView.anonymous.isAnonymous).toBe(false);
expect(legacyView.flags.isMobile).toBe(false);
});
it('keeps the existing success TTL selection', async () => {
useLookupHandler(() => successPayload('203.0.113.8'));
const plain = createRecordingCache();
await createIpInfoService({apiKey: 'token', cache: plain.cache}).lookup('203.0.113.8');
useLookupHandler(() => successPayload('203.0.113.9', {is_vpn: true}));
const anonymous = createRecordingCache();
await createIpInfoService({apiKey: 'token', cache: anonymous.cache}).lookup('203.0.113.9');
expect(plain.sets[0]?.ttlSeconds).toBe(14 * 24 * 60 * 60);
expect(anonymous.sets[0]?.ttlSeconds).toBe(7 * 24 * 60 * 60);
});
it('coalesces concurrent lookups across a failure', async () => {
const requests = useLookupHandler(() => new HttpResponse(null, {status: 500}));
const {cache, sets} = createRecordingCache();
const service = createIpInfoService({apiKey: 'token', cache});
const [first, second] = await Promise.all([service.lookup('203.0.113.10'), service.lookup('203.0.113.10')]);
expect(requests.count()).toBe(1);
expect(sets).toHaveLength(1);
expect(first.available).toBe(false);
expect(second.available).toBe(false);
});
it('coalesces concurrent lookups from different sources into one audited request', async () => {
const requests = useLookupHandler(() => successPayload('203.0.113.13'));
const {cache} = createRecordingCache();
const {logger, events} = createRecordingAuditLogger();
const service = createIpInfoService({apiKey: 'token', cache, auditLogger: logger});
const results = await Promise.all([
service.lookup('203.0.113.13', {source: 'admin.ip_ban', reason: 'ban'}),
service.lookup('203.0.113.13', {source: 'test.b'}),
service.lookup('203.0.113.13', {source: 'test.c'}),
]);
expect(requests.count()).toBe(1);
expect(results.every((result) => result.available)).toBe(true);
expect(events).toHaveLength(1);
expect(events[0]?.source).toBe('admin.ip_ban');
expect(events[0]?.outcome).toBe('http_success');
expect(events[0]?.note).toBe('IPInfo: IP is not anonymous');
});
});
@@ -1,75 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {IpInfoRequestAuditEvent} from '@pkgs/geoip/src/IpInfoService';
import {
createPostgresIpInfoCache,
createPostgresIpInfoRequestAuditLogger,
IPINFO_CACHE_TTL_SECONDS,
IPINFO_REQUEST_AUDIT_TTL_SECONDS,
} from '@pkgs/geoip/src/PostgresIpInfoKv';
import type {IPostgresClient} from '@pkgs/postgres/src/Client';
import {describe, expect, it} from 'vitest';
function recordingClient(writes: Array<Array<unknown>>): IPostgresClient {
return {
async query(_text: string, values?: Array<unknown>) {
writes.push(values ?? []);
return {rows: [], rowCount: 1};
},
kvTable() {
return 'kv';
},
} as never;
}
function expectExpiresIn(values: Array<unknown> | undefined, ttlSeconds: number): void {
const expiresAt = values?.[4];
expect(expiresAt).toBeInstanceOf(Date);
const remainingSeconds = ((expiresAt as Date).getTime() - Date.now()) / 1000;
expect(remainingSeconds).toBeGreaterThan(ttlSeconds - 10);
expect(remainingSeconds).toBeLessThanOrEqual(ttlSeconds);
}
const EVENT: IpInfoRequestAuditEvent = {
requestedAt: new Date('2026-09-21T12:00:00.000Z'),
ip: '192.0.2.1',
cacheKey: 'ip:192.0.2.1',
source: 'test',
reason: null,
outcome: 'http_success',
httpStatus: 200,
available: true,
note: 'none',
latencyMs: 12,
requestUrl: 'https://ipinfo.test/192.0.2.1',
responseIp: '192.0.2.1',
countryCode: 'SE',
asnNumber: 64500,
isAnonymous: false,
isTor: false,
isVpn: false,
isProxy: false,
isResidentialProxy: false,
};
describe('Postgres ipinfo KV expiry', () => {
it('expires request audit rows after 90 days', async () => {
const writes: Array<Array<unknown>> = [];
await createPostgresIpInfoRequestAuditLogger({client: recordingClient(writes)}).record(EVENT);
expect(writes).toHaveLength(1);
expect(writes[0]?.[0]).toBe('ipinfo_requests_by_hour');
expectExpiresIn(writes[0], IPINFO_REQUEST_AUDIT_TTL_SECONDS);
});
it('falls back to the 14-day cache default', async () => {
const writes: Array<Array<unknown>> = [];
const cache = createPostgresIpInfoCache({client: recordingClient(writes)});
await cache.set('fallback', {ok: true});
await cache.set('zero', {ok: true}, 0);
await cache.set('short', {ok: true}, 60);
expect(writes.map((values) => values[0])).toEqual(['ipinfo_cache', 'ipinfo_cache', 'ipinfo_cache']);
expectExpiresIn(writes[0], IPINFO_CACHE_TTL_SECONDS);
expectExpiresIn(writes[1], IPINFO_CACHE_TTL_SECONDS);
expectExpiresIn(writes[2], 60);
});
});
@@ -1,130 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {IpInfoCache} from '@pkgs/geoip/src/IpInfoService';
import {createTieredIpInfoCache} from '@pkgs/geoip/src/TieredIpInfoCache';
import {describe, expect, it} from 'vitest';
interface RecordedSet {
key: string;
value: unknown;
ttlSeconds: number | undefined;
}
interface RecordingCache {
cache: IpInfoCache;
store: Map<string, unknown>;
sets: Array<RecordedSet>;
}
function createRecordingCache(): RecordingCache {
const store = new Map<string, unknown>();
const sets: Array<RecordedSet> = [];
return {
store,
sets,
cache: {
async get<T>(key: string): Promise<T | null> {
return (store.get(key) as T | undefined) ?? null;
},
async set<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {
store.set(key, value);
sets.push({key, value, ttlSeconds});
},
},
};
}
describe('TieredIpInfoCache', () => {
it('clamps the hot TTL to the requested TTL and passes the raw TTL to the cold tier', async () => {
const hot = createRecordingCache();
const cold = createRecordingCache();
const tiered = createTieredIpInfoCache({hot: hot.cache, cold: cold.cache});
await tiered.set('a', {available: false}, 60);
expect(hot.sets).toEqual([{key: 'a', value: {available: false}, ttlSeconds: 60}]);
expect(cold.sets).toEqual([{key: 'a', value: {available: false}, ttlSeconds: 60}]);
});
it('caps the hot TTL at the configured hot window', async () => {
const hot = createRecordingCache();
const cold = createRecordingCache();
const tiered = createTieredIpInfoCache({hot: hot.cache, cold: cold.cache});
await tiered.set('a', {available: true}, 100000);
expect(hot.sets[0]?.ttlSeconds).toBe(600);
expect(cold.sets[0]?.ttlSeconds).toBe(100000);
});
it('uses the hot window when no TTL is supplied', async () => {
const hot = createRecordingCache();
const cold = createRecordingCache();
const tiered = createTieredIpInfoCache({hot: hot.cache, cold: cold.cache});
await tiered.set('a', {available: true});
expect(hot.sets[0]?.ttlSeconds).toBe(600);
expect(cold.sets[0]?.ttlSeconds).toBeUndefined();
});
it('skips the cold write when skipColdWrite matches', async () => {
const hot = createRecordingCache();
const cold = createRecordingCache();
const tiered = createTieredIpInfoCache({
hot: hot.cache,
cold: cold.cache,
skipColdWrite: (value) => (value as {available?: unknown}).available === false,
});
await tiered.set('a', {available: false}, 60);
await tiered.set('b', {available: true}, 60);
expect(hot.sets.map((entry) => entry.key)).toEqual(['a', 'b']);
expect(cold.sets.map((entry) => entry.key)).toEqual(['b']);
});
it('promotes a cold hit into the hot tier', async () => {
const hot = createRecordingCache();
const cold = createRecordingCache();
cold.store.set('a', {available: true});
const tiered = createTieredIpInfoCache({hot: hot.cache, cold: cold.cache});
const hit = await tiered.get('a');
expect(hit).toEqual({available: true});
expect(hot.sets).toEqual([{key: 'a', value: {available: true}, ttlSeconds: 600}]);
});
it('never promotes a cold hit that skipColdWrite matches', async () => {
const hot = createRecordingCache();
const cold = createRecordingCache();
cold.store.set('a', {available: false});
const tiered = createTieredIpInfoCache({
hot: hot.cache,
cold: cold.cache,
skipColdWrite: (value) => (value as {available?: unknown}).available === false,
});
const hit = await tiered.get('a');
expect(hit).toEqual({available: false});
expect(hot.sets).toEqual([]);
});
it('never writes a zero TTL', async () => {
const hot = createRecordingCache();
const cold = createRecordingCache();
const tiered = createTieredIpInfoCache({hot: hot.cache, cold: cold.cache});
await tiered.set('a', {available: false}, 60);
await tiered.set('b', {available: true}, 100000);
await tiered.set('c', {available: true});
cold.store.set('d', {available: true});
await tiered.get('d');
for (const entry of [...hot.sets, ...cold.sets]) {
expect(entry.ttlSeconds === undefined || entry.ttlSeconds > 0).toBe(true);
}
});
});
-3
View File
@@ -164,9 +164,6 @@ export interface APIConfig {
secure: boolean;
};
};
ipinfo: {
apiKey?: string;
};
blocklistFeeds: {
enabled: boolean;
};
@@ -6,7 +6,6 @@ import {fileURLToPath} from 'node:url';
import {DEFAULT_TTL_TABLES} from '@app/api/database/PostgresKvDefaultTtlExpiry';
import * as DonationTables from '@app/api/donation/DonationTables';
import * as Tables from '@app/api/Tables';
import {IPINFO_CACHE_TTL_SECONDS, IPINFO_REQUEST_AUDIT_TTL_SECONDS} from '@pkgs/geoip/src/PostgresIpInfoKv';
import {describe, expect, it} from 'vitest';
const THIS_DIR = path.dirname(fileURLToPath(import.meta.url));
@@ -32,8 +31,6 @@ const DSL_TABLES = [...Object.values(Tables), ...Object.values(DonationTables)];
const DSL_NAMES = new Set<string>(DSL_TABLES.map((table) => table.name));
const NON_DSL_DEFAULTS: Record<string, number | null> = {
ipinfo_cache: IPINFO_CACHE_TTL_SECONDS,
ipinfo_requests_by_hour: IPINFO_REQUEST_AUDIT_TTL_SECONDS,
billing_webhook_events: null,
forensic_identifier_by_key_day: null,
forensic_identifier_by_request: null,
@@ -333,7 +333,7 @@ RETURNING updated_at::text`,
await seed('attachment_upload_traces_by_key', 'at-29', '29 days');
await seed('oauth2_access_tokens', 'oa-8', '8 days');
await seed('donor_magic_link_tokens', 'dm-hour', '1 hour');
await seed('ipinfo_requests_by_hour', 'ip-day', '1 day');
await seed('push_subscriptions', 'ps-day', '1 day');
await seed('jobs_by_id', 'job', '100 days');
await seed('users', 'user', '100 days');
await seed('recent_mentions', 'rm-forever', '1 day', 'infinity');
@@ -346,8 +346,8 @@ RETURNING updated_at::text`,
});
expect(await remaining()).toEqual([
{table_name: 'attachment_upload_traces_by_key', row_key: 'at-29'},
{table_name: 'ipinfo_requests_by_hour', row_key: 'ip-day'},
{table_name: 'jobs_by_id', row_key: 'job'},
{table_name: 'push_subscriptions', row_key: 'ps-day'},
{table_name: 'recent_mentions', row_key: 'rm-day'},
{table_name: 'recent_mentions', row_key: 'rm-forever'},
{table_name: 'recent_mentions', row_key: 'rm-hour'},
@@ -359,13 +359,13 @@ RETURNING updated_at::text`,
expires_at = updated_at + CASE table_name WHEN 'recent_mentions' THEN interval '7 days' WHEN 'attachment_upload_traces_by_key' THEN interval '30 days' ELSE interval '90 days' END AS exact,
CASE WHEN row_key = 'rm-day' THEN updated_at = $1::timestamptz END AS unchanged
FROM ${KV_TABLE}
WHERE row_key IN ('rm-day', 'at-29', 'ip-day')
WHERE row_key IN ('rm-day', 'at-29', 'ps-day')
ORDER BY row_key`,
[mentionWrittenAt],
);
expect(exact.rows).toEqual([
{row_key: 'at-29', exact: true, unchanged: null},
{row_key: 'ip-day', exact: true, unchanged: null},
{row_key: 'ps-day', exact: true, unchanged: null},
{row_key: 'rm-day', exact: true, unchanged: true},
]);
const untouched = await raw.query<{row_key: string; state: string}>(
@@ -449,18 +449,18 @@ FROM generate_series(1, 2300) g`,
});
it('saves where a run stopped and starts the next run there', async () => {
const first = DEFAULT_TTL_TABLES[0]!.name;
const last = DEFAULT_TTL_TABLES.at(-1)!.name;
await seed(first, 'a', '1 hour');
await seed(first, 'z', '1 hour');
await seed(last, 'k', '1 hour');
const first = DEFAULT_TTL_TABLES[0]!;
const last = DEFAULT_TTL_TABLES.at(-1)!;
await seed(first.name, 'a', `${first.defaultTtlSeconds / 2} seconds`);
await seed(first.name, 'z', `${first.defaultTtlSeconds / 2} seconds`);
await seed(last.name, 'k', `${last.defaultTtlSeconds / 2} seconds`);
expect(await expireLegacyDefaultTtlRows(raw, Date.now() - 1)).toEqual({deleted: 0, expiring: 0, complete: false});
expect(await resumePoint()).toEqual({table: first, row_key: '', unset: 0});
expect(await resumePoint()).toEqual({table: first.name, row_key: '', unset: 0});
await raw.query(
`UPDATE ${KV_TABLE} SET row_data = jsonb_build_object('table', $1::text, 'row_key', 'm', 'unset', 0) WHERE table_name = '__fluxer_schema_migrations' AND row_key = $2`,
[first, DEFAULT_TTL_EXPIRY_RESUME],
[first.name, DEFAULT_TTL_EXPIRY_RESUME],
);
expect(await expireLegacyDefaultTtlRows(raw, Date.now() + 60_000)).toEqual({
deleted: 0,
@@ -469,7 +469,7 @@ FROM generate_series(1, 2300) g`,
});
const untouched = await raw.query<{expires_at: Date | null}>(
`SELECT expires_at FROM ${KV_TABLE} WHERE table_name = $1 AND row_key = 'a'`,
[first],
[first.name],
);
expect(untouched.rows).toEqual([{expires_at: null}]);
expect(await resumePoint()).toBeNull();
@@ -7,7 +7,6 @@ import {
} from '@app/api/database/PostgresKvQueryExecutor';
import * as DonationTables from '@app/api/donation/DonationTables';
import * as Tables from '@app/api/Tables';
import {IPINFO_CACHE_TTL_SECONDS, IPINFO_REQUEST_AUDIT_TTL_SECONDS} from '@pkgs/geoip/src/PostgresIpInfoKv';
import {type IPostgresClient, quoteIdentifier} from '@pkgs/postgres/src/Client';
import {ms} from 'itty-time';
@@ -23,8 +22,6 @@ export const DEFAULT_TTL_TABLES: ReadonlyArray<{name: string; defaultTtlSeconds:
? []
: [{name: table.name, defaultTtlSeconds: table.defaultTtlSeconds}],
),
{name: 'ipinfo_cache', defaultTtlSeconds: IPINFO_CACHE_TTL_SECONDS},
{name: 'ipinfo_requests_by_hour', defaultTtlSeconds: IPINFO_REQUEST_AUDIT_TTL_SECONDS},
];
export interface LegacyDefaultTtlExpiryResult {
@@ -3,6 +3,9 @@
import {requireEmailVerified} from '@app/api/auth/EmailVerificationUtils';
import {requireSudoMode} from '@app/api/auth/services/SudoVerificationService';
import {createGuildID} from '@app/api/BrandedTypes';
import {Config} from '@app/api/Config';
import {resolveLimitSafe} from '@app/api/limits/LimitConfigUtils';
import {createLimitMatchContext} from '@app/api/limits/LimitMatchContextBuilder';
import {LoginRequired} from '@app/api/middleware/AuthMiddleware';
import {requireOAuth2ScopeForBearer} from '@app/api/middleware/OAuth2ScopeMiddleware';
import {RateLimitMiddleware} from '@app/api/middleware/RateLimitMiddleware';
@@ -11,6 +14,8 @@ import {SudoModeMiddleware} from '@app/api/middleware/SudoModeMiddleware';
import {RateLimitConfigs} from '@app/api/RateLimitConfig';
import type {HonoApp} from '@app/api/types/HonoEnv';
import {Validator} from '@app/api/Validator';
import {AdminACLs} from '@fluxer/constants/src/AdminACLs';
import {GuildCreationPermissionRequiredError} from '@fluxer/errors/src/domains/guild/GuildCreationPermissionRequiredError';
import {SingleCommunityCannotCreateGuildsError} from '@fluxer/errors/src/domains/guild/SingleCommunityCannotCreateGuildsError';
import {SingleCommunityCannotDeleteError} from '@fluxer/errors/src/domains/guild/SingleCommunityCannotDeleteError';
import {SingleCommunityCannotLeaveError} from '@fluxer/errors/src/domains/guild/SingleCommunityCannotLeaveError';
@@ -40,7 +45,8 @@ export function GuildBaseController(app: HonoApp) {
OpenAPI({
operationId: 'create_guild',
summary: 'Create guild',
description: 'Only claimed, email-verified non-bot users can create guilds.',
description:
'Only claimed, email-verified non-bot users can create guilds. A self-hosted instance can restrict creation to admins and users granted the feature_guild_create limit.',
responseSchema: GuildResponse,
statusCode: 200,
security: ['bearerToken', 'sessionToken'],
@@ -56,6 +62,19 @@ export function GuildBaseController(app: HonoApp) {
if (!user.isUnclaimedAccount()) {
requireEmailVerified(user, 'guild_creation');
}
if (Config.instance.selfHosted && !policy.guild_create_access) {
const granted =
user.acls.has(AdminACLs.WILDCARD) ||
resolveLimitSafe(
ctx.get('limitConfigService').getConfigSnapshot(),
createLimitMatchContext({user}),
'feature_guild_create',
0,
) > 0;
if (!granted) {
throw new GuildCreationPermissionRequiredError();
}
}
const auditLogReason = ctx.get('auditLogReason') ?? null;
const locale = ctx.get('requestLocale') ?? null;
return ctx.json(await ctx.get('guildService').data.createGuild({user, data, locale}, auditLogReason));
@@ -24,7 +24,6 @@ import type {JoinSourceType} from '@fluxer/constants/src/GuildConstants';
import {UnknownGuildMemberError} from '@fluxer/errors/src/domains/guild/UnknownGuildMemberError';
import type {GuildMemberResponse} from '@fluxer/schema/src/domains/guild/GuildMemberSchemas';
import type {GuildMemberUpdateRequest} from '@fluxer/schema/src/domains/guild/GuildRequestSchemas';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
import type {IRateLimitService} from '@pkgs/rate_limit/src/IRateLimitService';
export class GuildMemberService {
@@ -47,11 +46,10 @@ export class GuildMemberService {
rateLimitService: IRateLimitService,
private readonly guildAuditLogService: GuildAuditLogService,
limitConfigService: LimitConfigService,
ipInfoService: IpInfoService,
) {
this.userRepository = userRepository;
this.authService = new GuildMemberAuthService(gatewayService, userRepository);
this.validationService = new GuildMemberValidationService(guildRepository, userRepository, ipInfoService);
this.validationService = new GuildMemberValidationService(guildRepository, userRepository);
this.auditService = new GuildMemberAuditService(guildAuditLogService);
this.eventService = new GuildMemberEventService(gatewayService, userCacheService);
this.searchIndexService = new GuildMemberSearchIndexService();
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {GuildID, UserID} from '@app/api/BrandedTypes';
import {getIpBanBlastRadiusVerdict, isSingleIpBanCandidate} from '@app/api/ban/IpBanCgnatGuard';
import {isIpBanExempt} from '@app/api/ban/IpBanExemptions';
import type {GuildAuditLogService} from '@app/api/guild/GuildAuditLogService';
import type {GuildAuditLogChange} from '@app/api/guild/GuildAuditLogTypes';
@@ -27,7 +26,6 @@ import {UnknownGuildMemberError} from '@fluxer/errors/src/domains/guild/UnknownG
import {UnknownUserError} from '@fluxer/errors/src/domains/user/UnknownUserError';
import {isSameIpDecisionMatch} from '@fluxer/ip_utils/src/IpAddress';
import type {GuildBanResponse} from '@fluxer/schema/src/domains/guild/GuildMemberSchemas';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
import type {IWorkerService} from '@pkgs/worker/src/contracts/IWorkerService';
const SECONDS_PER_DAY = 86_400;
@@ -42,7 +40,6 @@ export class GuildModerationService {
private readonly userCacheService: UserCacheService,
private readonly workerService: IWorkerService<WorkerTaskName>,
private readonly guildAuditLogService: GuildAuditLogService,
private readonly ipInfoService: IpInfoService,
) {
this.searchIndexService = new GuildMemberSearchIndexService();
}
@@ -218,7 +215,7 @@ export class GuildModerationService {
const userEmail = user?.email?.toLowerCase();
for (const ban of bans) {
if (ban.userId === userId) throw new BannedFromGuildError();
if (isSameIpDecisionMatch(userIp, ban.ipAddress) && (await this.shouldEnforceIpBan(userIp, ban.ipAddress))) {
if (isSameIpDecisionMatch(userIp, ban.ipAddress) && !isIpBanExempt(userIp)) {
throw new IpBannedFromGuildError();
}
}
@@ -228,35 +225,6 @@ export class GuildModerationService {
}
}
private async shouldEnforceIpBan(
userIp: string | null | undefined,
bannedIp: string | null | undefined,
): Promise<boolean> {
if (isIpBanExempt(userIp)) {
return false;
}
if (!userIp || !bannedIp || !isSingleIpBanCandidate(bannedIp)) {
return true;
}
try {
const {cgnat, sharedAccess} = await getIpBanBlastRadiusVerdict(userIp, this.ipInfoService, {
source: 'guild.ip_ban',
reason: 'join_cgnat_guard',
});
const highRisk = cgnat || sharedAccess;
if (highRisk) {
Logger.warn(
{userIp, bannedIp},
'Skipping guild IP ban match because IPInfo indicates high shared-network blast-radius risk',
);
}
return !highRisk;
} catch (error) {
Logger.warn({error, userIp, bannedIp}, 'IPInfo blast-radius guard failed while checking guild IP ban');
return true;
}
}
private serializeBanForAudit(ban: GuildBan): Record<string, unknown> {
return {
user_id: ban.userId.toString(),
@@ -58,7 +58,6 @@ import type {
import type {GuildUpdateRequest} from '@fluxer/schema/src/domains/guild/GuildRequestSchemas';
import type {GuildResponse} from '@fluxer/schema/src/domains/guild/GuildResponseSchemas';
import type {ICacheService} from '@pkgs/cache/src/ICacheService';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
interface StoredAuditLogWebhookResponse extends Omit<AuditLogWebhookResponse, 'type'> {
type: number;
@@ -113,7 +112,6 @@ export class GuildService {
webhookRepository: IWebhookRepository,
guildAuditLogService: GuildAuditLogService,
limitConfigService: LimitConfigService,
ipInfoService: IpInfoService,
) {
const {
cache: cacheService,
@@ -153,7 +151,6 @@ export class GuildService {
rateLimitService,
guildAuditLogService,
limitConfigService,
ipInfoService,
);
this.roles = new GuildRoleService(
guildRepository,
@@ -171,7 +168,6 @@ export class GuildService {
userCacheService,
workerService,
guildAuditLogService,
ipInfoService,
);
this.content = new GuildContentService(
guildRepository,
@@ -2,10 +2,8 @@
import type {GuildID, RoleID, UserID} from '@app/api/BrandedTypes';
import {guildIdToRoleId} from '@app/api/BrandedTypes';
import {getIpBanBlastRadiusVerdict, isSingleIpBanCandidate} from '@app/api/ban/IpBanCgnatGuard';
import {isIpBanExempt} from '@app/api/ban/IpBanExemptions';
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
import {Logger} from '@app/api/Logger';
import type {GuildMember} from '@app/api/models/GuildMember';
import type {IUserRepository} from '@app/api/user/IUserRepository';
import {Permissions} from '@fluxer/constants/src/ChannelConstants';
@@ -17,7 +15,6 @@ import {IpBannedFromGuildError} from '@fluxer/errors/src/domains/guild/IpBannedF
import {UnknownGuildRoleError} from '@fluxer/errors/src/domains/guild/UnknownGuildRoleError';
import {isSameIpDecisionMatch} from '@fluxer/ip_utils/src/IpAddress';
import type {GuildResponse} from '@fluxer/schema/src/domains/guild/GuildResponseSchemas';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
function ensureNotEveryoneRole(roleId: RoleID, guildId: GuildID, path: string): void {
if (roleId === guildIdToRoleId(guildId)) {
@@ -29,7 +26,6 @@ export class GuildMemberValidationService {
constructor(
private readonly guildRepository: IGuildRepositoryAggregate,
private readonly userRepository: IUserRepository,
private readonly ipInfoService: IpInfoService,
) {}
async validateAndGetRoleIds(params: {
@@ -102,38 +98,9 @@ export class GuildMemberValidationService {
if (ban.userId === userId) {
throw new BannedFromGuildError();
}
if (isSameIpDecisionMatch(userIp, ban.ipAddress) && (await this.shouldEnforceIpBan(userIp, ban.ipAddress))) {
if (isSameIpDecisionMatch(userIp, ban.ipAddress) && !isIpBanExempt(userIp)) {
throw new IpBannedFromGuildError();
}
}
}
private async shouldEnforceIpBan(
userIp: string | null | undefined,
bannedIp: string | null | undefined,
): Promise<boolean> {
if (isIpBanExempt(userIp)) {
return false;
}
if (!userIp || !bannedIp || !isSingleIpBanCandidate(bannedIp)) {
return true;
}
try {
const {cgnat, sharedAccess} = await getIpBanBlastRadiusVerdict(userIp, this.ipInfoService, {
source: 'guild.member_ip_ban',
reason: 'join_cgnat_guard',
});
const highRisk = cgnat || sharedAccess;
if (highRisk) {
Logger.warn(
{userIp, bannedIp},
'Skipping guild member IP ban match because IPInfo indicates high shared-network blast-radius risk',
);
}
return !highRisk;
} catch (error) {
Logger.warn({error, userIp, bannedIp}, 'IPInfo CGNAT guard failed while checking guild member IP ban');
return true;
}
}
}
@@ -2,6 +2,7 @@
export const GatewayRpcMethodErrorCodes = {
OVERLOADED: 'overloaded',
GUILD_OVERLOADED: 'guild_overloaded',
INTERNAL_ERROR: 'internal_error',
TIMEOUT: 'timeout',
NO_RESPONDERS: 'no_responders',
@@ -296,6 +296,9 @@ export class GatewayService {
if (error.code === GatewayRpcMethodErrorCodes.TIMEOUT) {
return new GatewayTimeoutError();
}
if (error.code === GatewayRpcMethodErrorCodes.GUILD_OVERLOADED) {
return new ServiceUnavailableError({headers: {'Retry-After': '1'}});
}
if (error.code === GatewayRpcMethodErrorCodes.OVERLOADED) {
return new ServiceUnavailableError();
}
@@ -8,6 +8,7 @@ import type {IGatewayRpcTransport} from '@app/api/infrastructure/IGatewayRpcTran
import {APIErrorCodes} from '@fluxer/constants/src/ApiErrorCodes';
import {BadGatewayError} from '@fluxer/errors/src/domains/core/BadGatewayError';
import {BadRequestError} from '@fluxer/errors/src/domains/core/BadRequestError';
import {ServiceUnavailableError} from '@fluxer/errors/src/domains/core/ServiceUnavailableError';
import {UnknownGuildError} from '@fluxer/errors/src/domains/guild/UnknownGuildError';
import {afterEach, describe, expect, it} from 'vitest';
@@ -70,4 +71,30 @@ describe('GatewayService gateway error mapping', () => {
expect((error as BadRequestError).status).toBe(400);
expect((error as BadRequestError).code).toBe(APIErrorCodes.INVALID_FORM_BODY);
});
it('returns 503 with Retry-After for an overloaded guild', async () => {
const service = serviceRaising(GatewayRpcMethodErrorCodes.GUILD_OVERLOADED);
const error = await service
.getUserPermissions({guildId: createGuildID(1n), userId: createUserID(2n)})
.catch((raised: unknown) => raised);
expect(error).toBeInstanceOf(ServiceUnavailableError);
const response = (error as ServiceUnavailableError).getResponse();
expect(response.status).toBe(503);
expect(response.headers.get('Retry-After')).toBe('1');
});
it('does not retry a guild overload response', async () => {
let calls = 0;
const client = GatewayRpcClient.createForTests({
async call(): Promise<unknown> {
calls += 1;
throw new GatewayRpcMethodError(GatewayRpcMethodErrorCodes.GUILD_OVERLOADED);
},
async destroy(): Promise<void> {},
});
await expect(client.call('guild.dispatch', {guild_id: '1'})).rejects.toMatchObject({
code: GatewayRpcMethodErrorCodes.GUILD_OVERLOADED,
});
expect(calls).toBe(1);
});
});
@@ -173,6 +173,7 @@ export interface InstancePolicyConfig {
direct_messages_disabled: boolean;
direct_messages_locked: boolean;
premium_mode: InstancePremiumMode;
guild_create_access: boolean;
gif_enabled: boolean | null;
youtube_enabled: boolean | null;
bluesky_enabled: boolean | null;
@@ -647,6 +648,7 @@ const StoredInstancePolicySchema = z.object({
direct_messages_disabled: InstancePolicyUpdateSchema.shape.direct_messages_disabled.default(false),
direct_messages_locked: z.boolean().default(false),
premium_mode: InstancePolicyUpdateSchema.shape.premium_mode.default('everyone'),
guild_create_access: InstancePolicyUpdateSchema.shape.guild_create_access.default(true),
gif_enabled: InstancePolicyServiceUpdateSchema.shape.gif_enabled.default(null),
youtube_enabled: InstancePolicyServiceUpdateSchema.shape.youtube_enabled.default(null),
bluesky_enabled: InstancePolicyServiceUpdateSchema.shape.bluesky_enabled.default(null),
@@ -1773,6 +1775,7 @@ export class InstanceConfigRepository {
single_community: policy.single_community_enabled,
single_community_guild_id: policy.single_community_enabled ? policy.single_community_guild_id : null,
direct_messages_disabled: policy.direct_messages_disabled,
guild_create_access: policy.guild_create_access,
};
}
@@ -24,7 +24,6 @@ import type {ReadStateService} from '@app/api/read_state/ReadStateService';
import type {IUserRepository} from '@app/api/user/IUserRepository';
import type {VoiceAvailabilityService} from '@app/api/voice/VoiceAvailabilityService';
import type {IWebhookRepository} from '@app/api/webhook/IWebhookRepository';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
import type {IVirusScanService} from '@pkgs/virus_scan/src/IVirusScanService';
interface GuildStackServiceFactoryDependencies {
@@ -50,7 +49,6 @@ interface GuildStackServiceFactoryDependencies {
voiceRoomStore: IVoiceRoomStore;
liveKitService: ILiveKitService;
voiceAvailabilityService: VoiceAvailabilityService | null;
ipInfoService: IpInfoService;
}
export interface GuildStackServices {
@@ -106,7 +104,6 @@ class LazyGuildStackServices implements GuildStackServices {
this.dependencies.webhookRepository,
this.dependencies.guildAuditLogService,
this.dependencies.limitConfigService,
this.dependencies.ipInfoService,
);
return this.cachedGuildService;
}
@@ -6,7 +6,6 @@ import {AdminService} from '@app/api/admin/AdminService';
import {AuthRequestService} from '@app/api/auth/AuthRequestService';
import {DesktopHandoffService} from '@app/api/auth/services/DesktopHandoffService';
import {SsoService} from '@app/api/auth/services/SsoService';
import {buildIpInfoCache, buildIpInfoRequestAuditLogger} from '@app/api/ban/IpInfoCacheFactory';
import type {IBlueskyOAuthService} from '@app/api/bluesky/IBlueskyOAuthService';
import {Config} from '@app/api/Config';
import {createApiContext} from '@app/api/CreateApiContext';
@@ -138,7 +137,6 @@ import {getRequestClientIp} from '@app/api/utils/RequestClientIp';
import {VoiceService} from '@app/api/voice/VoiceService';
import {WebhookRequestService} from '@app/api/webhook/WebhookRequestService';
import {WebhookService} from '@app/api/webhook/WebhookService';
import {createIpInfoService, createUnavailableIpInfoService, type IpInfoService} from '@pkgs/geoip/src/IpInfoService';
import {createMiddleware} from 'hono/factory';
export {initializeServiceSingletons} from '@app/api/middleware/ServiceSingletons';
@@ -172,33 +170,6 @@ export function shutdownReportService(): void {
}
}
let _ipInfoService: IpInfoService | null = null;
let _injectedIpInfoService: IpInfoService | undefined;
export function setInjectedIpInfoService(service: IpInfoService | undefined): void {
_injectedIpInfoService = service;
}
export function getIpInfoService(): IpInfoService {
if (_injectedIpInfoService) {
return _injectedIpInfoService;
}
if (_ipInfoService) return _ipInfoService;
if (!Config.ipinfo.apiKey) {
_ipInfoService = createUnavailableIpInfoService('IPInfo API key not configured');
return _ipInfoService;
}
const cache = buildIpInfoCache({
hot: getCacheService(),
});
_ipInfoService = createIpInfoService({
apiKey: Config.ipinfo.apiKey,
cache,
auditLogger: buildIpInfoRequestAuditLogger(),
});
return _ipInfoService;
}
let _liveKitWebhookService: LiveKitWebhookService | null = null;
function getLiveKitWebhookService(): LiveKitWebhookService | null {
@@ -349,7 +320,6 @@ class RequestServices implements RequestScopedServices {
voiceRoomStore: this.voiceRooms,
liveKitService: this.liveKit,
voiceAvailabilityService: getVoiceAvailabilityService(),
ipInfoService: getIpInfoService(),
});
return this.cachedGuildStack;
}
@@ -544,7 +514,6 @@ class RequestServices implements RequestScopedServices {
getApplicationRepository(),
this.stripeService.getStripe(),
new JobLedgerRepository(),
getIpInfoService(),
this.storeEntitlementService,
);
return this.cachedAdminService;
@@ -931,6 +900,5 @@ export const ServiceMiddleware = createMiddleware<HonoEnv>(async (ctx, next) =>
export function resetServiceMiddlewareForTesting(): void {
shutdownReportService();
_ipInfoService = null;
_liveKitWebhookService = null;
}
+12 -3
View File
@@ -6236,7 +6236,7 @@
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
}
},
"description": "Only claimed, email-verified non-bot users can create guilds.",
"description": "Only claimed, email-verified non-bot users can create guilds. A self-hosted instance can restrict creation to admins and users granted the feature_guild_create limit.",
"security": [{"sessionToken": []}],
"requestBody": {
"required": true,
@@ -22729,7 +22729,7 @@
"description": "The sequence number for lifetime premium subscribers"
},
"premium_grace_ends_at": {
"description": "ISO8601 timestamp at which the post-cancel grace period ends. Set when the subscription is fully canceled in Stripe; perks remain active and the original premium_since is restored on resubscribe until this timestamp passes. Null when not in grace.",
"description": "ISO8601 timestamp at which grace access ends after premium_until passes: after a failed renewal payment (7 days from the renewal for monthly plans, 14 for yearly), after a subscription ends (3 days), or during an App Store or Google Play grace period. Perks stay active and the original premium_since is kept on resubscribe until this timestamp passes. Null when no grace is recorded, in which case access lasts 3 days after premium_until.",
"type": ["string", "null"]
},
"premium_discriminator": {
@@ -30259,9 +30259,18 @@
"direct_messages_disabled": {
"type": "boolean",
"description": "Whether direct messages and friend requests are disabled instance-wide"
},
"guild_create_access": {
"type": "boolean",
"description": "Whether every account can create communities. When false, only admins and accounts granted the feature_guild_create limit can"
}
},
"required": ["single_community", "single_community_guild_id", "direct_messages_disabled"],
"required": [
"single_community",
"single_community_guild_id",
"direct_messages_disabled",
"guild_create_access"
],
"additionalProperties": false,
"description": "Community topology and direct-message policy for this instance"
},
@@ -30,7 +30,7 @@ import type {StripePremiumService} from '@app/api/stripe/services/StripePremiumS
import type {StripeSubscriptionReconciler} from '@app/api/stripe/services/StripeSubscriptionReconciler';
import type {IUserRepository} from '@app/api/user/IUserRepository';
import {PaymentRepository} from '@app/api/user/repositories/PaymentRepository';
import {PREMIUM_GRACE_PERIOD_MS} from '@app/api/user/UserHelpers';
import {getPremiumPaymentRecoveryGraceMs} from '@app/api/user/UserHelpers';
import {mapUserToPrivateResponse} from '@app/api/user/UserMappers';
import {UserPremiumTypes} from '@fluxer/constants/src/UserConstants';
import {StripeError} from '@fluxer/errors/src/domains/payment/StripeError';
@@ -369,7 +369,7 @@ export class StripeSubscriptionWebhookHandler {
);
return;
}
const updatedUser = await this.markSubscriptionAsGraceDisabled(targetUser, {
const updatedUser = await this.markSubscriptionPaymentIssue(targetUser, {
subscriptionId,
customerId: this.reconciler.getCustomerIdFromInvoice(invoice),
failedInvoiceServicePeriod: this.getInvoiceServicePeriod(invoice),
@@ -507,10 +507,10 @@ export class StripeSubscriptionWebhookHandler {
}
const willCancel = getPremiumWillCancelFromSubscription(canonicalSubscription);
if (!canProvisionPremiumFromSubscriptionStatus(canonicalSubscription.status)) {
const updatedUser = await this.markSubscriptionAsGraceDisabled(targetUser, {
const updatedUser = await this.markSubscriptionPaymentIssue(targetUser, {
subscriptionId: canonicalSubscription.id,
customerId: extractId(canonicalSubscription.customer),
failedInvoiceServicePeriod: null,
failedInvoiceServicePeriod: this.getUnpaidRenewalPeriod(targetUser, canonicalSubscription),
});
await this.enqueuePremiumStateReconciliation(updatedUser.id, {
reason: 'subscription_updated_non_provisionable',
@@ -523,7 +523,7 @@ export class StripeSubscriptionWebhookHandler {
status: canonicalSubscription.status,
willCancel,
},
'Subscription updated in non-provisionable state; preserved local expiry and disabled grace period',
'Subscription updated in non-provisionable state; preserved local expiry',
);
return;
}
@@ -663,11 +663,22 @@ export class StripeSubscriptionWebhookHandler {
if (!alreadyAppliedEarlyCancellation) {
const cancelledBeforePeriodEnd =
targetUser.premiumUntil != null && subscriptionEndedAt.getTime() < targetUser.premiumUntil.getTime();
if (cancelledBeforePeriodEnd) {
updates.premium_until = subscriptionEndedAt;
updates.premium_grace_ends_at = subscriptionEndedAt;
if (subscription.cancellation_details?.reason === 'payment_failed') {
const lapseStart =
targetUser.premiumUntil && targetUser.premiumUntil.getTime() < subscriptionEndedAt.getTime()
? targetUser.premiumUntil
: subscriptionEndedAt;
const billingCycle =
targetUser.premiumBillingCycle ?? this.reconciler.getBillingCycleFromSubscription(subscription);
updates.premium_until = lapseStart;
updates.premium_grace_ends_at = new Date(
lapseStart.getTime() + getPremiumPaymentRecoveryGraceMs(billingCycle),
);
} else {
updates.premium_grace_ends_at = new Date(subscriptionEndedAt.getTime() + PREMIUM_GRACE_PERIOD_MS);
if (cancelledBeforePeriodEnd) {
updates.premium_until = subscriptionEndedAt;
}
updates.premium_grace_ends_at = subscriptionEndedAt;
}
}
}
@@ -740,7 +751,7 @@ export class StripeSubscriptionWebhookHandler {
);
}
private async markSubscriptionAsGraceDisabled(
private async markSubscriptionPaymentIssue(
user: User,
context: {
subscriptionId: string | null;
@@ -770,6 +781,17 @@ export class StripeSubscriptionWebhookHandler {
) {
patch.premium_until = context.failedInvoiceServicePeriod.start;
}
const lapseStart = patch.premium_until ?? user.premiumUntil;
if (
user.premiumType === UserPremiumTypes.SUBSCRIPTION &&
context.failedInvoiceServicePeriod &&
lapseStart?.getTime() === context.failedInvoiceServicePeriod.start.getTime()
) {
const graceEndsAt = new Date(lapseStart.getTime() + getPremiumPaymentRecoveryGraceMs(user.premiumBillingCycle));
if (user.premiumGraceEndsAt?.getTime() !== graceEndsAt.getTime()) {
patch.premium_grace_ends_at = graceEndsAt;
}
}
if (Object.keys(patch).length === 0) {
return user;
}
@@ -778,6 +800,27 @@ export class StripeSubscriptionWebhookHandler {
return (await this.restoreStoreEntitlement(updatedUser.id)) ?? updatedUser;
}
private getUnpaidRenewalPeriod(
user: User,
subscription: Stripe.Subscription,
): {
start: Date;
end: Date;
} | null {
if (subscription.status !== 'past_due' && subscription.status !== 'unpaid') {
return null;
}
const item = getPrimarySubscriptionItem(subscription);
if (!item?.current_period_start || !item.current_period_end || !user.premiumUntil) {
return null;
}
const start = new Date(item.current_period_start * 1000);
if (user.premiumUntil.getTime() !== start.getTime()) {
return null;
}
return {start, end: new Date(item.current_period_end * 1000)};
}
private getInvoiceServicePeriod(invoice: Stripe.Invoice): {
start: Date;
end: Date;
@@ -43,6 +43,7 @@ const MOCK_PRICES = {
gift1YearEur: 'price_gift_1_year_eur',
};
const DAY_MS = 24 * 60 * 60 * 1000;
const LEGACY_MONTHLY_BRL_PRICE = 'price_legacy_monthly_brl';
const LEGACY_YEARLY_BRL_PRICE = 'price_legacy_yearly_brl';
const UNMAPPED_PRICE = 'price_retired_unmapped_brl';
@@ -147,6 +148,7 @@ describe('Stripe Webhook - Invoice Events', () => {
customerId: string;
premiumUntil: Date;
premiumWillCancel?: boolean;
billingCycle?: 'monthly' | 'yearly';
}): Promise<void> {
const {UserRepository} = await import('@app/api/user/repositories/UserRepository');
const userRepository = new UserRepository();
@@ -157,12 +159,44 @@ describe('Stripe Webhook - Invoice Events', () => {
premium_type: UserPremiumTypes.SUBSCRIPTION,
premium_until: params.premiumUntil,
premium_will_cancel: params.premiumWillCancel ?? false,
...(params.billingCycle ? {premium_billing_cycle: params.billingCycle} : {}),
stripe_subscription_id: params.subscriptionId,
stripe_customer_id: params.customerId,
},
(await userRepository.findUnique(userId))!.toRow(),
);
}
function createRenewalFailureEvent(params: {
invoiceId: string;
customerId: string;
subscriptionId: string;
periodStart: Date;
periodEnd: Date;
}): StripeWebhookEventData {
const eventData = createInvoicePaymentFailedEvent({
invoiceId: params.invoiceId,
customerId: params.customerId,
subscriptionId: params.subscriptionId,
amountDue: 2500,
});
eventData.data.object.billing_reason = 'subscription_cycle';
eventData.data.object.lines = {
data: [
{
period: {
start: Math.floor(params.periodStart.getTime() / 1000),
end: Math.floor(params.periodEnd.getTime() / 1000),
},
parent: {
subscription_item_details: {
subscription: params.subscriptionId,
},
},
},
],
};
return eventData;
}
describe('invoice.payment_succeeded', () => {
test('processes recurring subscription payment successfully', async () => {
const account = await createTestAccount(harness);
@@ -559,6 +593,7 @@ describe('Stripe Webhook - Invoice Events', () => {
premium_type: UserPremiumTypes.SUBSCRIPTION,
premium_until: existingPremiumUntil,
premium_will_cancel: false,
premium_billing_cycle: 'monthly',
stripe_subscription_id: subscriptionId,
stripe_customer_id: 'cus_test_failed_invoice',
},
@@ -592,12 +627,96 @@ describe('Stripe Webhook - Invoice Events', () => {
premium_type: number | null;
premium_until: string | null;
premium_will_cancel: boolean;
premium_grace_ends_at: string | null;
}>(harness, account.token)
.get('/users/@me')
.execute();
const failedPeriodStartMs = Math.floor(failedPeriodStart.getTime() / 1000) * 1000;
expect(me.premium_type).toBe(UserPremiumTypes.SUBSCRIPTION);
expect(me.premium_until).toBe(new Date(failedPeriodStartMs).toISOString());
expect(me.premium_will_cancel).toBe(true);
expect(me.premium_grace_ends_at).toBe(new Date(failedPeriodStartMs + 7 * DAY_MS).toISOString());
});
test('records a 14-day recovery deadline for a yearly subscription', async () => {
const account = await createTestAccount(harness);
const subscriptionId = `sub_failed_yearly_${Date.now()}`;
const failedPeriodStart = new Date(Math.floor((Date.now() - 60 * 60 * 1000) / 1000) * 1000);
const failedPeriodEnd = new Date(failedPeriodStart.getTime() + 365 * DAY_MS);
await createPaymentRecord({
userId: account.userId,
subscriptionId,
priceId: MOCK_PRICES.yearlyUsd,
productType: ProductType.YEARLY_SUBSCRIPTION,
});
await setSubscriptionUserState({
accountUserId: account.userId,
subscriptionId,
customerId: 'cus_test_failed_yearly',
premiumUntil: failedPeriodStart,
billingCycle: 'yearly',
});
const result = await sendWebhook(
createRenewalFailureEvent({
invoiceId: `in_failed_yearly_${Date.now()}`,
customerId: 'cus_test_failed_yearly',
subscriptionId,
periodStart: failedPeriodStart,
periodEnd: failedPeriodEnd,
}),
);
expect(result.received).toBe(true);
const me = await createBuilder<{
premium_type: number | null;
premium_until: string | null;
premium_grace_ends_at: string | null;
}>(harness, account.token)
.get('/users/@me')
.execute();
expect(me.premium_type).toBe(UserPremiumTypes.SUBSCRIPTION);
expect(me.premium_until).toBe(new Date(Math.floor(failedPeriodStart.getTime() / 1000) * 1000).toISOString());
expect(me.premium_will_cancel).toBe(true);
expect(me.premium_until).toBe(failedPeriodStart.toISOString());
expect(me.premium_grace_ends_at).toBe(new Date(failedPeriodStart.getTime() + 14 * DAY_MS).toISOString());
});
test('does not move the recovery deadline on a repeated failure for the same period', async () => {
const account = await createTestAccount(harness);
const subscriptionId = `sub_failed_repeat_${Date.now()}`;
const failedPeriodStart = new Date(Math.floor((Date.now() - 2 * DAY_MS) / 1000) * 1000);
const failedPeriodEnd = new Date(failedPeriodStart.getTime() + 30 * DAY_MS);
await createPaymentRecord({
userId: account.userId,
subscriptionId,
priceId: MOCK_PRICES.monthlyUsd,
productType: ProductType.MONTHLY_SUBSCRIPTION,
});
await setSubscriptionUserState({
accountUserId: account.userId,
subscriptionId,
customerId: 'cus_test_failed_repeat',
premiumUntil: failedPeriodStart,
billingCycle: 'monthly',
});
const invoiceId = `in_failed_repeat_${Date.now()}`;
const expectedDeadline = new Date(failedPeriodStart.getTime() + 7 * DAY_MS).toISOString();
for (const attempt of [1, 2]) {
const eventData = createRenewalFailureEvent({
invoiceId,
customerId: 'cus_test_failed_repeat',
subscriptionId,
periodStart: failedPeriodStart,
periodEnd: failedPeriodEnd,
});
eventData.id = `evt_failed_repeat_${attempt}_${Date.now()}`;
eventData.data.object.attempt_count = attempt;
const result = await sendWebhook(eventData);
expect(result.received).toBe(true);
const me = await createBuilder<{
premium_until: string | null;
premium_grace_ends_at: string | null;
}>(harness, account.token)
.get('/users/@me')
.execute();
expect(me.premium_until).toBe(failedPeriodStart.toISOString());
expect(me.premium_grace_ends_at).toBe(expectedDeadline);
}
});
test('ignores non-renewal invoice payment failures', async () => {
const account = await createTestAccount(harness);
@@ -688,11 +807,14 @@ describe('Stripe Webhook - Invoice Events', () => {
const me = await createBuilder<{
premium_until: string | null;
premium_will_cancel: boolean;
premium_grace_ends_at: string | null;
}>(harness, account.token)
.get('/users/@me')
.execute();
expect(me.premium_until).toBe(new Date(Math.floor(failedPeriodStart.getTime() / 1000) * 1000).toISOString());
const failedPeriodStartMs = Math.floor(failedPeriodStart.getTime() / 1000) * 1000;
expect(me.premium_until).toBe(new Date(failedPeriodStartMs).toISOString());
expect(me.premium_will_cancel).toBe(true);
expect(me.premium_grace_ends_at).toBe(new Date(failedPeriodStartMs + 7 * DAY_MS).toISOString());
});
test('handles invoice.finalization_failed like a recurring access issue', async () => {
const account = await createTestAccount(harness);
@@ -19,6 +19,7 @@ import {server} from '@app/api/test/msw/server';
import {createBuilder} from '@app/api/test/TestRequestBuilder';
import {PaymentRepository} from '@app/api/user/repositories/PaymentRepository';
import {UserRepository} from '@app/api/user/repositories/UserRepository';
import {getPremiumPaymentRecoveryGraceMs, PREMIUM_GRACE_PERIOD_MS} from '@app/api/user/UserHelpers';
import {APIErrorCodes} from '@fluxer/constants/src/ApiErrorCodes';
import {UserPremiumTypes} from '@fluxer/constants/src/UserConstants';
import {HttpResponse, http} from 'msw';
@@ -26,6 +27,7 @@ import {afterAll, afterEach, beforeAll, beforeEach, describe, expect, test} from
const MOCK_PRICES = {
monthlyUsd: 'price_monthly_usd',
yearlyUsd: 'price_yearly_usd',
};
describe('Stripe Webhook Subscription Lifecycle', () => {
@@ -259,6 +261,80 @@ describe('Stripe Webhook Subscription Lifecycle', () => {
expect(updatedUser?.stripeSubscriptionId).toBe(subscriptionId);
expect(updatedUser?.stripeCustomerId).toBe('cus_test_past_due');
});
async function seedPastDueUser(subscriptionId: string, premiumUntil: Date) {
const account = await createTestAccount(harness);
const userId = createUserID(BigInt(account.userId));
const sessionId = `cs_${subscriptionId}_${Date.now()}`;
await paymentRepository.createPayment({
checkout_session_id: sessionId,
user_id: userId,
price_id: MOCK_PRICES.monthlyUsd,
product_type: ProductType.MONTHLY_SUBSCRIPTION,
status: 'completed',
is_gift: false,
created_at: new Date(),
});
await paymentRepository.updatePayment({
checkout_session_id: sessionId,
subscription_id: subscriptionId,
stripe_customer_id: 'cus_test_past_due',
status: 'completed',
});
await userRepository.patchUpsert(
userId,
{
premium_type: UserPremiumTypes.SUBSCRIPTION,
premium_until: premiumUntil,
premium_will_cancel: false,
premium_billing_cycle: 'monthly',
stripe_subscription_id: subscriptionId,
stripe_customer_id: 'cus_test_past_due',
premium_since: new Date(),
},
(await userRepository.findUnique(userId))!.toRow(),
);
return userId;
}
function pastDueEvent(subscriptionId: string, periodStartSeconds: number, periodEndSeconds: number) {
const eventData = createSubscriptionUpdatedEvent({
subscriptionId,
customerId: 'cus_test_past_due',
status: 'past_due',
cancelAtPeriodEnd: false,
});
eventData.data.object.cancel_at = null;
eventData.data.object.items = {
data: [{current_period_start: periodStartSeconds, current_period_end: periodEndSeconds}],
};
return eventData;
}
test('records the payment recovery deadline when past_due arrives before the failed invoice', async () => {
const subscriptionId = 'sub_test_past_due_first';
const renewalSeconds = Math.floor(Date.now() / 1000) - 60 * 60;
const renewalAt = new Date(renewalSeconds * 1000);
const userId = await seedPastDueUser(subscriptionId, renewalAt);
const result = await sendWebhook(
pastDueEvent(subscriptionId, renewalSeconds, renewalSeconds + 30 * 24 * 60 * 60),
);
expect(result.received).toBe(true);
const updatedUser = await userRepository.findUnique(userId);
expect(updatedUser?.premiumUntil?.getTime()).toBe(renewalAt.getTime());
expect(updatedUser?.premiumGraceEndsAt?.getTime()).toBe(
renewalAt.getTime() + getPremiumPaymentRecoveryGraceMs('monthly'),
);
});
test('does not move premium back to the period start for a mid-period past_due', async () => {
const subscriptionId = 'sub_test_past_due_mid_period';
const periodStartSeconds = Math.floor(Date.now() / 1000) - 20 * 24 * 60 * 60;
const periodEndSeconds = periodStartSeconds + 30 * 24 * 60 * 60;
const paidThrough = new Date(periodEndSeconds * 1000);
const userId = await seedPastDueUser(subscriptionId, paidThrough);
const result = await sendWebhook(pastDueEvent(subscriptionId, periodStartSeconds, periodEndSeconds));
expect(result.received).toBe(true);
const updatedUser = await userRepository.findUnique(userId);
expect(updatedUser?.premiumUntil?.getTime()).toBe(paidThrough.getTime());
expect(updatedUser?.premiumGraceEndsAt).toBeNull();
});
test('does not clear premium when period end is missing', async () => {
const account = await createTestAccount(harness);
const userId = createUserID(BigInt(account.userId));
@@ -501,7 +577,7 @@ describe('Stripe Webhook Subscription Lifecycle', () => {
const {checkHasActivePaidPremium} = await import('@app/api/user/UserHelpers');
expect(checkHasActivePaidPremium(afterUser!)).toBe(false);
});
test('grants standard grace when the subscription is cancelled at the end of its paid period', async () => {
test('ends premium without grace when the subscription is cancelled at the end of its paid period', async () => {
const account = await createTestAccount(harness);
const userId = createUserID(BigInt(account.userId));
const subscriptionId = 'sub_test_cancel_natural';
@@ -523,8 +599,113 @@ describe('Stripe Webhook Subscription Lifecycle', () => {
expect(result.received).toBe(true);
const afterUser = await userRepository.findUnique(userId);
expect(afterUser?.premiumUntil?.getTime()).toBe(premiumUntil.getTime());
expect(afterUser?.premiumGraceEndsAt).not.toBeNull();
expect(afterUser!.premiumGraceEndsAt!.getTime()).toBe(endedAt * 1000 + 3 * 24 * 60 * 60 * 1000);
expect(afterUser?.premiumGraceEndsAt?.getTime()).toBe(endedAt * 1000);
const {checkHasActivePaidPremium} = await import('@app/api/user/UserHelpers');
expect(checkHasActivePaidPremium(afterUser!)).toBe(false);
});
test('keeps the payment recovery deadline when Stripe cancels for non-payment', async () => {
const account = await createTestAccount(harness);
const userId = createUserID(BigInt(account.userId));
const subscriptionId = 'sub_test_cancel_non_payment';
const sessionId = `cs_test_non_payment_${Date.now()}`;
await paymentRepository.createPayment({
checkout_session_id: sessionId,
user_id: userId,
price_id: MOCK_PRICES.monthlyUsd,
product_type: ProductType.MONTHLY_SUBSCRIPTION,
status: 'completed',
is_gift: false,
created_at: new Date(),
});
await paymentRepository.updatePayment({
checkout_session_id: sessionId,
subscription_id: subscriptionId,
stripe_customer_id: 'cus_test_1',
status: 'completed',
});
const lapseStart = new Date(Math.floor((Date.now() - 5 * 24 * 60 * 60 * 1000) / 1000) * 1000);
const recoveryDeadline = new Date(lapseStart.getTime() + 7 * 24 * 60 * 60 * 1000);
await userRepository.patchUpsert(
userId,
{
premium_type: UserPremiumTypes.SUBSCRIPTION,
stripe_subscription_id: subscriptionId,
stripe_customer_id: 'cus_test_1',
premium_since: new Date(),
premium_until: lapseStart,
premium_billing_cycle: 'monthly',
premium_will_cancel: true,
premium_grace_ends_at: recoveryDeadline,
},
(await userRepository.findUnique(userId))!.toRow(),
);
const endedAt = Math.floor(Date.now() / 1000);
const eventData = createSubscriptionDeletedEvent({
subscriptionId,
endedAt,
cancellationReason: 'payment_failed',
interval: 'month',
});
const result = await sendWebhook(eventData);
expect(result.received).toBe(true);
const afterUser = await userRepository.findUnique(userId);
expect(afterUser?.premiumType).toBe(UserPremiumTypes.SUBSCRIPTION);
expect(afterUser?.premiumUntil?.getTime()).toBe(lapseStart.getTime());
expect(afterUser?.premiumGraceEndsAt?.getTime()).toBe(recoveryDeadline.getTime());
expect(afterUser?.premiumGraceEndsAt?.getTime()).not.toBe(endedAt * 1000 + PREMIUM_GRACE_PERIOD_MS);
expect(afterUser?.stripeSubscriptionId).toBeNull();
const {checkHasActivePaidPremium} = await import('@app/api/user/UserHelpers');
expect(checkHasActivePaidPremium(afterUser!)).toBe(true);
});
test('records the recovery deadline from the payload cycle when none was recorded', async () => {
const account = await createTestAccount(harness);
const userId = createUserID(BigInt(account.userId));
const subscriptionId = 'sub_test_cancel_non_payment_yearly';
const sessionId = `cs_test_non_payment_yearly_${Date.now()}`;
await paymentRepository.createPayment({
checkout_session_id: sessionId,
user_id: userId,
price_id: MOCK_PRICES.yearlyUsd,
product_type: ProductType.YEARLY_SUBSCRIPTION,
status: 'completed',
is_gift: false,
created_at: new Date(),
});
await paymentRepository.updatePayment({
checkout_session_id: sessionId,
subscription_id: subscriptionId,
stripe_customer_id: 'cus_test_1',
status: 'completed',
});
const lapseStart = new Date(Math.floor((Date.now() - 10 * 24 * 60 * 60 * 1000) / 1000) * 1000);
await userRepository.patchUpsert(
userId,
{
premium_type: UserPremiumTypes.SUBSCRIPTION,
stripe_subscription_id: subscriptionId,
stripe_customer_id: 'cus_test_1',
premium_since: new Date(),
premium_until: lapseStart,
premium_billing_cycle: null,
premium_grace_ends_at: null,
},
(await userRepository.findUnique(userId))!.toRow(),
);
const endedAt = Math.floor(Date.now() / 1000);
const eventData = createSubscriptionDeletedEvent({
subscriptionId,
endedAt,
cancellationReason: 'payment_failed',
interval: 'year',
});
const result = await sendWebhook(eventData);
expect(result.received).toBe(true);
const afterUser = await userRepository.findUnique(userId);
expect(afterUser?.premiumUntil?.getTime()).toBe(lapseStart.getTime());
expect(afterUser?.premiumGraceEndsAt?.getTime()).toBe(
lapseStart.getTime() + getPremiumPaymentRecoveryGraceMs('yearly'),
);
expect(afterUser?.premiumGraceEndsAt?.getTime()).toBe(lapseStart.getTime() + 14 * 24 * 60 * 60 * 1000);
const {checkHasActivePaidPremium} = await import('@app/api/user/UserHelpers');
expect(checkHasActivePaidPremium(afterUser!)).toBe(true);
});
@@ -10,7 +10,6 @@ import {
import {resetSharedListsForTests} from '@app/api/infrastructure/activity/SharedLists';
import {NullSearchProvider} from '@app/api/infrastructure/NullSearchProvider';
import {ipBanCache} from '@app/api/middleware/IpBanMiddleware';
import {setInjectedIpInfoService} from '@app/api/middleware/ServiceMiddleware';
import {
setInjectedBlueskyOAuthService,
setInjectedGatewayService,
@@ -106,7 +105,6 @@ export async function createApiTestHarness(options: CreateApiTestHarnessOptions
getInstanceConfigRepository().clearCacheForTesting();
kvProvider.reset();
mockBlueskyOAuthService.reset();
setInjectedIpInfoService(undefined);
setInjectedUnfurlerService(undefined);
resetSharedListsForTests();
}
@@ -134,7 +132,6 @@ export async function createApiTestHarness(options: CreateApiTestHarnessOptions
setInjectedWorkerService(new NoopWorkerService());
setInjectedGatewayService(new NoopGatewayService());
setInjectedKVProvider(new MockKVProvider());
setInjectedIpInfoService(undefined);
setInjectedUnfurlerService(undefined);
resetSharedListsForTests();
const fallbackStorageService = new MockStorageService();
@@ -1,28 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {HttpResponse, http} from 'msw';
export function createIpInfoLookupHandler() {
return http.get('https://api.ipinfo.io/lookup/:ip', ({params}) => {
const ip = typeof params.ip === 'string' ? params.ip : '198.51.100.1';
return HttpResponse.json({
ip,
geo: {
city: 'Ashburn',
region: 'Virginia',
region_code: 'VA',
country: 'United States',
country_code: 'US',
continent: 'North America',
continent_code: 'NA',
},
as: {
asn: 'AS64500',
name: 'Test ISP',
domain: 'example.com',
type: 'isp',
},
anonymous: {},
});
});
}
@@ -1857,6 +1857,8 @@ export function createSubscriptionDeletedEvent(options: {
subscriptionId?: string;
customerId?: string;
endedAt?: number;
cancellationReason?: 'cancellation_requested' | 'payment_disputed' | 'payment_failed';
interval?: 'month' | 'year';
}): StripeWebhookEventData {
const nowSeconds = Math.floor(Date.now() / 1000);
return {
@@ -1869,6 +1871,15 @@ export function createSubscriptionDeletedEvent(options: {
status: 'canceled',
canceled_at: nowSeconds,
ended_at: options.endedAt ?? nowSeconds,
...(options.cancellationReason ? {cancellation_details: {reason: options.cancellationReason}} : {}),
...(options.interval
? {
items: {
object: 'list',
data: [{object: 'subscription_item', price: {recurring: {interval: options.interval}}}],
},
}
: {}),
},
},
};
-2
View File
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {createIpInfoLookupHandler} from '@app/api/test/msw/handlers/IpInfoHandlers';
import {createNcmecHandlers} from '@app/api/test/msw/handlers/NcmecHandlers';
import {createOnionooDetailsHandler} from '@app/api/test/msw/handlers/OnionooHandlers';
import {createOpenNsfwHandlers} from '@app/api/test/msw/handlers/OpenNsfwHandlers';
@@ -10,7 +9,6 @@ import {setupServer} from 'msw/node';
export const server = setupServer(
...createNcmecHandlers(),
...createOpenNsfwHandlers(),
createIpInfoLookupHandler(),
createOnionooDetailsHandler(),
createPwnedPasswordsRangeHandler(),
);
@@ -7,9 +7,11 @@ import {
checkIsPremium,
getEffectivePremiumUntil,
getEffectiveSuspiciousFlags,
getPremiumPaymentRecoveryGraceMs,
getRequiredActions,
isSignInRefused,
isTemporarilyBanned,
PREMIUM_GRACE_PERIOD_MS,
} from '@app/api/user/UserHelpers';
import {
DEFERRED_PHONE_ON_COMMUNITY_JOIN,
@@ -289,3 +291,17 @@ describe('account standing', () => {
expect(canOwnerRunBots(standing(0n))).toBe(true);
});
});
describe('premium grace lengths', () => {
it('maps billing cycles to payment recovery grace', () => {
const day = 24 * 60 * 60 * 1000;
expect(getPremiumPaymentRecoveryGraceMs('monthly')).toBe(7 * day);
expect(getPremiumPaymentRecoveryGraceMs('yearly')).toBe(14 * day);
expect(getPremiumPaymentRecoveryGraceMs(null)).toBe(7 * day);
expect(getPremiumPaymentRecoveryGraceMs(undefined)).toBe(7 * day);
});
it('keeps the fallback grace at 3 days', () => {
expect(PREMIUM_GRACE_PERIOD_MS).toBe(3 * 24 * 60 * 60 * 1000);
});
});
+12 -2
View File
@@ -9,12 +9,14 @@ import {extractEmailDomain} from '@app/api/utils/EmailDomainUtils';
import {
DEFERRABLE_PHONE_FLAGS,
DEFERRED_PHONE_ON_COMMUNITY_JOIN,
PREMIUM_GRACE_PERIOD_DAYS,
PREMIUM_PAYMENT_RECOVERY_GRACE_DAYS,
PremiumFlags,
SuspiciousActivityFlags,
UserFlags,
} from '@fluxer/constants/src/UserConstants';
import {MS_PER_DAY} from '@fluxer/date_utils/src/DateConstants';
import type {RequiredAction} from '@fluxer/schema/src/domains/user/UserResponseSchemas';
import {ms} from 'itty-time';
type ClauseAction = Exclude<RequiredAction, 'REQUIRE_INBOUND_PHONE_VERIFICATION'>;
type VerificationChannel = 'email' | 'phone';
@@ -214,7 +216,15 @@ interface PremiumCheckable {
premiumFlags: number;
}
export const PREMIUM_GRACE_PERIOD_MS = ms('3 days');
export const PREMIUM_GRACE_PERIOD_MS = PREMIUM_GRACE_PERIOD_DAYS * MS_PER_DAY;
export function getPremiumPaymentRecoveryGraceMs(billingCycle: string | null | undefined): number {
const days =
billingCycle === 'yearly'
? PREMIUM_PAYMENT_RECOVERY_GRACE_DAYS.yearly
: PREMIUM_PAYMENT_RECOVERY_GRACE_DAYS.monthly;
return days * MS_PER_DAY;
}
export function getEffectivePremiumUntil(
user: Pick<PremiumCheckable, 'premiumUntil' | 'premiumGiftExtensionEndsAt'>,
@@ -38,7 +38,6 @@ import type {InviteService} from '@app/api/invite/InviteService';
import {Logger} from '@app/api/Logger';
import type {LimitConfigService} from '@app/api/limits/LimitConfigService';
import {createGuildStackServices} from '@app/api/middleware/GuildStackServiceFactory';
import {getIpInfoService} from '@app/api/middleware/ServiceMiddleware';
import {
ensureVoiceResourcesInitialized,
getGatewayService,
@@ -237,7 +236,6 @@ export async function initializeWorkerDependencies(snowflakeService: ISnowflakeS
}
const inviteRepository = getInviteRepository();
const webhookRepository = getWebhookRepository();
const ipInfoService = getIpInfoService();
const contactChangeLogService = getContactChangeLogService();
const apiContext = createApiContext();
const {channelService, guildService, inviteService} = createGuildStackServices({
@@ -263,7 +261,6 @@ export async function initializeWorkerDependencies(snowflakeService: ISnowflakeS
voiceRoomStore,
liveKitService,
voiceAvailabilityService,
ipInfoService,
});
const billingRepository = new BillingRepository(snowflakeService, kvClient);
const storeEntitlementService = createStoreEntitlementService({
@@ -75,6 +75,9 @@ function buildStripePremiumRepairPatch(user: User, subscription: Stripe.Subscrip
if (user.premiumWillCancel !== premiumWillCancel) {
patch.premium_will_cancel = premiumWillCancel;
}
if (user.premiumGraceEndsAt != null) {
patch.premium_grace_ends_at = null;
}
if (premiumBillingCycle && user.premiumBillingCycle !== premiumBillingCycle) {
patch.premium_billing_cycle = premiumBillingCycle;
}
@@ -293,7 +296,9 @@ async function reconcileUserPremiumStateFromStripe(params: {userId: UserID; stri
const patch: Partial<UserRow> = {};
let effectivePremiumUntil = getEffectivePremiumUntil(user);
const paidThrough = await getPaidThroughFromSubscriptionInvoices(stripe, mostRecentTerminalSubscription);
if (mostRecentTerminalSubscription?.ended_at && user.premiumUntil) {
const terminalSubscriptionIsCurrent =
user.stripeSubscriptionId == null || mostRecentTerminalSubscription?.id === user.stripeSubscriptionId;
if (mostRecentTerminalSubscription?.ended_at && user.premiumUntil && terminalSubscriptionIsCurrent) {
const subscriptionEndedAt = new Date(mostRecentTerminalSubscription.ended_at * 1000);
const entitlementEnd =
paidThrough && paidThrough.getTime() > subscriptionEndedAt.getTime() ? paidThrough : subscriptionEndedAt;
@@ -314,7 +319,10 @@ async function reconcileUserPremiumStateFromStripe(params: {userId: UserID; stri
premiumGiftExtensionEndsAt: user.premiumGiftExtensionEndsAt,
});
}
const hasFutureLocalEntitlement = effectivePremiumUntil != null && Date.now() <= effectivePremiumUntil.getTime();
const graceEndsAt = patch.premium_grace_ends_at ?? user.premiumGraceEndsAt;
const hasFutureLocalEntitlement =
(effectivePremiumUntil != null && Date.now() <= effectivePremiumUntil.getTime()) ||
(graceEndsAt != null && Date.now() <= graceEndsAt.getTime());
if (hasFutureLocalEntitlement) {
if (user.premiumWillCancel !== true) {
patch.premium_will_cancel = true;
+63 -15
View File
@@ -2,19 +2,65 @@
import {createUserID, type UserID} from '@app/api/BrandedTypes';
import {createRequestCache} from '@app/api/middleware/RequestCacheMiddleware';
import type {User} from '@app/api/models/User';
import {UserChannelService} from '@app/api/user/services/UserChannelService';
import {getWorkerDependencies} from '@app/api/worker/WorkerContext';
import {JobCancelledError, type WorkerTaskHelpers} from '@pkgs/worker/src/contracts/WorkerTask';
import {UserFlags} from '@fluxer/constants/src/UserConstants';
import {JobCancelledError, type WorkerTaskHelpers, type WorkerTaskResult} from '@pkgs/worker/src/contracts/WorkerTask';
import {z} from 'zod';
const SYSTEM_USER_ID: UserID = createUserID(0n);
const PayloadSchema = z.object({
content: z.string().min(1).max(4000),
user_ids: z.array(z.string().regex(/^\d+$/)).min(1),
});
const ALL_USERS_PAGE_SIZE = 100;
const CURSOR_TTL_SECONDS = 7 * 24 * 60 * 60;
const INELIGIBLE_FLAGS = UserFlags.DELETED | UserFlags.SELF_DELETED | UserFlags.DISABLED;
const PayloadSchema = z.union([
z.object({
content: z.string().min(1).max(4000),
user_ids: z.array(z.string().regex(/^\d+$/)).min(1),
}),
z.object({
content: z.string().min(1).max(4000),
all_users: z.literal(true),
}),
]);
export async function sendSystemDm(payload: unknown, helpers: WorkerTaskHelpers): Promise<void> {
const {content, user_ids} = PayloadSchema.parse(payload);
function isEligibleRecipient(user: User): boolean {
return user.id !== SYSTEM_USER_ID && !user.isBot && !user.isSystem && (user.flags & INELIGIBLE_FLAGS) === 0n;
}
async function* allUserRecipients(helpers: WorkerTaskHelpers): AsyncGenerator<UserID> {
const {userRepository, kvClient} = getWorkerDependencies();
const cursorKey = `system_dm:all_users_cursor:${helpers.jobId}`;
let pageState = await kvClient.get(cursorKey);
if (pageState !== null) {
helpers.logger.info('Resuming system DM broadcast from saved cursor');
}
do {
const page = await userRepository.scanAllUsersPage(ALL_USERS_PAGE_SIZE, pageState);
for (const user of page.users) {
if (isEligibleRecipient(user)) {
yield user.id;
}
}
pageState = page.pageState;
if (pageState !== null) {
await kvClient.setex(cursorKey, CURSOR_TTL_SECONDS, pageState);
}
} while (pageState !== null);
await kvClient.del(cursorKey);
}
async function* listedRecipients(userIds: Array<string>): AsyncGenerator<UserID> {
for (const raw of userIds) {
yield createUserID(BigInt(raw));
}
}
export async function sendSystemDm(payload: unknown, helpers: WorkerTaskHelpers): Promise<WorkerTaskResult> {
const parsed = PayloadSchema.parse(payload);
const {content} = parsed;
const total = 'user_ids' in parsed ? parsed.user_ids.length : null;
const recipients = 'user_ids' in parsed ? listedRecipients(parsed.user_ids) : allUserRecipients(helpers);
const deps = getWorkerDependencies();
const systemUser = await deps.userRepository.findUniqueAssert(SYSTEM_USER_ID);
const userChannelService = new UserChannelService(
@@ -29,16 +75,12 @@ export async function sendSystemDm(payload: unknown, helpers: WorkerTaskHelpers)
const requestCache = createRequestCache();
let sent = 0;
let failed = 0;
for (const raw of user_ids) {
for await (const recipientId of recipients) {
if (await helpers.shouldCancel()) {
helpers.logger.info(
{sent, failed, remaining: user_ids.length - sent - failed},
'System DM job cancelled mid-flight',
);
helpers.logger.info({sent, failed, total}, 'System DM job cancelled mid-flight');
requestCache.clear();
throw new JobCancelledError();
}
const recipientId = createUserID(BigInt(raw));
try {
const channel = await userChannelService.ensureDmOpenForBothUsers({
userId: SYSTEM_USER_ID,
@@ -55,9 +97,15 @@ export async function sendSystemDm(payload: unknown, helpers: WorkerTaskHelpers)
sent += 1;
} catch (error) {
failed += 1;
helpers.logger.warn({recipientId: raw, error}, 'System DM send failed for recipient');
helpers.logger.warn({recipientId: recipientId.toString(), error}, 'System DM send failed for recipient');
}
if ((sent + failed) % ALL_USERS_PAGE_SIZE === 0) {
requestCache.clear();
await helpers.reportProgress(sent + failed, total, `${sent} sent, ${failed} failed`);
}
}
requestCache.clear();
helpers.logger.info({sent, failed, total: user_ids.length}, 'System DM job complete');
await helpers.reportProgress(sent + failed, sent + failed, `${sent} sent, ${failed} failed`);
helpers.logger.info({sent, failed, total: sent + failed}, 'System DM job complete');
return {sent_count: sent, failed_count: failed};
}
@@ -5,7 +5,7 @@ import {AdminBanManagementService} from '@app/api/admin/services/AdminBanManagem
import {AdminGuildService} from '@app/api/admin/services/AdminGuildService';
import {AdminUserService} from '@app/api/admin/services/AdminUserService';
import {createApiContext} from '@app/api/CreateApiContext';
import {getIpInfoService, getReportServiceInstance} from '@app/api/middleware/ServiceMiddleware';
import {getReportServiceInstance} from '@app/api/middleware/ServiceMiddleware';
import {
getDiscriminatorService,
getEntityAssetService,
@@ -28,7 +28,6 @@ export function createAdminBulkServices(deps: WorkerDependencies): AdminBulkServ
apiContext,
adminRepository: deps.adminRepository,
auditService,
ipInfoService: getIpInfoService(),
});
const userService = new AdminUserService({
apiContext,
@@ -10,7 +10,6 @@ import {DisabledLiveKitService} from '@app/api/infrastructure/DisabledLiveKitSer
import {InMemoryVoiceRoomStore} from '@app/api/infrastructure/InMemoryVoiceRoomStore';
import {getMessages} from '@app/api/message/tests/MessageTestUtils';
import {createGuildStackServices} from '@app/api/middleware/GuildStackServiceFactory';
import {getIpInfoService} from '@app/api/middleware/ServiceMiddleware';
import {getGatewayService, getSnowflakeService, getVoiceAvailabilityService} from '@app/api/middleware/ServiceRegistry';
import {
getAdminRepository,
@@ -97,7 +96,6 @@ function installWorkerDependencies(): void {
voiceRoomStore: new InMemoryVoiceRoomStore(),
liveKitService: new DisabledLiveKitService(),
voiceAvailabilityService: getVoiceAvailabilityService(),
ipInfoService: getIpInfoService(),
});
setWorkerDependenciesForTest({
adminRepository: getAdminRepository(),
@@ -71,6 +71,28 @@ function createActiveSubscription(periodEndMs: number): Stripe.Subscription {
} as unknown as Stripe.Subscription;
}
function createPastDueSubscription(): Stripe.Subscription {
return {
id: 'sub_test',
status: 'past_due',
customer: 'cus_test',
ended_at: null,
canceled_at: null,
cancel_at: null,
cancel_at_period_end: false,
trial_end: null,
start_date: Math.floor((Date.now() - 200 * ONE_DAY_MS) / 1000),
items: {
data: [
{
current_period_end: Math.floor((Date.now() + 29 * ONE_DAY_MS) / 1000),
price: {recurring: {interval: 'month'}},
},
],
},
} as unknown as Stripe.Subscription;
}
function createPaidInvoice(periodEndMs: number): Stripe.Invoice {
return {
id: 'in_test',
@@ -344,6 +366,153 @@ describe('processPremiumStateReconciliationQueue', () => {
expect(patches[0].premium_until).toBeNull();
expect(patches[0].premium_since).toBeNull();
});
test('keeps premium for a past_due subscription until the recorded payment recovery deadline', async () => {
const queueService = createQueueService();
await queueService.enqueueUser(USER_ID, new Date(Date.now() - 1000));
const lapseStartMs = Math.floor((Date.now() - ONE_HOUR_MS) / 1000) * 1000;
const user = createPremiumUser({
premium_until: new Date(lapseStartMs),
premium_will_cancel: true,
premium_billing_cycle: 'monthly',
premium_grace_ends_at: new Date(lapseStartMs + 7 * ONE_DAY_MS),
});
const {userRepository, patches, extras} = createCapturingDeps(user);
setWorkerDependenciesForTest({
premiumStateReconciliationQueueService: queueService,
stripe: createStripeStub(createPastDueSubscription(), [createPaidInvoice(lapseStartMs)]),
userRepository,
...extras,
});
await processPremiumStateReconciliationQueue({}, createHelpers());
expect(patches).toHaveLength(0);
expect(await queueService.getQueueSize()).toBe(0);
});
test('keeps the recovery deadline when an older cancelled subscription shares the customer', async () => {
const queueService = createQueueService();
await queueService.enqueueUser(USER_ID, new Date(Date.now() - 1000));
const lapseStartMs = Math.floor((Date.now() - ONE_HOUR_MS) / 1000) * 1000;
const recoveryDeadline = new Date(lapseStartMs + 7 * ONE_DAY_MS);
const user = createPremiumUser({
premium_until: new Date(lapseStartMs),
premium_will_cancel: true,
premium_billing_cycle: 'monthly',
premium_grace_ends_at: recoveryDeadline,
stripe_subscription_id: 'sub_current',
});
const {userRepository, patches, extras} = createCapturingDeps(user);
const currentSubscription = {...createPastDueSubscription(), id: 'sub_current'} as Stripe.Subscription;
const olderSubscription = {
...createCancelledSubscription(Date.now() - 90 * ONE_DAY_MS),
id: 'sub_older',
} as Stripe.Subscription;
setWorkerDependenciesForTest({
premiumStateReconciliationQueueService: queueService,
stripe: {
subscriptions: {
retrieve: async () => currentSubscription,
list: async () => ({data: [olderSubscription, currentSubscription]}),
},
invoices: {
list: async () => ({data: [createPaidInvoice(Date.now() - 90 * ONE_DAY_MS)]}),
},
} as unknown as Stripe,
userRepository,
...extras,
});
await processPremiumStateReconciliationQueue({}, createHelpers());
expect(patches).toHaveLength(0);
});
test('clears a leftover recovery deadline once the subscription is active again', async () => {
const queueService = createQueueService();
await queueService.enqueueUser(USER_ID, new Date(Date.now() - 1000));
const periodEndMs = Math.floor((Date.now() + 29 * ONE_DAY_MS) / 1000) * 1000;
const user = createPremiumUser({
premium_until: new Date(periodEndMs),
premium_billing_cycle: 'monthly',
premium_grace_ends_at: new Date(Date.now() + 6 * ONE_DAY_MS),
});
const {userRepository, patches, extras} = createCapturingDeps(user);
setWorkerDependenciesForTest({
premiumStateReconciliationQueueService: queueService,
stripe: createStripeStub(createActiveSubscription(periodEndMs), []),
userRepository,
...extras,
});
await processPremiumStateReconciliationQueue({}, createHelpers());
expect(patches).toHaveLength(1);
expect(patches[0].premium_grace_ends_at).toBeNull();
expect(patches[0].premium_until).toBeUndefined();
});
test('strips a past_due subscription once the recovery deadline has passed', async () => {
const queueService = createQueueService();
await queueService.enqueueUser(USER_ID, new Date(Date.now() - 1000));
const lapseStartMs = Math.floor((Date.now() - 7 * ONE_DAY_MS - 60_000) / 1000) * 1000;
const user = createPremiumUser({
premium_until: new Date(lapseStartMs),
premium_will_cancel: true,
premium_billing_cycle: 'monthly',
premium_grace_ends_at: new Date(lapseStartMs + 7 * ONE_DAY_MS),
});
const {userRepository, patches, extras} = createCapturingDeps(user);
setWorkerDependenciesForTest({
premiumStateReconciliationQueueService: queueService,
stripe: createStripeStub(createPastDueSubscription(), [createPaidInvoice(lapseStartMs)]),
userRepository,
...extras,
});
await processPremiumStateReconciliationQueue({}, createHelpers());
expect(patches).toHaveLength(1);
expect(patches[0].premium_type).toBeNull();
expect(patches[0].premium_grace_ends_at).toBeNull();
});
test('honours the voluntary-cancel grace written by the delete webhook', async () => {
const queueService = createQueueService();
await queueService.enqueueUser(USER_ID, new Date(Date.now() - 1000));
const endedAtMs = Math.floor((Date.now() - 60_000) / 1000) * 1000;
const user = createPremiumUser({
premium_until: new Date(endedAtMs),
premium_will_cancel: false,
premium_billing_cycle: null,
stripe_subscription_id: null,
premium_grace_ends_at: new Date(endedAtMs + 3 * ONE_DAY_MS),
});
const {userRepository, patches, extras} = createCapturingDeps(user);
setWorkerDependenciesForTest({
premiumStateReconciliationQueueService: queueService,
stripe: createStripeStub(createCancelledSubscription(endedAtMs), [createPaidInvoice(endedAtMs)]),
userRepository,
...extras,
});
await processPremiumStateReconciliationQueue({}, createHelpers());
expect(patches.every((patch) => patch.premium_type === undefined)).toBe(true);
expect(patches.every((patch) => patch.premium_until === undefined)).toBe(true);
expect(patches.every((patch) => patch.premium_grace_ends_at === undefined)).toBe(true);
});
test('hands a user with an active App Store subscription and a stale Stripe customer to the store', async () => {
const queueService = createQueueService();
await queueService.enqueueUser(USER_ID, new Date(Date.now() - 1000));
@@ -8,6 +8,7 @@ import type {UserRepository} from '@app/api/user/repositories/UserRepository';
import {sendSystemDm} from '@app/api/worker/tasks/SendSystemDm';
import {clearWorkerDependencies, setWorkerDependenciesForTest} from '@app/api/worker/WorkerContext';
import {WorkerRunner} from '@app/api/worker/WorkerRunner';
import {UserFlags} from '@fluxer/constants/src/UserConstants';
import type {JsMsg} from '@nats-io/jetstream';
import {afterEach, beforeAll, describe, expect, it, vi} from 'vitest';
@@ -71,11 +72,11 @@ function createWorkerDependencies() {
return {sentChannelIds, sentUserIds};
}
function createJobMessage() {
function createJobMessage(recipients: Record<string, unknown> = {user_ids: ['11', '12', '13']}) {
const envelope = {
payload: {
content: 'scheduled maintenance tonight',
user_ids: ['11', '12', '13'],
...recipients,
__jobId: LEDGER_JOB_ID.toString(),
},
max_attempts: 5,
@@ -164,4 +165,61 @@ describe('System DM cancellation', () => {
expect(deps.sentUserIds).toEqual([0n, 0n, 0n]);
});
it('broadcasts to every eligible user when all_users is set', async () => {
const user = (id: bigint, extra: Record<string, unknown> = {}) => ({
id,
isBot: false,
isSystem: false,
flags: 0n,
...extra,
});
const pages = [
{users: [user(0n, {isSystem: true}), user(21n), user(22n, {isBot: true})], pageState: 'page-2'},
{
users: [user(23n, {flags: UserFlags.DELETED}), user(24n), user(25n, {flags: UserFlags.DISABLED})],
pageState: null,
},
];
const kv = new Map<string, string>();
const kvClient = {
get: async (key: string) => kv.get(key) ?? null,
setex: async (key: string, _ttl: number, value: string) => {
kv.set(key, value);
},
del: async (key: string) => (kv.delete(key) ? 1 : 0),
};
const recipientIds: Array<bigint> = [];
const systemUser = {id: 0n, username: 'Fluxer', bot: true, system: true};
const userRepository = {
findUnique: async () => systemUser,
findUniqueAssert: async () => systemUser,
findExistingDmState: async (_userId: bigint, recipientId: bigint) => {
recipientIds.push(recipientId);
return {id: 500n};
},
isDmChannelOpen: async () => true,
scanAllUsersPage: async (_limit: number, pageState: string | null) =>
pageState === 'page-2' ? pages[1] : pages[0],
} as unknown as UserRepository;
const channelService = {
messages: {send: {sendMessage: async () => {}}},
} as unknown as ChannelService;
setWorkerDependenciesForTest({userRepository, channelService, kvClient} as never);
const {ledger, markSucceeded} = createLedgerStub(Number.POSITIVE_INFINITY);
const runner = new TestWorkerRunner({
tasks: {[TASK_TYPE]: sendSystemDm},
queue: queueStub,
consumerName: 'workers_batch',
laneName: 'batch',
ledger,
concurrency: 1,
});
await expect(runner.runJob(TASK_TYPE, createJobMessage({all_users: true}) as unknown as JsMsg)).resolves.toBe(true);
expect(recipientIds).toEqual([21n, 24n]);
expect(markSucceeded).toHaveBeenCalledWith(LEDGER_JOB_ID, {sent_count: 2, failed_count: 0});
expect(kv.size).toBe(0);
});
});
@@ -8,6 +8,7 @@ import type {TrackBitrateInfo} from './PCTransport.ts';
import {
applyVideoStartBitrate,
collectStereoMids,
conformBundledCodecFmtp,
ensureAudioNackAndStereo,
ensureOpusFmtp,
ensureVideoDDExtension,
@@ -282,15 +283,63 @@ describe('placeholderMidsFromTransceivers', () => {
return {mid, currentDirection, sender: {track}} as unknown as RTCRtpTransceiver;
}
it('keeps the trackless recvonly sections that still hold an m-line', () => {
it('keeps unused trackless sections that still hold an m-line', () => {
const mids = placeholderMidsFromTransceivers([
transceiver('3', null, 'recvonly'),
transceiver('3', null, 'inactive'),
transceiver('4', null, null),
transceiver('7', {} as MediaStreamTrack, 'sendonly'),
]);
expect(mids).toEqual(new Set(['3']));
expect(mids).toEqual(new Set(['3', '4']));
});
it('drops a transceiver that unpublish stopped so its recycled m-section is not fmtp-conformed', () => {
expect(placeholderMidsFromTransceivers([transceiver('7', null, 'stopped')])).toEqual(new Set());
});
it.each(['recvonly', 'sendrecv'] as const)(
'preserves a negotiated %s receiver without a local sender',
(direction) => {
expect(placeholderMidsFromTransceivers([transceiver('0', null, direction)])).toEqual(new Set());
},
);
it.each(['sendonly', 'sendrecv', undefined] as const)(
'preserves a receiver activated by a remote %s answer before currentDirection updates',
(direction) => {
const incoming = opusMedia('useinbandfec=1');
incoming.direction = direction;
expect(placeholderMidsFromTransceivers([transceiver('0', null, null)], [incoming])).toEqual(new Set());
},
);
it('keeps inactive and rejected remote sections eligible for placeholder conformance', () => {
const inactive = opusMedia('useinbandfec=1', '0');
inactive.direction = 'inactive';
const rejected = opusMedia('useinbandfec=1', '1');
rejected.direction = 'sendonly';
rejected.port = 0;
expect(
placeholderMidsFromTransceivers(
[transceiver('0', null, 'inactive'), transceiver('1', null, null)],
[inactive, rejected],
),
).toEqual(new Set(['0', '1']));
});
it('starting a stereo share preserves incoming microphone fmtp while conforming unused placeholders', () => {
const microphone = opusMedia('useinbandfec=1;maxaveragebitrate=64000', '0');
const placeholder = opusMedia('useinbandfec=1;usedtx=1', '1');
const screenShare = opusMedia('useinbandfec=1', '2');
ensureOpusFmtp(screenShare, 128000, true);
const microphoneConfig = opusConfig(microphone);
const mids = placeholderMidsFromTransceivers([
transceiver('0', null, 'recvonly'),
transceiver('1', null, 'inactive'),
transceiver('2', {} as MediaStreamTrack, 'sendonly'),
]);
conformBundledCodecFmtp([microphone, placeholder, screenShare], (media) => mids.has(String(media.mid)));
expect(opusConfig(microphone)).toBe(microphoneConfig);
expect(opusConfig(screenShare)).toContain('stereo=1');
expect(opusConfig(placeholder)).toBe(opusConfig(screenShare));
});
});
@@ -257,7 +257,7 @@ export default class PCTransport extends (EventEmitter as new () => TypedEmitter
}
}
});
const placeholderMids = this.getPlaceholderMids();
const placeholderMids = this.getPlaceholderMids(sdpParsed.media);
if (placeholderMids.size > 0) {
conformBundledCodecFmtp(sdpParsed.media, (media) => placeholderMids.has(getMidString(media.mid!)));
}
@@ -461,8 +461,11 @@ export default class PCTransport extends (EventEmitter as new () => TypedEmitter
}
}
private getPlaceholderMids(): Set<string> {
return placeholderMidsFromTransceivers(this._pc?.getTransceivers() ?? []);
private getPlaceholderMids(remoteMedia?: ReadonlyArray<MediaDescription>): Set<string> {
return placeholderMidsFromTransceivers(
this._pc?.getTransceivers() ?? [],
remoteMedia ?? parse(this._pc?.remoteDescription?.sdp ?? '').media,
);
}
createDataChannel(label: string, dataChannelDict: RTCDataChannelInit) {
@@ -853,10 +856,28 @@ export function collectStereoMids(
return stereoMids;
}
export function placeholderMidsFromTransceivers(transceivers: ReadonlyArray<RTCRtpTransceiver>): Set<string> {
export function placeholderMidsFromTransceivers(
transceivers: ReadonlyArray<RTCRtpTransceiver>,
remoteMedia: ReadonlyArray<MediaDescription> = [],
): Set<string> {
const receivingMids = new Set(
remoteMedia
.filter(
(media) =>
media.mid !== undefined &&
media.port !== 0 &&
(media.direction === 'sendonly' || media.direction === 'sendrecv' || media.direction === undefined),
)
.map((media) => getMidString(media.mid!)),
);
const mids = new Set<string>();
for (const transceiver of transceivers) {
if (transceiver.currentDirection === 'stopped') {
if (
transceiver.currentDirection === 'stopped' ||
transceiver.currentDirection === 'recvonly' ||
transceiver.currentDirection === 'sendrecv' ||
(transceiver.mid !== null && receivingMids.has(transceiver.mid))
) {
continue;
}
if (transceiver.mid && !transceiver.sender.track) {
@@ -0,0 +1,127 @@
import {type AddTrackRequest, AudioTrackFeature, ParticipantPermission, TrackInfo} from '@livekit/protocol';
import {EventEmitter} from 'events';
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
import {SignalConnectionState} from '../../api/SignalClient.ts';
import {publishDefaults, roomOptionDefaults} from '../defaults.ts';
import {TrackEvent} from '../events.ts';
import type RTCEngine from '../RTCEngine.ts';
import LocalAudioTrack from '../track/LocalAudioTrack.ts';
import {Track} from '../track/Track.ts';
import LocalParticipant from './LocalParticipant.ts';
class TestMediaStreamTrack extends EventTarget {
readonly id = 'microphone-input';
readonly kind = 'audio';
enabled = true;
readyState: MediaStreamTrackState = 'live';
constructor(private readonly channelCount: number) {
super();
}
getSettings(): MediaTrackSettings {
return {channelCount: this.channelCount, echoCancellation: true};
}
getConstraints(): MediaTrackConstraints {
return {};
}
stop() {
this.readyState = 'ended';
}
}
class TestMediaStream {
constructor(private readonly tracks: Array<MediaStreamTrack>) {}
getTracks() {
return this.tracks;
}
}
function createPublisher() {
const setTrackCodecBitrate = vi.fn();
const sendUpdateLocalAudioTrack = vi.fn();
const sender = {replaceTrack: vi.fn(async () => undefined)} as unknown as RTCRtpSender;
const transceiver = {sender} as RTCRtpTransceiver;
const addTrack = vi.fn(
async (request: AddTrackRequest) =>
new TrackInfo({
sid: 'TR_microphone',
name: request.name,
type: request.type,
source: request.source,
audioFeatures: request.audioFeatures,
}),
);
const engine = Object.assign(new EventEmitter(), {
isClosed: false,
logContext: {},
client: {currentState: SignalConnectionState.CONNECTED, sendUpdateLocalAudioTrack},
pcManager: {publisher: {getTransceivers: () => [transceiver], setTrackCodecBitrate}},
createSender: vi.fn(async () => sender),
negotiate: vi.fn(async () => undefined),
addTrack,
});
type ParticipantArgs = ConstructorParameters<typeof LocalParticipant>;
const participant = new LocalParticipant(
'PA_publisher',
'publisher',
engine as unknown as RTCEngine,
{...roomOptionDefaults, publishDefaults},
{} as ParticipantArgs[4],
{} as ParticipantArgs[5],
{} as ParticipantArgs[6],
{} as ParticipantArgs[7],
);
participant.permissions = new ParticipantPermission({canPublish: true});
return {participant, addTrack, setTrackCodecBitrate, sendUpdateLocalAudioTrack};
}
describe('microphone publication stereo metadata', () => {
beforeEach(() => {
vi.stubGlobal('MediaStreamTrack', TestMediaStreamTrack);
vi.stubGlobal('MediaStream', TestMediaStream);
});
afterEach(() => {
vi.unstubAllGlobals();
});
it.each([
{name: 'mono policy on a two-channel device', channelCount: 2, forceStereo: false, stereo: false},
{name: 'automatic stereo on a two-channel device', channelCount: 2, forceStereo: undefined, stereo: true},
{name: 'forced stereo on a one-channel device', channelCount: 1, forceStereo: true, stereo: true},
{name: 'automatic mono on a one-channel device', channelCount: 1, forceStereo: undefined, stereo: false},
])(
'keeps the request, SDP policy, and feature updates consistent for $name',
async ({channelCount, forceStereo, stereo}) => {
const {participant, addTrack, setTrackCodecBitrate, sendUpdateLocalAudioTrack} = createPublisher();
const source = new TestMediaStreamTrack(channelCount);
const track = new LocalAudioTrack(source as unknown as MediaStreamTrack);
track.source = Track.Source.Microphone;
await track.runWithTrackChangeLock(async () => undefined);
const publication = await participant.publishTrack(track, {
audioPreset: {maxBitrate: 64000},
forceStereo,
});
expect(addTrack).toHaveBeenCalledTimes(1);
const request = addTrack.mock.calls[0]![0];
expect(request.stereo).toBe(stereo);
expect(request.audioFeatures.includes(AudioTrackFeature.TF_STEREO)).toBe(stereo);
expect(request.audioFeatures).toContain(AudioTrackFeature.TF_ECHO_CANCELLATION);
expect(setTrackCodecBitrate).toHaveBeenCalledWith(expect.objectContaining({codec: 'opus', maxbr: 64, stereo}));
expect(publication.getTrackFeatures().includes(AudioTrackFeature.TF_STEREO)).toBe(stereo);
track.emit(TrackEvent.AudioTrackFeatureUpdate, track, AudioTrackFeature.TF_ECHO_CANCELLATION, true);
expect(sendUpdateLocalAudioTrack).toHaveBeenCalledTimes(1);
const [sid, features] = sendUpdateLocalAudioTrack.mock.calls[0]!;
expect(sid).toBe('TR_microphone');
expect(features.includes(AudioTrackFeature.TF_STEREO)).toBe(stereo);
expect(features).toContain(AudioTrackFeature.TF_ECHO_CANCELLATION);
track.stop();
},
);
});
@@ -966,7 +966,7 @@ export default class LocalParticipant extends Participant {
if (settings.noiseSuppression) {
audioFeatures.push(AudioTrackFeature.TF_NOISE_SUPPRESSION);
}
if (settings.channelCount && settings.channelCount > 1) {
if (isStereo) {
audioFeatures.push(AudioTrackFeature.TF_STEREO);
}
if (disableDtx) {
@@ -90,7 +90,7 @@ export default class LocalTrackPublication extends TrackPublication {
if (settings.noiseSuppression) {
features.add(AudioTrackFeature.TF_NOISE_SUPPRESSION);
}
if (settings.channelCount && settings.channelCount > 1) {
if (this.options?.forceStereo ?? (settings.channelCount !== undefined && settings.channelCount > 1)) {
features.add(AudioTrackFeature.TF_STEREO);
}
if (!this.options?.dtx) {
@@ -135,8 +135,7 @@ export const PlutoniumContent = observer(({defaultGiftMode = false}: PlutoniumCo
title={<Trans>Cancel subscription?</Trans>}
description={
<Trans>
You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep
your subscriber history.
You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history.
</Trans>
}
primaryText={<Trans>Cancel subscription</Trans>}
@@ -463,6 +463,22 @@ export const SubscriptionCard: React.FC<SubscriptionCardProps> = observer(
</Trans>
);
})()
) : gracePeriodInfo.isPaymentRecovery ? (
(() => {
const graceDate = graceEndDate ? getFormattedLongDate(graceEndDate, locale) : undefined;
return (
<Trans comment="Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.">
Your renewal payment failed but{' '}
<PerksButton
onClick={scrollToPerks}
data-flx="app.plutonium.subscription-card.perks-button.scroll-to-perks--9"
/>{' '}
stay active until{' '}
<strong data-flx="app.plutonium.subscription-card.strong--16">{graceDate}</strong>. Update your
payment method before then to keep your subscription.
</Trans>
);
})()
) : isInGracePeriod ? (
(() => {
const graceDate = graceEndDate ? getFormattedLongDate(graceEndDate, locale) : undefined;
@@ -844,7 +860,7 @@ export const SubscriptionCard: React.FC<SubscriptionCardProps> = observer(
<Trans comment="Billing button that starts subscription cancellation.">Cancel subscription</Trans>
</Button>
)}
{isInGracePeriod && (
{isInGracePeriod && !gracePeriodInfo.isPaymentRecovery && (
<Button
variant="danger"
onClick={handleEndPremiumGracePeriod}
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import DeveloperOptions from '@app/features/devtools/state/DeveloperOptions';
import {getPremiumGraceEndDate} from '@app/features/premium/utils/PremiumGrace';
import type {User} from '@app/features/user/models/User';
import {UserPremiumTypes} from '@fluxer/constants/src/UserConstants';
import {MS_PER_DAY} from '@fluxer/date_utils/src/DateConstants';
@@ -12,6 +13,7 @@ export interface GracePeriodInfo {
isExpired: boolean;
graceEndDate: Date | null;
showExpiredState: boolean;
isPaymentRecovery: boolean;
}
export interface SubscriptionStatusInfo {
@@ -82,13 +84,25 @@ export const useSubscriptionStatus = (
const isGiftSubscription = Boolean(!billingCycle && hasPaidPremium && !isVisionary && premiumUntil);
const gracePeriodInfo = useMemo((): GracePeriodInfo => {
if (isVisionary) {
return {isInGracePeriod: false, isExpired: false, graceEndDate: null, showExpiredState: false};
return {
isInGracePeriod: false,
isExpired: false,
graceEndDate: null,
showExpiredState: false,
isPaymentRecovery: false,
};
}
const explicitGraceEnd = premiumGraceEndsAt ?? null;
const expiryDate = premiumUntil ? new Date(premiumUntil) : null;
const graceEndDate = explicitGraceEnd ?? (expiryDate ? new Date(expiryDate.getTime() + 3 * MS_PER_DAY) : null);
const graceEndDate = expiryDate ? getPremiumGraceEndDate(expiryDate, explicitGraceEnd) : explicitGraceEnd;
if (!graceEndDate) {
return {isInGracePeriod: false, isExpired: false, graceEndDate: null, showExpiredState: false};
return {
isInGracePeriod: false,
isExpired: false,
graceEndDate: null,
showExpiredState: false,
isPaymentRecovery: false,
};
}
const now = new Date();
const anchorDate = expiryDate ?? graceEndDate;
@@ -96,8 +110,9 @@ export const useSubscriptionStatus = (
const isInGracePeriod = (!expiryDate || now > expiryDate) && now <= graceEndDate;
const isExpired = now > graceEndDate;
const showExpiredState = isExpired && now <= expiredStateEndDate;
return {isInGracePeriod, isExpired, graceEndDate, showExpiredState};
}, [premiumUntil, premiumGraceEndsAt, isVisionary]);
const isPaymentRecovery = isInGracePeriod && explicitGraceEnd != null && billingCycle != null;
return {isInGracePeriod, isExpired, graceEndDate, showExpiredState, isPaymentRecovery};
}, [premiumUntil, premiumGraceEndsAt, isVisionary, billingCycle]);
const {isInGracePeriod, isExpired: isFullyExpired, showExpiredState} = gracePeriodInfo;
const isPremium = useDeveloperOverride
? hasPaidPremium && !isFullyExpired && !perksDisabled
@@ -21,6 +21,7 @@ import * as NotificationUtils from '@app/features/notification/utils/Notificatio
import NativePermission from '@app/features/permissions/system/state/NativePermission';
import {resolvePriceAnnouncementCampaign} from '@app/features/premium/config/PriceAnnouncementCampaign';
import PremiumState from '@app/features/premium/state/PremiumState';
import {getPremiumGraceEndDate} from '@app/features/premium/utils/PremiumGrace';
import {canServiceStripeSubscriptions, shouldShowPremiumFeatures} from '@app/features/premium/utils/PremiumUtils';
import StreamerMode from '@app/features/streamer_mode/state/StreamerMode';
import Nagbar from '@app/features/ui/state/Nagbar';
@@ -117,14 +118,11 @@ export const useNagbarConditions = (): NagbarConditions => {
if (!showPremium || !canServiceSubscription) return false;
if (nagbarState.forceHidePremiumGracePeriod) return false;
if (nagbarState.forcePremiumGracePeriod) return true;
if (!user?.premiumUntil || user.premiumType === 2 || premiumWillCancel) return false;
if (!user?.premiumUntil || !user.premiumGraceEndsAt || !user.premiumBillingCycle || user.premiumType === 2) {
return false;
}
const now = new Date();
const expiryDate = new Date(user.premiumUntil);
const gracePeriodMs = 3 * MS_PER_DAY;
const graceEndDate = user.premiumGraceEndsAt
? new Date(user.premiumGraceEndsAt)
: new Date(expiryDate.getTime() + gracePeriodMs);
const isInGracePeriod = now > expiryDate && now <= graceEndDate;
const isInGracePeriod = now > new Date(user.premiumUntil) && now <= new Date(user.premiumGraceEndsAt);
return isInGracePeriod && !nagbarState.premiumGracePeriodDismissed;
})();
const canShowPremiumExpired = (() => {
@@ -134,11 +132,8 @@ export const useNagbarConditions = (): NagbarConditions => {
if (!user?.premiumUntil || user.premiumType === 2 || premiumWillCancel) return false;
const now = new Date();
const expiryDate = new Date(user.premiumUntil);
const gracePeriodMs = 3 * MS_PER_DAY;
const expiredStateDurationMs = 30 * MS_PER_DAY;
const graceEndDate = user.premiumGraceEndsAt
? new Date(user.premiumGraceEndsAt)
: new Date(expiryDate.getTime() + gracePeriodMs);
const graceEndDate = getPremiumGraceEndDate(expiryDate, user.premiumGraceEndsAt);
const expiredStateEndDate = new Date(graceEndDate.getTime() + expiredStateDurationMs);
const isExpired = now > graceEndDate;
const showExpiredState = isExpired && now <= expiredStateEndDate;
@@ -8,12 +8,12 @@ import {NAGBAR_TONES, NagbarToneKind} from '@app/features/app/components/layout/
import {PREMIUM_PRODUCT_NAME} from '@app/features/app/config/I18nDisplayConstants';
import {Logger} from '@app/features/platform/utils/AppLogger';
import * as PremiumCommands from '@app/features/premium/commands/PremiumCommands';
import {getPremiumGraceEndDate} from '@app/features/premium/utils/PremiumGrace';
import {MANAGE_SUBSCRIPTION_DESCRIPTOR} from '@app/features/premium/utils/PremiumMessageDescriptors';
import * as NagbarCommands from '@app/features/ui/commands/NagbarCommands';
import {openExternalUrl} from '@app/features/ui/utils/NativeUtils';
import Users from '@app/features/user/state/Users';
import * as LocaleUtils from '@app/features/user/utils/LocaleUtils';
import {MS_PER_DAY} from '@fluxer/date_utils/src/DateConstants';
import {getFormattedLongDate} from '@fluxer/date_utils/src/DateFormatting';
import {msg} from '@lingui/core/macro';
import {useLingui} from '@lingui/react/macro';
@@ -62,10 +62,8 @@ export const PremiumGracePeriodNagbar = observer(({isMobile}: {isMobile: boolean
const handleDismiss = () => {
NagbarCommands.dismissNagbar('premiumGracePeriodDismissed');
};
if (!user?.premiumUntil || user?.premiumWillCancel) return null;
const expiryDate = new Date(user.premiumUntil);
const gracePeriodMs = 3 * MS_PER_DAY;
const graceEndDate = new Date(expiryDate.getTime() + gracePeriodMs);
if (!user?.premiumUntil) return null;
const graceEndDate = getPremiumGraceEndDate(new Date(user.premiumUntil), user.premiumGraceEndsAt);
const locale = LocaleUtils.getCurrentLocale();
const formattedGraceDate = getFormattedLongDate(graceEndDate, locale);
return (
@@ -111,6 +111,7 @@ export const DEFAULT_INSTANCE_COMMUNITY: InstanceCommunity = {
single_community: false,
single_community_guild_id: null,
direct_messages_disabled: false,
guild_create_access: true,
};
export function normalizeInstanceCommunity(community?: InstanceCommunity | null): InstanceCommunity {
@@ -402,6 +403,7 @@ class RuntimeConfig {
? config.policy.single_community_guild_id
: null,
direct_messages_disabled: config.policy.direct_messages_disabled,
guild_create_access: config.policy.guild_create_access,
});
this.services = normalizeInstanceServices({
gif_enabled: config.policy.services_resolved.gif_enabled,
@@ -20,6 +20,7 @@ import {handleGuildCountsUpdate} from '@app/features/guild/events/GuildCountsUpd
import {handleGuildCreate} from '@app/features/guild/events/GuildCreate';
import {handleGuildDelete} from '@app/features/guild/events/GuildDelete';
import {handleGuildEmojisUpdate} from '@app/features/guild/events/GuildEmojisUpdate';
import {handleGuildHealthUpdate} from '@app/features/guild/events/GuildHealthUpdate';
import {handleGuildMemberAdd} from '@app/features/guild/events/GuildMemberAdd';
import {handleGuildMemberListUpdate} from '@app/features/guild/events/GuildMemberListUpdate';
import {handleGuildMemberRemove} from '@app/features/guild/events/GuildMemberRemove';
@@ -112,6 +113,7 @@ export function createHandlerRegistry(): GatewayHandlerRegistry {
registry.set('GUILD_MEMBERS_CHUNK', handleGuildMembersChunk as GatewayEventHandler);
registry.set('GUILD_MEMBER_LIST_UPDATE', handleGuildMemberListUpdate as GatewayEventHandler);
registry.set('GUILD_COUNTS_UPDATE', handleGuildCountsUpdate as GatewayEventHandler);
registry.set('GUILD_HEALTH_UPDATE', handleGuildHealthUpdate as GatewayEventHandler);
registry.set('CHANNEL_MEMBER_COUNTS_UPDATE', handleChannelMemberCountsUpdate as GatewayEventHandler);
registry.set('GUILD_ROLE_CREATE', handleGuildRoleCreate as GatewayEventHandler);
registry.set('GUILD_ROLE_UPDATE', handleGuildRoleUpdate as GatewayEventHandler);
@@ -23,4 +23,5 @@ export type GuildReadyData = Readonly<{
joined_at: string;
unavailable?: boolean;
unavailable_hidden?: boolean;
degraded?: boolean;
}>;
@@ -48,6 +48,9 @@ export function handleGuildCreate(data: GuildReadyData, _context: GatewayHandler
return;
}
GuildAvailability.setGuildAvailable(data.id);
if (!isSync || data.degraded !== undefined) {
GuildAvailability.setGuildDegraded(data.id, data.degraded === true);
}
Guilds.handleGuildCreate(data);
GuildCount.handleGuildCreate(data);
if (!isSync) {
@@ -32,6 +32,7 @@ interface GuildDeletePayload {
}
export function handleGuildDelete(data: GuildDeletePayload, _context: GatewayHandlerContext): void {
GuildAvailability.setGuildDegraded(data.id, false);
GuildAvailability.handleGuildAvailability(data.id, data.unavailable, data.unavailable_hidden);
Guilds.handleGuildDelete({guildId: data.id, unavailable: data.unavailable});
GuildList.handleGuildDelete(data.id, data.unavailable);
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import GuildAvailability from '@app/features/guild/state/GuildAvailability';
import Guilds from '@app/features/guild/state/Guilds';
export function handleGuildHealthUpdate(data: {guild_id: string; degraded: boolean}): void {
if (Guilds.getGuild(data.guild_id)) {
GuildAvailability.setGuildDegraded(data.guild_id, data.degraded);
}
}
@@ -5,12 +5,14 @@ import {makeAutoObservable, observable} from 'mobx';
class GuildAvailability {
unavailableGuilds: Set<string> = observable.set();
degradedGuilds: Set<string> = observable.set();
constructor() {
makeAutoObservable(
this,
{
unavailableGuilds: false,
degradedGuilds: false,
},
{autoBind: true},
);
@@ -23,11 +25,20 @@ class GuildAvailability {
}
setGuildUnavailable(guildId: string): void {
this.degradedGuilds.delete(guildId);
if (!this.unavailableGuilds.has(guildId)) {
this.unavailableGuilds.add(guildId);
}
}
setGuildDegraded(guildId: string, degraded: boolean): void {
if (degraded) {
this.degradedGuilds.add(guildId);
} else {
this.degradedGuilds.delete(guildId);
}
}
handleGuildAvailability(guildId: string, unavailable = false, unavailableHidden = false): void {
if (unavailable && !unavailableHidden) {
this.setGuildUnavailable(guildId);
@@ -38,7 +49,11 @@ class GuildAvailability {
loadUnavailableGuilds(guilds: ReadonlyArray<GuildReadyData>): void {
this.unavailableGuilds.clear();
this.degradedGuilds.clear();
for (const guild of guilds) {
if (guild.degraded && !guild.unavailable) {
this.degradedGuilds.add(guild.id);
}
if (guild.unavailable && !guild.unavailable_hidden) {
this.unavailableGuilds.add(guild.id);
}
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "يتوفر تحديث لتطبيق سطح المكتب على Linux. اختر تنسيق الحزمة لهذا النظام وسيحفظه {productName} محليًا."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "يتوفر سعر أقل. يسري التبديل اعتبارًا من <0>{listPriceEffectiveDate}</0> ولا يغيّر أي شيء آخر."
@@ -2639,7 +2639,7 @@ msgstr "الوصول إلى معلومات ملفك الشخصي الأساسي
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. User settings tab for accessibility preferences (visual, motion, screen reader, etc.).
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:14
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/SettingsConstants.tsx:61
msgid "Accessibility"
msgstr "إمكانية الوصول"
@@ -3487,19 +3487,19 @@ msgstr "عناصر التحكم في المحاذاة متاحة فقط على
msgid "All"
msgstr "الكل"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "جميع <0/> مقابل <1>{effectiveMonthlyPrice} شهريًا</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "جميع <0/> مقابل <1>{effectiveYearlyPrice} سنويًا</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "جميع <0/> مشمولة في اشتراكك."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "جميع <0/> للأبد. بلا فواتير ولا تجديدات."
@@ -4706,7 +4706,7 @@ msgstr "المرفقات"
#. Generic tab / section / category label for audio content or settings.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:255
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:179
msgid "Audio"
msgstr "الصوت"
@@ -6210,7 +6210,7 @@ msgid "California"
msgstr "كاليفورنيا"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
msgid "Call"
msgstr "مكالمة"
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "إلغاء الاستيراد"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "إلغاء تغيير السعر"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "إلغاء الطلب"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "إلغاء التبديل المجدول"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "إلغاء الاشتراك"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "هل تريد إلغاء الاشتراك؟"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "ألغِ التغيير المجدول للانتقال إلى السعر الحالي بدلاً من ذلك."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "إلغاء التحميل"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "إلغاء الترقية السنوية"
@@ -6530,7 +6530,7 @@ msgstr "سيتم الإلغاء"
msgid "Cancellation"
msgstr "إلغاء الصدى"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "سيتم الإلغاء في <0>{cancelDate}</0>. تظل <1/> سارية حتى ذلك الحين."
@@ -7088,7 +7088,7 @@ msgid "Channel"
msgstr "القناة"
#. Fallback name for an unnamed channel in the forward modal destination list. Preserve {id}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:78
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:79
msgid "Channel {id}"
msgstr "القناة {id}"
@@ -7317,7 +7317,7 @@ msgid "Chat font size"
msgstr "حجم خط الدردشة"
#. Settings search synonym. Refers to the message composer area.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
msgid "chat input"
msgstr "مربع الكتابة"
@@ -8726,7 +8726,7 @@ msgid "Community updated"
msgstr "تم تحديث المجتمع"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:35
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:38
msgid "Community voice"
msgstr "صوت المجتمع"
@@ -8789,12 +8789,13 @@ msgstr "أكمل عملية التحقق المطلوبة لمتابعة است
msgid "Completely hide your {premiumProductName} badge from other users"
msgstr "إخفاء شارة {premiumProductName} الخاصة بك بالكامل عن المستخدمين الآخرين"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:134
#: src/features/auth/components/pages/SsoCallbackPage.tsx:118
#: src/features/auth/components/pages/SsoCallbackPage.tsx:168
#: src/features/auth/flow/HandoffApprovalFlow.tsx:218
msgid "Completing sign-in…"
msgstr "جارٍ إكمال تسجيل الدخول…"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:138
#: src/features/auth/components/pages/SsoCallbackPage.tsx:172
msgid "Completing your sign-in…"
msgstr "جارٍ إكمال تسجيل دخولك…"
@@ -8912,8 +8913,8 @@ msgstr "تأكيد"
#. Settings search entry label. Names the settings search entry in the settings UI.
#. Short label for an advanced voice-channel safety preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:21
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:15
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:24
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:18
msgid "Confirm before joining voice channels"
msgstr "التأكيد قبل الانضمام إلى القنوات الصوتية"
@@ -8952,7 +8953,7 @@ msgstr "تأكيد كلمة المرور"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:27
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:30
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:398
msgid "Confirm voice join"
msgstr "تأكيد الانضمام إلى الصوت"
@@ -8963,7 +8964,7 @@ msgid "Confirmation"
msgstr "تأكيد"
#. Settings search entry description. One-line summary of what the settings search entry controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:43
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:46
msgid "Confirmation or double-click for community voice joins"
msgstr "التأكيد أو النقر المزدوج للانضمام إلى القنوات الصوتية في المجتمعات"
@@ -9200,7 +9201,7 @@ msgstr "بوابات سلامة المحتوى"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/ui/action_menu/ContextMenu.tsx:23
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:225
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
msgid "Context menu"
msgstr "قائمة السياق"
@@ -10871,7 +10872,7 @@ msgstr "مخصص…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "بوابة العملاء"
@@ -11341,7 +11342,7 @@ msgstr "ديلاوير"
#: src/features/user/components/modals/tabs/component_gallery_tab/ComponentGalleryTabButtonsTab.tsx:290
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:238
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:174
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
msgid "Delete"
msgstr "حذف"
@@ -11626,7 +11627,7 @@ msgid "Deleted {duration} of the member's recent message history"
msgstr "تم حذف {duration} من سجل رسائل العضو الحديثة"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
msgid "Deleted text"
msgstr "نص محذوف"
@@ -12028,7 +12029,7 @@ msgid "Different sizes & member counts"
msgstr "أحجام وأعداد أعضاء مختلفة"
#. Toggle label and settings search entry for slightly muting text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:106
msgid "Dim strikethrough text"
msgstr "تعتيم النص المشطوب"
@@ -12043,7 +12044,7 @@ msgstr "إدخال مباشر"
#: src/features/channel/components/bottomsheets/channel_details_bottom_sheet/ChannelDetailsBottomSheetShared.ts:14
#: src/features/channel/components/channel_header_components/developer_tools/MockingMenu.tsx:398
#: src/features/i18n/utils/CommonMessageDescriptors.ts:567
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
msgid "Direct message"
msgstr "رسالة مباشرة"
@@ -12480,7 +12481,7 @@ msgid "District of Columbia"
msgstr "مقاطعة كولومبيا"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:180
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
msgid "DM"
msgstr "رسالة مباشرة"
@@ -12735,6 +12736,16 @@ msgstr "تنزيل {productName}"
msgid "Download <0>fluxer-verification</0> and place it in your <1>.well-known</1> folder so we can validate the domain."
msgstr "نزّل <0>fluxer-verification</0> وضعه في مجلد <1>.well-known</1> حتى نتمكن من التحقق من النطاق."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:98
msgid "Download app"
msgstr "تنزيل التطبيق"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:106
msgid "Download app button in the sidebar"
msgstr "تنزيل التطبيق"
#. Media context menu action that downloads an audio attachment.
#: src/features/ui/action_menu/items/MediaMenuData.tsx:122
msgid "Download audio"
@@ -13433,7 +13444,7 @@ msgstr "تم إظهار التضمينات"
#: src/features/app/config/AuditLogConstants.ts:167
#: src/features/emoji/components/emojis/EmojiListItem.tsx:337
#: src/features/theme_studio/sections/TokenGroups.ts:114
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
msgid "Emoji"
msgstr "رمز تعبيري"
@@ -13866,15 +13877,15 @@ msgid "End date"
msgstr "تاريخ الانتهاء"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "إنهاء فترة السماح الآن"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "إنهاء فترة السماح"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "إنهاء فترة السماح الآن؟"
@@ -14681,7 +14692,7 @@ msgid "Failed to clear trusted domains."
msgstr "تعذّر مسح النطاقات الموثوقة."
#. Short label in the authentication SSO callback page. Keep the tone plain and specific.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:28
#: src/features/auth/components/pages/SsoCallbackPage.tsx:30
msgid "Failed to complete SSO sign-in"
msgstr "تعذّر إكمال تسجيل الدخول الموحّد (SSO)"
@@ -15027,7 +15038,7 @@ msgid "Favorite channel"
msgstr "إضافة القناة إلى المفضلة"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:79
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:82
msgid "Favorite channels"
msgstr "القنوات المفضلة"
@@ -15800,7 +15811,7 @@ msgstr "بوت يقبل الصداقة"
#: src/features/connection/components/modals/EditConnectionModal.tsx:86
#: src/features/search/utils/QuickSwitcherModalUtils.tsx:50
#: src/features/user/components/modals/tabs/my_profile_tab/TimezoneProfileSettings.tsx:63
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
msgid "Friends"
msgstr "الأصدقاء"
@@ -16145,7 +16156,7 @@ msgstr "احصل على تطبيق {productName} الجديد"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Type label for GIF media.
#: src/features/expressions/utils/FavoriteMemeUtils.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
msgid "GIF"
msgstr "GIF"
@@ -16336,7 +16347,7 @@ msgstr "هدية: تنتهي صلاحيتها قريبًا"
msgid "Gift: grace period (still have access)"
msgstr "هدية: فترة سماح (لا يزال لديك حق الوصول)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "<0/> مُهدى حتى <1>{giftEndDate}</1>. لا يتجدد تلقائيًا. استرد المزيد من رموز الهدايا لتمديده."
@@ -16549,7 +16560,7 @@ msgid "Graphics"
msgstr "الرسومات"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
msgid "Gray text"
msgstr "نص رمادي"
@@ -16815,7 +16826,7 @@ msgid "Hate speech"
msgstr "خطاب الكراهية"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "هل لديك رمز هدية؟ استبدله لفتح {PREMIUM_PRODUCT_NAME}."
@@ -16896,11 +16907,21 @@ msgstr "مرحباً، {username}! سعيدون بوجودك معنا."
msgid "Help"
msgstr "مساعدة"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:94
msgid "Help button"
msgstr "زر المساعدة"
#. Short label in the sidebar navigation help button.
#: src/features/app/components/layout/sidebar_nav/HelpButton.tsx:27
msgid "Help center"
msgstr "مركز المساعدة"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:102
msgid "Help center button in the sidebar"
msgstr "مركز المساعدة"
#: src/features/user/components/modals/tabs/LanguageTab.tsx:348
msgid "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
msgstr "ساعد في ترجمة {PRODUCT_NAME} إلى لغتك على <0>{I18N_WEBLATE_DOMAIN}</0>."
@@ -17035,7 +17056,7 @@ msgid "Hide join messages"
msgstr "إخفاء رسائل الانضمام"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:47
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:50
msgid "Hide keyboard hints"
msgstr "إخفاء تلميحات لوحة المفاتيح"
@@ -18721,7 +18742,7 @@ msgstr "الانضمام إلى مكالمة الفيديو"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/profile/VoiceActivityCard.tsx:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:31
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:34
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:454
msgid "Join voice"
msgstr "الانضمام إلى المحادثة الصوتية"
@@ -18764,6 +18785,7 @@ msgstr "التنقل بين القنوات غير المقروءة"
msgid "Jump between unread channels with mentions"
msgstr "التنقل بين القنوات غير المقروءة التي تحتوي على إشارات"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:121
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:75
msgid "Jump straight to the app to continue."
msgstr "انتقل مباشرة إلى التطبيق للمتابعة."
@@ -18904,7 +18926,7 @@ msgstr "الاحتفاظ بالمرفقات عند إفراغ نص الرسال
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "حافظ على المستويات المجانية والمدفوعة. يمكنك تخصيص المستويات، أو البيع عبر Stripe، أو توزيع رموز هدايا لاحقًا من لوحة التحكم."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "الاحتفاظ بفترة السماح"
@@ -18918,7 +18940,7 @@ msgstr "إبقاء Neko ثابتًا"
msgid "Keep running"
msgstr "مواصلة التشغيل"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "الاحتفاظ بالاشتراك"
@@ -18980,7 +19002,7 @@ msgid "Keyboard mode"
msgstr "وضع لوحة المفاتيح"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:59
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:62
msgid "Keyboard shortcut hints in tooltips"
msgstr "إظهار اختصارات لوحة المفاتيح في التلميحات"
@@ -19275,8 +19297,8 @@ msgstr "زر الفأرة الأيسر"
msgid "Left tooltip"
msgstr "تلميح لليسار"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "السعر القديم"
@@ -20094,7 +20116,7 @@ msgstr "وضع علامة على أعلى قناة في صندوق الوارد
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:364
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
msgid "Markdown"
msgstr "تنسيق ماركداون"
@@ -20644,7 +20666,7 @@ msgstr "هل تريد الإشارة إلى هذا الدور؟"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/guild/components/modals/GuildNotificationSettingsModal.tsx:136
#: src/features/i18n/utils/CommonMessageDescriptors.ts:648
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
msgid "Mentions"
msgstr "الإشارات"
@@ -21158,7 +21180,7 @@ msgid "Missing client_id"
msgstr "client_id مفقود"
#. SSO callback page error shown when the SSO callback is missing code or state parameters.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:24
#: src/features/auth/components/pages/SsoCallbackPage.tsx:26
msgid "Missing SSO code. Sign in again."
msgstr "رمز تسجيل الدخول الموحّد مفقود. سجّل الدخول مرة أخرى."
@@ -21317,11 +21339,11 @@ msgstr "شهريًا"
msgid "Monthly {monthlyPrice}"
msgstr "شهريًا {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "تبدأ الفوترة الشهرية في <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "تبدأ الفوترة الشهرية في <0>{pendingChangeDate}</0>. أول رسوم شهرية: {pendingInitialPriceLabel}. التجديدات الشهرية اللاحقة: {pendingRecurringPriceLabel}/شهر."
@@ -21756,7 +21778,7 @@ msgstr "مكتوم"
#. Status label indicating the surface is currently muted.
#: src/features/app/components/layout/sidebar_nav/UseGuildListItemState.ts:23
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:491
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/lib/overlay/OverlayContextMenu.tsx:24
msgid "Muted"
msgstr "مكتوم"
@@ -21779,7 +21801,7 @@ msgstr "مكتوم الصوت من المشرفين"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:495
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
msgid "Muted channels"
msgstr "القنوات المكتومة"
@@ -21992,7 +22014,7 @@ msgid "Narrates only the channel you're viewing. Narration follows you between c
msgstr "يقرأ رسائل القناة التي تشاهدها فقط. تنتقل القراءة معك بين القنوات."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
msgid "Narration"
msgstr "السرد"
@@ -22057,12 +22079,12 @@ msgid "Need an account?"
msgstr "هل تحتاج إلى حساب؟"
#. Settings search synonym. Proper name of the optional cat sprite that chases the cursor.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
msgid "Neko"
msgstr "نيكو"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:63
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:66
msgid "Neko cat that chases your cursor"
msgstr "قط نيكو يطارد مؤشر الفأرة"
@@ -22247,12 +22269,12 @@ msgid "New password"
msgstr "كلمة مرور جديدة"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "من المقرر تطبيق سعر جديد في <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "من المقرر تطبيق سعر جديد في <0>{pendingChangeDate}</0>. سيكون التجديد بسعر {pendingTargetPriceLabel} من ذلك الحين فصاعدًا."
@@ -23560,6 +23582,8 @@ msgid "Open {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName}
msgstr "افتح {macosSystemSettingsName} ← {macosPrivacyAndSecuritySettingsName} ← {macosScreenRecordingPermissionName}، ثم اسمح لـ {productName}. إذا كان {productName2} مفعّلًا بالفعل، فأغلقه تمامًا ثم أعد تشغيل {productName3} حتى يطبّق macOS الإذن."
#. Button label that opens the desktop app. productName is the app name.
#. Button that hands SSO sign-in back to the mobile app. productName is the app name.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:34
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:27
msgid "Open {productName}"
msgstr "فتح {productName}"
@@ -24945,7 +24969,7 @@ msgstr "ثبّت هذه الرسالة في القناة ليراها الجمي
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Voice stats field label (mobile lobby). Shows current latency in ms.
#. Voice stats field label (mobile voice lobby). Shows current latency in ms.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:184
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/voice/components/bottomsheets/DirectCallLobbyBottomSheet.tsx:118
#: src/features/voice/components/bottomsheets/VoiceLobbyBottomSheet.tsx:86
msgid "Ping"
@@ -25165,7 +25189,7 @@ msgid "Popped out"
msgstr "في نافذة منفصلة"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:204
msgid "Popup"
msgstr "نافذة منبثقة"
@@ -26128,7 +26152,7 @@ msgstr "التفاعلات"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "إعادة التفعيل"
@@ -26139,7 +26163,7 @@ msgid "Reactivate subscription"
msgstr "إعادة تفعيل الاشتراك"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
msgid "Read aloud"
msgstr "قراءة بصوت عالٍ"
@@ -26156,7 +26180,7 @@ msgstr "قراءة سجل الرسائل"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:177
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
msgid "Read messages"
msgstr "قراءة الرسائل"
@@ -26351,8 +26375,8 @@ msgstr "استرداد لنفسك"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "استرداد رمز الهدية"
@@ -26630,7 +26654,7 @@ msgstr "تذكر حجم النافذة وموضعها"
#: src/features/user/components/modals/tabs/chat_settings_tab/SearchEnginesTab.tsx:26
#: src/features/user/components/modals/tabs/LinkedAccountsTab.tsx:55
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:178
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:200
#: src/features/webhook/components/WebhookListItem.tsx:277
msgid "Remove"
msgstr "إزالة"
@@ -27123,7 +27147,7 @@ msgstr "عتبة التجديد (بالأيام)"
msgid "Renew window (days)"
msgstr "فترة التجديد (بالأيام)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "يتجدد في <0>{renewalDate}.</0>"
@@ -27321,7 +27345,7 @@ msgid "Require a passkey as your second factor"
msgstr "طلب مفتاح مرور كعامل ثانٍ"
#. Short label for an advanced voice-channel navigation preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:17
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:20
msgid "Require double-click to join voice channels"
msgstr "اشتراط النقر المزدوج للانضمام إلى القنوات الصوتية"
@@ -27872,8 +27896,8 @@ msgstr "استعادة النافذة"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "إعادة الاشتراك"
@@ -29578,7 +29602,7 @@ msgid "Sending malware or dangerous links"
msgstr "إرسال برامج ضارة أو روابط خطيرة"
#. Short label under a destination row in the forward modal, shown when the community has messaging disabled.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:54
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:55
msgid "Sending messages is disabled in this community"
msgstr "تم تعطيل إرسال الرسائل في هذا المجتمع"
@@ -30120,7 +30144,7 @@ msgstr "اختصار"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:55
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:58
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:370
msgid "Shortcut badges"
msgstr "شارات الاختصارات"
@@ -30280,7 +30304,9 @@ msgid "Show delete button"
msgstr "إظهار زر الحذف"
#. Short label for an advanced media button preference.
#. Toggle label and settings search entry for showing the download app button in the sidebar.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:76
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
msgid "Show download button"
msgstr "إظهار زر التنزيل"
@@ -30322,7 +30348,7 @@ msgid "Show favorite button"
msgstr "إظهار زر المفضلة"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:87
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:90
msgid "Show favorites throughout the app"
msgstr "إظهار العناصر المفضلة في جميع أنحاء التطبيق"
@@ -30350,6 +30376,11 @@ msgstr "إظهار مؤشر GIF"
msgid "Show GIFs button"
msgstr "إظهار زر صور GIF"
#. Toggle label and settings search entry for showing the help center button in the sidebar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
msgid "Show help center button"
msgstr "إظهار زر مركز المساعدة"
#. Switch label in the community-folder settings modal. When on, the folder icon is shown in the sidebar while the folder is collapsed.
#: src/features/guild/components/modals/GuildFolderSettingsModal.tsx:77
msgid "Show icon when collapsed"
@@ -30565,7 +30596,7 @@ msgid "Show stickers in expression autocomplete"
msgstr "إظهار الملصقات في الإكمال التلقائي للتعبيرات"
#. Description for a visual accessibility setting that mutes the color of text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:110
msgid "Show strikethrough Markdown text in a slightly muted color."
msgstr "إظهار نص Markdown المشطوب بلون باهت قليلًا."
@@ -31008,7 +31039,7 @@ msgid "Slowmode"
msgstr "الوضع البطيء"
#. Short label under a destination row in the forward modal while slowmode blocks sending. Preserve {remaining}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:73
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:74
msgid "Slowmode · wait {remaining}"
msgstr "الوضع البطيء · انتظر {remaining}"
@@ -31559,7 +31590,7 @@ msgstr "المشاهدون - {count}"
#. Native macOS Edit submenu title for text-to-speech actions.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/platform/utils/DesktopLocaleBridge.ts:85
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
msgid "Speech"
msgstr "الكلام"
@@ -31670,12 +31701,12 @@ msgstr "أزرار أيقونات مربعة"
msgid "SSO is required to access this workspace."
msgstr "تتطلب مساحة العمل هذه تسجيل الدخول الموحّد (SSO)."
#: src/features/auth/components/pages/SsoCallbackPage.tsx:105
#: src/features/auth/components/pages/SsoCallbackPage.tsx:139
msgid "SSO sign-in failed"
msgstr "فشل تسجيل الدخول الموحّد"
#. SSO callback page error shown when the SSO sign-in timed out before the callback arrived.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:20
#: src/features/auth/components/pages/SsoCallbackPage.tsx:22
msgid "SSO sign-in timed out. Try again."
msgstr "انتهت مهلة تسجيل الدخول الموحّد (SSO). حاول مرة أخرى."
@@ -31714,7 +31745,7 @@ msgid "Star animation"
msgstr "رسوم متحركة للنجمة"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:83
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:86
msgid "Starred channels"
msgstr "القنوات المميزة بنجمة"
@@ -31791,7 +31822,7 @@ msgstr "البدء من جديد"
msgid "Start recording"
msgstr "بدء التسجيل"
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:592
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:582
msgid "Start searches with <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> to narrow down results."
msgstr "ابدأ عمليات البحث بـ <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> لتضييق نطاق النتائج."
@@ -31831,7 +31862,7 @@ msgid "Startup"
msgstr "بدء التشغيل"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:75
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:78
msgid "Static Neko"
msgstr "نيكو ثابت"
@@ -32038,7 +32069,7 @@ msgid "Still indexing — check back in a moment"
msgstr "لا تزال الفهرسة جارية. تحقق مجددًا بعد قليل"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:71
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:74
msgid "Still Neko"
msgstr "نيكو ساكن"
@@ -32067,7 +32098,7 @@ msgid "Stop mic test"
msgstr "إيقاف اختبار الميكروفون"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:70
msgid "Stop Neko from chasing your cursor while keeping it draggable and interactive."
msgstr "منع نيكو من مطاردة مؤشر الفأرة مع إبقائه قابلًا للسحب والتفاعل."
@@ -32259,14 +32290,14 @@ msgid "Streaming privacy on"
msgstr "خصوصية البث مفعّلة"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:111
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
msgid "Strike through"
msgstr "يتوسطه خط"
#. Selection formatting toolbar button.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/lexical/composer/SelectionFormattingToolbar.tsx:72
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:107
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
msgid "Strikethrough"
msgstr "يتوسطه خط"
@@ -32490,7 +32521,7 @@ msgid "Switch price"
msgstr "تبديل السعر"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "التبديل إلى {listPriceNewLabel}"
@@ -32515,7 +32546,7 @@ msgstr "التبديل إلى الإدخال المباشر"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "التبديل إلى الفوترة الشهرية"
@@ -32584,7 +32615,7 @@ msgstr "التبديل إلى عمودين"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "التبديل إلى الفوترة السنوية"
@@ -33074,7 +33105,7 @@ msgstr "أرسل لنا رسالة نصية من هاتفك"
#. Feature label / section heading for the text-to-speech feature.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:419
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
msgid "Text-to-speech"
msgstr "تحويل النص إلى كلام"
@@ -34133,7 +34164,7 @@ msgid "This member isn't connected to voice anymore."
msgstr "لم يعد هذا العضو متصلًا بالقناة الصوتية."
#. Forward dialog error shown when the forwarded message contains age-restricted media and the target channel is not age-restricted.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:68
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:69
msgid "This message can only be forwarded to age-restricted channels"
msgstr "لا يمكن إعادة توجيه هذه الرسالة إلا إلى القنوات المخصصة للبالغين"
@@ -34766,7 +34797,7 @@ msgid "Toolbar"
msgstr "شريط الأدوات"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:51
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:54
msgid "Tooltip shortcuts"
msgstr "تلميحات الاختصارات"
@@ -35080,7 +35111,7 @@ msgid "Try sending your message again."
msgstr "حاول إرسال رسالتك مرة أخرى."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
msgid "TTS"
msgstr "TTS"
@@ -35277,7 +35308,7 @@ msgstr "أربع وعشرون ساعة"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:39
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:42
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:406
msgid "Two clicks"
msgstr "نقرتان"
@@ -35834,7 +35865,7 @@ msgstr "افتح الرموز التعبيرية المخصصة في الرسا
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "افتح مشاركة الشاشة عالية الدقة باستخدام {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "احصل على حدود أعلى وميزات حصرية مع دعم منصة تواصل مستقلة."
@@ -36044,7 +36075,7 @@ msgstr "غير مقروءة"
#. Tab label in the inbox popout filtering to channels with unread messages.
#: src/features/messaging/components/popouts/InboxPopout.tsx:30
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
msgid "Unread"
msgstr "غير مقروءة"
@@ -37866,7 +37897,7 @@ msgstr "مؤشرات مرئية توضح حالة المستخدم، وتُعر
#: src/features/app/components/layout/MobileBottomNav.tsx:123
#: src/features/channel/utils/ChannelUtils.tsx:31
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:17
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
msgid "Voice"
msgstr "صوت"
@@ -37961,7 +37992,7 @@ msgstr "قناة صوتية"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:23
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:26
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:402
msgid "Voice channel confirmation"
msgstr "تأكيد القناة الصوتية"
@@ -37972,7 +38003,7 @@ msgid "Voice channel full"
msgstr "القناة الصوتية ممتلئة"
#. Settings search entry label. Names the settings search entry in the settings UI.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:19
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:22
msgid "Voice channel join behavior"
msgstr "سلوك الانضمام إلى القناة الصوتية"
@@ -38099,7 +38130,7 @@ msgstr "ملغاة"
#: src/features/i18n/utils/CommonMessageDescriptors.ts:378
#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:181
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:183
msgid "Volume"
msgstr "مستوى الصوت"
@@ -38984,15 +39015,15 @@ msgstr "سنويًا {yearlyPrice}"
msgid "Yearly gift"
msgstr "هدية سنوية"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "الترقية السنوية مجدولة بتاريخ <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "الترقية السنوية مجدولة بتاريخ <0>{pendingChangeDate}</0>. أول رسوم سنوية: {pendingInitialPriceLabel} بعد خصم رصيد بقيمة {pendingCreditPriceLabel}. التجديدات السنوية المستقبلية: {pendingRecurringPriceLabel} سنويًا."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "الترقية السنوية مجدولة بتاريخ <0>{pendingChangeDate}</0>. أول رسوم سنوية: {pendingInitialPriceLabel}. التجديدات السنوية المستقبلية: {pendingRecurringPriceLabel} سنويًا."
@@ -39462,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "لقد ضغطت على Tab للتو. وضع لوحة المفاتيح قيد التشغيل الآن حتى تتمكن من التنقل في {productName} دون استخدام الماوس."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "ستحتفظ بمزاياك حتى تاريخ التجديد التالي، ثم تحصل على فترة سماح مدتها 3 أيام لإعادة الاشتراك والاحتفاظ بسجل اشتراكك."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "ستحتفظ بمزاياك حتى تاريخ التجديد التالي. أعد تفعيل اشتراكك قبل ذلك للاحتفاظ بسجل اشتراكك."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "ستفقد جميع مزايا {PREMIUM_PRODUCT_NAME} على الفور وستتم إعادة تعيين سجل اشتراكك. لا يمكن التراجع عن هذا الإجراء."
@@ -39508,12 +39539,12 @@ msgid "You need access to your current email to change it from here. Use phone v
msgstr "تحتاج إلى الوصول إلى بريدك الإلكتروني الحالي لتغييره من هنا. استخدم التحقق عبر الهاتف إذا كان متاحًا أو اتصل بالدعم."
#. Forward dialog error shown when the forwarded message has attachments and the user lacks Attach Files in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:63
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:64
msgid "You need the \"{attachFilesPermissionLabel}\" permission to attach files in this channel"
msgstr "أنت بحاجة إلى إذن \"{attachFilesPermissionLabel}\" لإرفاق الملفات في هذه القناة"
#. Forward dialog error shown when the forwarded message contains embeds and the user lacks Embed Links in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:58
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:59
msgid "You need the \"{embedLinksPermissionLabel}\" permission to embed links in this channel"
msgstr "أنت بحاجة إلى إذن \"{embedLinksPermissionLabel}\" لتضمين الروابط في هذه القناة"
@@ -40200,6 +40231,11 @@ msgstr "منطقتك"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "يتطلب تسجيلك فحصًا إضافيًا لمكافحة الرسائل المزعجة قبل أن تتمكن من المتابعة."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "فشل دفع تجديد اشتراكك، لكن <0/> ستظل نشطة حتى <1>{graceDate}</1>. حدّث طريقة الدفع قبل ذلك التاريخ للاحتفاظ باشتراكك."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40221,7 +40257,7 @@ msgstr "البث المباشر الخاص بك لا يزال نشطًا"
msgid "Your subscription can't move to the new price right now."
msgstr "لا يمكن نقل اشتراكك إلى السعر الجديد في الوقت الحالي."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "انتهى اشتراكك، لكن <0/> ستظل نشطة حتى <1>{graceDate}</1>. أعد الاشتراك قبل ذلك التاريخ للاحتفاظ بسجل اشتراكك."
@@ -40250,7 +40286,7 @@ msgstr "تم تحويل اشتراكك إلى الفوترة الشهرية."
msgid "Your subscription has been switched to yearly billing."
msgstr "تم تحويل اشتراكك إلى الفوترة السنوية."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "اشتراكك نشط، ولكن المزايا متوقفة مؤقتًا."
@@ -40270,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "سينتقل اشتراكك إلى السعر الجديد في {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "سينتهي اشتراكك في <0>{cancelDate}</0> كما هو مقرر. السعر الحالي الآن {listPriceNewLabel}. إذا أعدت التفعيل، يمكنك التبديل إليه من هنا."
@@ -448,6 +448,9 @@
{
"msgid": "Download"
},
{
"msgid": "Download app"
},
{
"msgid": "Download {productName}"
},
@@ -1884,6 +1887,12 @@
{
"msgid": "Domain moved nagbar"
},
{
"msgid": "Download app"
},
{
"msgid": "Download app button in the sidebar"
},
{
"msgid": "Drag members between voice channels they can access, and disconnect them from voice."
},
@@ -2016,6 +2025,9 @@
{
"msgid": "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
},
{
"msgid": "Help button"
},
{
"msgid": "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
},
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Налична е актуализация за настолното приложение на Linux. Избери формата на пакета за тази система и {productName} ще я запази локално."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Предлага се по-ниска цена. Преминаването влиза в сила на <0>{listPriceEffectiveDate}</0> и не променя нищо друго."
@@ -2639,7 +2639,7 @@ msgstr "Достъп до основната информация в профи
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. User settings tab for accessibility preferences (visual, motion, screen reader, etc.).
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:14
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/SettingsConstants.tsx:61
msgid "Accessibility"
msgstr "Достъпност"
@@ -3487,19 +3487,19 @@ msgstr "Контролите за подравняване са налични
msgid "All"
msgstr "Всички"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Всички <0/> за <1>{effectiveMonthlyPrice}/месец</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Всички <0/> за <1>{effectiveYearlyPrice}/година</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Всички <0/> са включени в абонамента ти."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Всички <0/>, завинаги. Без таксуване и подновявания."
@@ -4706,7 +4706,7 @@ msgstr "Прикачени файлове"
#. Generic tab / section / category label for audio content or settings.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:255
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:179
msgid "Audio"
msgstr "Аудио"
@@ -6210,7 +6210,7 @@ msgid "California"
msgstr "Калифорния"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
msgid "Call"
msgstr "Обаждане"
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Отказ на импортирането"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Отказ на промяната на цената"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Отмяна на поканата"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Отказ на планираната промяна"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Отказ от абонамент"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Да откажеш ли абонамента?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Отмени планираната промяна, за да преминеш към текущата цена вместо това."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Отказ на качването"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Отказ на годишното надграждане"
@@ -6530,7 +6530,7 @@ msgstr "Анулиране"
msgid "Cancellation"
msgstr "Потискане на ехото"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Анулира се на <0>{cancelDate}</0>. <1/> остават активни дотогава."
@@ -7088,7 +7088,7 @@ msgid "Channel"
msgstr "Канал"
#. Fallback name for an unnamed channel in the forward modal destination list. Preserve {id}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:78
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:79
msgid "Channel {id}"
msgstr "Канал {id}"
@@ -7317,7 +7317,7 @@ msgid "Chat font size"
msgstr "Размер на шрифта в чата"
#. Settings search synonym. Refers to the message composer area.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
msgid "chat input"
msgstr "поле за въвеждане в чата"
@@ -8726,7 +8726,7 @@ msgid "Community updated"
msgstr "Общността е актуализирана"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:35
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:38
msgid "Community voice"
msgstr "Гласов чат в общност"
@@ -8789,12 +8789,13 @@ msgstr "Завърши необходимото потвърждение, за
msgid "Completely hide your {premiumProductName} badge from other users"
msgstr "Пълно скриване на значката ти {premiumProductName} от другите потребители"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:134
#: src/features/auth/components/pages/SsoCallbackPage.tsx:118
#: src/features/auth/components/pages/SsoCallbackPage.tsx:168
#: src/features/auth/flow/HandoffApprovalFlow.tsx:218
msgid "Completing sign-in…"
msgstr "Завършване на влизането…"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:138
#: src/features/auth/components/pages/SsoCallbackPage.tsx:172
msgid "Completing your sign-in…"
msgstr "Завършване на влизането ти…"
@@ -8912,8 +8913,8 @@ msgstr "Потвърди"
#. Settings search entry label. Names the settings search entry in the settings UI.
#. Short label for an advanced voice-channel safety preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:21
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:15
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:24
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:18
msgid "Confirm before joining voice channels"
msgstr "Потвърждаване преди присъединяване към гласови канали"
@@ -8952,7 +8953,7 @@ msgstr "Потвърди паролата"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:27
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:30
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:398
msgid "Confirm voice join"
msgstr "Потвърждаване на присъединяването към гласов канал"
@@ -8963,7 +8964,7 @@ msgid "Confirmation"
msgstr "Потвърждение"
#. Settings search entry description. One-line summary of what the settings search entry controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:43
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:46
msgid "Confirmation or double-click for community voice joins"
msgstr "Потвърждение или двойно щракване при присъединяване към гласов канал в общност"
@@ -9200,7 +9201,7 @@ msgstr "Предпазни мерки за съдържанието"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/ui/action_menu/ContextMenu.tsx:23
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:225
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
msgid "Context menu"
msgstr "Контекстно меню"
@@ -10871,7 +10872,7 @@ msgstr "По избор…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Клиентски портал"
@@ -11341,7 +11342,7 @@ msgstr "Делауер"
#: src/features/user/components/modals/tabs/component_gallery_tab/ComponentGalleryTabButtonsTab.tsx:290
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:238
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:174
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
msgid "Delete"
msgstr "Изтриване"
@@ -11626,7 +11627,7 @@ msgid "Deleted {duration} of the member's recent message history"
msgstr "Изтри {duration} от скорошната история на съобщенията на члена"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
msgid "Deleted text"
msgstr "Изтрит текст"
@@ -12028,7 +12029,7 @@ msgid "Different sizes & member counts"
msgstr "Различни размери и брой членове"
#. Toggle label and settings search entry for slightly muting text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:106
msgid "Dim strikethrough text"
msgstr "Приглушаване на зачеркнатия текст"
@@ -12043,7 +12044,7 @@ msgstr "Директен вход"
#: src/features/channel/components/bottomsheets/channel_details_bottom_sheet/ChannelDetailsBottomSheetShared.ts:14
#: src/features/channel/components/channel_header_components/developer_tools/MockingMenu.tsx:398
#: src/features/i18n/utils/CommonMessageDescriptors.ts:567
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
msgid "Direct message"
msgstr "Директно съобщение"
@@ -12480,7 +12481,7 @@ msgid "District of Columbia"
msgstr "Окръг Колумбия"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:180
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
msgid "DM"
msgstr "DM"
@@ -12735,6 +12736,16 @@ msgstr "Изтегляне на {productName}"
msgid "Download <0>fluxer-verification</0> and place it in your <1>.well-known</1> folder so we can validate the domain."
msgstr "Изтегли <0>fluxer-verification</0> и го постави в папката си <1>.well-known</1>, за да можем да потвърдим домейна."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:98
msgid "Download app"
msgstr "Изтегляне на приложението"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:106
msgid "Download app button in the sidebar"
msgstr "Бутон за изтегляне на приложението в страничната лента"
#. Media context menu action that downloads an audio attachment.
#: src/features/ui/action_menu/items/MediaMenuData.tsx:122
msgid "Download audio"
@@ -13433,7 +13444,7 @@ msgstr "Вградените елементи са видими"
#: src/features/app/config/AuditLogConstants.ts:167
#: src/features/emoji/components/emojis/EmojiListItem.tsx:337
#: src/features/theme_studio/sections/TokenGroups.ts:114
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
msgid "Emoji"
msgstr "Емоджи"
@@ -13866,15 +13877,15 @@ msgid "End date"
msgstr "Крайна дата"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Прекратяване сега"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Край на гратисния период"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Да се прекрати ли гратисният период сега?"
@@ -14681,7 +14692,7 @@ msgid "Failed to clear trusted domains."
msgstr "Неуспешно изчистване на доверени домейни."
#. Short label in the authentication SSO callback page. Keep the tone plain and specific.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:28
#: src/features/auth/components/pages/SsoCallbackPage.tsx:30
msgid "Failed to complete SSO sign-in"
msgstr "Неуспешно влизане чрез SSO"
@@ -15027,7 +15038,7 @@ msgid "Favorite channel"
msgstr "Добави канала в любими"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:79
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:82
msgid "Favorite channels"
msgstr "Любими канали"
@@ -15800,7 +15811,7 @@ msgstr "Приятелски бот"
#: src/features/connection/components/modals/EditConnectionModal.tsx:86
#: src/features/search/utils/QuickSwitcherModalUtils.tsx:50
#: src/features/user/components/modals/tabs/my_profile_tab/TimezoneProfileSettings.tsx:63
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
msgid "Friends"
msgstr "Приятели"
@@ -16145,7 +16156,7 @@ msgstr "Вземи новото приложение {productName}"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Type label for GIF media.
#: src/features/expressions/utils/FavoriteMemeUtils.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
msgid "GIF"
msgstr "GIF"
@@ -16336,7 +16347,7 @@ msgstr "Подарък: изтича скоро"
msgid "Gift: grace period (still have access)"
msgstr "Подарък: гратисен период (все още имаш достъп)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Подарено <0/> до <1>{giftEndDate}</1>. Не се подновява автоматично. Осребри още кодове за подарък, за да удължиш."
@@ -16549,7 +16560,7 @@ msgid "Graphics"
msgstr "Графика"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
msgid "Gray text"
msgstr "Сив текст"
@@ -16815,7 +16826,7 @@ msgid "Hate speech"
msgstr "Език на омразата"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Имате код за подарък? Осребрете го, за да отключите {PREMIUM_PRODUCT_NAME}."
@@ -16896,11 +16907,21 @@ msgstr "Здравей, {username}! Радваме се, че си тук."
msgid "Help"
msgstr "Помощ"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:94
msgid "Help button"
msgstr "Бутон за помощ"
#. Short label in the sidebar navigation help button.
#: src/features/app/components/layout/sidebar_nav/HelpButton.tsx:27
msgid "Help center"
msgstr "Помощен център"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:102
msgid "Help center button in the sidebar"
msgstr "Помощ в центъра за помощ в страничната лента"
#: src/features/user/components/modals/tabs/LanguageTab.tsx:348
msgid "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
msgstr "Помогни да преведем {PRODUCT_NAME} на твоя език на <0>{I18N_WEBLATE_DOMAIN}</0>."
@@ -17035,7 +17056,7 @@ msgid "Hide join messages"
msgstr "Скрий съобщенията за присъединяване"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:47
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:50
msgid "Hide keyboard hints"
msgstr "Скрий подсказките за клавиатурата"
@@ -18721,7 +18742,7 @@ msgstr "Присъединяване към видеоразговор"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/profile/VoiceActivityCard.tsx:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:31
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:34
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:454
msgid "Join voice"
msgstr "Присъединяване към гласов чат"
@@ -18764,6 +18785,7 @@ msgstr "Прескачане между непрочетени канали"
msgid "Jump between unread channels with mentions"
msgstr "Прескачане между непрочетени канали със споменавания"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:121
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:75
msgid "Jump straight to the app to continue."
msgstr "Премини към приложението, за да продължиш."
@@ -18904,7 +18926,7 @@ msgstr "Запазване на прикачени файлове при изч
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Запазете безплатни и премиум нива. Можете да персонализирате нивата, да продавате премиум чрез Stripe или по-късно да раздавате кодове за подаръци от административния панел."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Запазване на гратисния период"
@@ -18918,7 +18940,7 @@ msgstr "Спиране на движението на Неко"
msgid "Keep running"
msgstr "Работа във фонов режим"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Запазване на абонамента"
@@ -18980,7 +19002,7 @@ msgid "Keyboard mode"
msgstr "Режим „Клавиатура“"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:59
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:62
msgid "Keyboard shortcut hints in tooltips"
msgstr "Показване на клавишните комбинации в подсказките"
@@ -19275,8 +19297,8 @@ msgstr "Ляв бутон на мишката"
msgid "Left tooltip"
msgstr "Подсказка отляво"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Стара цена"
@@ -20094,7 +20116,7 @@ msgstr "Маркирай най-горния канал във входящит
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:364
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
msgid "Markdown"
msgstr "Markdown"
@@ -20644,7 +20666,7 @@ msgstr "Да се спомене ли тази роля?"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/guild/components/modals/GuildNotificationSettingsModal.tsx:136
#: src/features/i18n/utils/CommonMessageDescriptors.ts:648
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
msgid "Mentions"
msgstr "Споменавания"
@@ -21158,7 +21180,7 @@ msgid "Missing client_id"
msgstr "Липсващ client_id"
#. SSO callback page error shown when the SSO callback is missing code or state parameters.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:24
#: src/features/auth/components/pages/SsoCallbackPage.tsx:26
msgid "Missing SSO code. Sign in again."
msgstr "Липсва SSO код. Влез отново."
@@ -21317,11 +21339,11 @@ msgstr "Месечно"
msgid "Monthly {monthlyPrice}"
msgstr "Месечно {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Месечното таксуване започва на <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Месечното таксуване започва на <0>{pendingChangeDate}</0>. Първа месечна такса: {pendingInitialPriceLabel}. Бъдещи месечни подновявания: {pendingRecurringPriceLabel}/месец."
@@ -21756,7 +21778,7 @@ msgstr "заглушено"
#. Status label indicating the surface is currently muted.
#: src/features/app/components/layout/sidebar_nav/UseGuildListItemState.ts:23
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:491
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/lib/overlay/OverlayContextMenu.tsx:24
msgid "Muted"
msgstr "Заглушено"
@@ -21779,7 +21801,7 @@ msgstr "Микрофонът е изключен от модератори"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:495
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
msgid "Muted channels"
msgstr "Заглушени канали"
@@ -21992,7 +22014,7 @@ msgid "Narrates only the channel you're viewing. Narration follows you between c
msgstr "Чете само канала, който гледаш. Четенето те следва между каналите."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
msgid "Narration"
msgstr "Четене на глас"
@@ -22057,12 +22079,12 @@ msgid "Need an account?"
msgstr "Нямаш акаунт?"
#. Settings search synonym. Proper name of the optional cat sprite that chases the cursor.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
msgid "Neko"
msgstr "Неко"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:63
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:66
msgid "Neko cat that chases your cursor"
msgstr "Котето Неко, което гони курсора ти"
@@ -22247,12 +22269,12 @@ msgid "New password"
msgstr "Нова парола"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Нова цена е насрочена за <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Нова цена е насрочена за <0>{pendingChangeDate}</0>. След това подновяванията ще бъдат {pendingTargetPriceLabel}."
@@ -23560,6 +23582,8 @@ msgid "Open {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName}
msgstr "Отвори {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName} → {macosScreenRecordingPermissionName}, след което разреши достъпа за {productName}. Ако {productName2} вече е активирано, затвори напълно и рестартирай {productName3}, за да може macOS да приложи разрешението."
#. Button label that opens the desktop app. productName is the app name.
#. Button that hands SSO sign-in back to the mobile app. productName is the app name.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:34
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:27
msgid "Open {productName}"
msgstr "Отваряне на {productName}"
@@ -24945,7 +24969,7 @@ msgstr "Закачи това съобщение в канала, за да го
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Voice stats field label (mobile lobby). Shows current latency in ms.
#. Voice stats field label (mobile voice lobby). Shows current latency in ms.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:184
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/voice/components/bottomsheets/DirectCallLobbyBottomSheet.tsx:118
#: src/features/voice/components/bottomsheets/VoiceLobbyBottomSheet.tsx:86
msgid "Ping"
@@ -25165,7 +25189,7 @@ msgid "Popped out"
msgstr "В отделен прозорец"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:204
msgid "Popup"
msgstr "Изскачащ прозорец"
@@ -26128,7 +26152,7 @@ msgstr "Реакции"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Активиране отново"
@@ -26139,7 +26163,7 @@ msgid "Reactivate subscription"
msgstr "Повторно активиране на абонамент"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
msgid "Read aloud"
msgstr "Прочитане на глас"
@@ -26156,7 +26180,7 @@ msgstr "Четене на историята на съобщенията"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:177
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
msgid "Read messages"
msgstr "Четене на съобщения"
@@ -26351,8 +26375,8 @@ msgstr "Осребри за себе си"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Осребряване на код за подарък"
@@ -26630,7 +26654,7 @@ msgstr "Запомняне на размера и позицията на про
#: src/features/user/components/modals/tabs/chat_settings_tab/SearchEnginesTab.tsx:26
#: src/features/user/components/modals/tabs/LinkedAccountsTab.tsx:55
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:178
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:200
#: src/features/webhook/components/WebhookListItem.tsx:277
msgid "Remove"
msgstr "Премахване"
@@ -27123,7 +27147,7 @@ msgstr "Праг на подновяване (дни)"
msgid "Renew window (days)"
msgstr "Период за подновяване (дни)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Подновява се на <0>{renewalDate}.</0>"
@@ -27321,7 +27345,7 @@ msgid "Require a passkey as your second factor"
msgstr "Изискване на ключ за достъп като втори фактор"
#. Short label for an advanced voice-channel navigation preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:17
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:20
msgid "Require double-click to join voice channels"
msgstr "Изискване на двойно щракване за присъединяване към гласови канали"
@@ -27872,8 +27896,8 @@ msgstr "Възстановяване на прозореца"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Абониране отново"
@@ -29578,7 +29602,7 @@ msgid "Sending malware or dangerous links"
msgstr "Изпращане на злонамерен софтуер или опасни линкове"
#. Short label under a destination row in the forward modal, shown when the community has messaging disabled.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:54
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:55
msgid "Sending messages is disabled in this community"
msgstr "Изпращането на съобщения е деактивирано в тази общност"
@@ -30120,7 +30144,7 @@ msgstr "Пряк път"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:55
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:58
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:370
msgid "Shortcut badges"
msgstr "Значки за клавишни комбинации"
@@ -30280,7 +30304,9 @@ msgid "Show delete button"
msgstr "Показване на бутон за изтриване"
#. Short label for an advanced media button preference.
#. Toggle label and settings search entry for showing the download app button in the sidebar.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:76
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
msgid "Show download button"
msgstr "Показване на бутон за изтегляне"
@@ -30322,7 +30348,7 @@ msgid "Show favorite button"
msgstr "Показване на бутон „Любими“"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:87
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:90
msgid "Show favorites throughout the app"
msgstr "Показвай любимите навсякъде в приложението"
@@ -30350,6 +30376,11 @@ msgstr "Показване на индикатор за GIF"
msgid "Show GIFs button"
msgstr "Показване на бутона за GIF файлове"
#. Toggle label and settings search entry for showing the help center button in the sidebar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
msgid "Show help center button"
msgstr "Покажи бутона за помощния център"
#. Switch label in the community-folder settings modal. When on, the folder icon is shown in the sidebar while the folder is collapsed.
#: src/features/guild/components/modals/GuildFolderSettingsModal.tsx:77
msgid "Show icon when collapsed"
@@ -30565,7 +30596,7 @@ msgid "Show stickers in expression autocomplete"
msgstr "Показване на стикери в автоматичното довършване на изрази"
#. Description for a visual accessibility setting that mutes the color of text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:110
msgid "Show strikethrough Markdown text in a slightly muted color."
msgstr "Показване на зачеркнат Markdown текст в леко приглушен цвят."
@@ -31008,7 +31039,7 @@ msgid "Slowmode"
msgstr "Бавен режим"
#. Short label under a destination row in the forward modal while slowmode blocks sending. Preserve {remaining}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:73
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:74
msgid "Slowmode · wait {remaining}"
msgstr "Бавен режим · изчакай {remaining}"
@@ -31559,7 +31590,7 @@ msgstr "Зрители - {count}"
#. Native macOS Edit submenu title for text-to-speech actions.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/platform/utils/DesktopLocaleBridge.ts:85
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
msgid "Speech"
msgstr "Реч"
@@ -31670,12 +31701,12 @@ msgstr "Квадратни бутони с икона"
msgid "SSO is required to access this workspace."
msgstr "Изисква се SSO за достъп до това работно пространство."
#: src/features/auth/components/pages/SsoCallbackPage.tsx:105
#: src/features/auth/components/pages/SsoCallbackPage.tsx:139
msgid "SSO sign-in failed"
msgstr "Неуспешно влизане чрез SSO"
#. SSO callback page error shown when the SSO sign-in timed out before the callback arrived.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:20
#: src/features/auth/components/pages/SsoCallbackPage.tsx:22
msgid "SSO sign-in timed out. Try again."
msgstr "Времето за влизане чрез SSO изтече. Опитай отново."
@@ -31714,7 +31745,7 @@ msgid "Star animation"
msgstr "Анимация на звезда"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:83
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:86
msgid "Starred channels"
msgstr "Отбелязани канали"
@@ -31791,7 +31822,7 @@ msgstr "Започване отначало"
msgid "Start recording"
msgstr "Започване на запис"
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:592
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:582
msgid "Start searches with <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> to narrow down results."
msgstr "Започни търсенето с <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3>, за да стесниш резултатите."
@@ -31831,7 +31862,7 @@ msgid "Startup"
msgstr "Стартиране"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:75
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:78
msgid "Static Neko"
msgstr "Статичен Неко"
@@ -32038,7 +32069,7 @@ msgid "Still indexing — check back in a moment"
msgstr "Индексирането още тече. Провери отново след малко."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:71
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:74
msgid "Still Neko"
msgstr "Неподвижен Неко"
@@ -32067,7 +32098,7 @@ msgid "Stop mic test"
msgstr "Спиране на теста на микрофона"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:70
msgid "Stop Neko from chasing your cursor while keeping it draggable and interactive."
msgstr "Спри Неко да гони курсора ти, като запазиш възможността да го местиш и да взаимодействаш с него."
@@ -32259,14 +32290,14 @@ msgid "Streaming privacy on"
msgstr "Поверителност при стрийминг: вкл"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:111
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
msgid "Strike through"
msgstr "Зачертаване"
#. Selection formatting toolbar button.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/lexical/composer/SelectionFormattingToolbar.tsx:72
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:107
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
msgid "Strikethrough"
msgstr "Зачеркване"
@@ -32490,7 +32521,7 @@ msgid "Switch price"
msgstr "Смяна на цена"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Премини към {listPriceNewLabel}"
@@ -32515,7 +32546,7 @@ msgstr "Превключване към директен вход"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Премини към месечно таксуване"
@@ -32584,7 +32615,7 @@ msgstr "Превключване към две колони"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Премини към годишно таксуване"
@@ -33074,7 +33105,7 @@ msgstr "Изпрати ни съобщение от телефона си"
#. Feature label / section heading for the text-to-speech feature.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:419
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
msgid "Text-to-speech"
msgstr "Текст към говор"
@@ -34133,7 +34164,7 @@ msgid "This member isn't connected to voice anymore."
msgstr "Този член вече не е свързан с гласов канал."
#. Forward dialog error shown when the forwarded message contains age-restricted media and the target channel is not age-restricted.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:68
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:69
msgid "This message can only be forwarded to age-restricted channels"
msgstr "Това съобщение може да бъде препратено само към канали с ограничена възраст"
@@ -34766,7 +34797,7 @@ msgid "Toolbar"
msgstr "Лента с инструменти"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:51
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:54
msgid "Tooltip shortcuts"
msgstr "Клавишни комбинации в подсказките"
@@ -35080,7 +35111,7 @@ msgid "Try sending your message again."
msgstr "Опитай да изпратиш съобщението си отново."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
msgid "TTS"
msgstr "TTS"
@@ -35277,7 +35308,7 @@ msgstr "24-часов"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:39
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:42
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:406
msgid "Two clicks"
msgstr "Две кликвания"
@@ -35834,7 +35865,7 @@ msgstr "Отключи персонализирани емоджита в DM с
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Отключи споделяне на екран в HD с {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Отключи по-високи лимити и ексклузивни функции, докато подкрепяш независима комуникационна платформа."
@@ -36044,7 +36075,7 @@ msgstr "непрочетени"
#. Tab label in the inbox popout filtering to channels with unread messages.
#: src/features/messaging/components/popouts/InboxPopout.tsx:30
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
msgid "Unread"
msgstr "Непрочетени"
@@ -37866,7 +37897,7 @@ msgstr "Визуални индикатори, показващи състоян
#: src/features/app/components/layout/MobileBottomNav.tsx:123
#: src/features/channel/utils/ChannelUtils.tsx:31
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:17
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
msgid "Voice"
msgstr "Глас"
@@ -37961,7 +37992,7 @@ msgstr "Гласов канал"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:23
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:26
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:402
msgid "Voice channel confirmation"
msgstr "Потвърждение за гласов канал"
@@ -37972,7 +38003,7 @@ msgid "Voice channel full"
msgstr "Гласовият канал е пълен"
#. Settings search entry label. Names the settings search entry in the settings UI.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:19
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:22
msgid "Voice channel join behavior"
msgstr "Поведение при присъединяване към гласов канал"
@@ -38099,7 +38130,7 @@ msgstr "Анулирана"
#: src/features/i18n/utils/CommonMessageDescriptors.ts:378
#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:181
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:183
msgid "Volume"
msgstr "Сила на звука"
@@ -38984,15 +39015,15 @@ msgstr "Годишно {yearlyPrice}"
msgid "Yearly gift"
msgstr "Годишен подарък"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Годишно надграждане, насрочено за <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Годишно надграждане, насрочено за <0>{pendingChangeDate}</0>. Първо годишно таксуване: {pendingInitialPriceLabel} след кредит от {pendingCreditPriceLabel}. Бъдещи годишни подновявания: {pendingRecurringPriceLabel}/година."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Годишно надграждане, насрочено за <0>{pendingChangeDate}</0>. Първо годишно таксуване: {pendingInitialPriceLabel}. Бъдещи годишни подновявания: {pendingRecurringPriceLabel}/година."
@@ -39462,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Току-що натисна Tab. Режимът за навигация с клавиатура вече е включен, за да можеш да използваш {productName} без мишка."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Запазваш предимствата си до следващата дата на подновяване, след което имаш 3-дневен гратисен период, за да се абонираш отново и да запазиш историята си като абонат."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Запазваш предимствата си до следващата дата на подновяване. Активирай абонамента отново преди това, за да запазиш историята си като абонат."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Веднага губиш всички предимства на {PREMIUM_PRODUCT_NAME} и историята ти като абонат се нулира. Това не може да бъде отменено."
@@ -39508,12 +39539,12 @@ msgid "You need access to your current email to change it from here. Use phone v
msgstr "За да смениш имейла си оттук, трябва да имаш достъп до текущия. Използвай потвърждение по телефона, ако е налично, или се свържи с поддръжката."
#. Forward dialog error shown when the forwarded message has attachments and the user lacks Attach Files in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:63
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:64
msgid "You need the \"{attachFilesPermissionLabel}\" permission to attach files in this channel"
msgstr "Нужно е разрешението „{attachFilesPermissionLabel}“, за да прикачваш файлове в този канал"
#. Forward dialog error shown when the forwarded message contains embeds and the user lacks Embed Links in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:58
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:59
msgid "You need the \"{embedLinksPermissionLabel}\" permission to embed links in this channel"
msgstr "Нужно е разрешението „{embedLinksPermissionLabel}“, за да вграждаш линкове в този канал"
@@ -40200,6 +40231,11 @@ msgstr "твоя регион"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Регистрацията ти изисква допълнителна проверка срещу спам, преди да продължиш."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Плащането за подновяване не успя, но <0/> остават активни до <1>{graceDate}</1>. Обнови начина си на плащане преди тази дата, за да запазиш абонамента си."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40221,7 +40257,7 @@ msgstr "Потокът ти все още е на живо"
msgid "Your subscription can't move to the new price right now."
msgstr "Абонаментът ти не може да премине към новата цена в момента."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Абонаментът ти приключи, но <0/> остават активни до <1>{graceDate}</1>. Абонирай се отново преди тази дата, за да запазиш историята си като абонат."
@@ -40250,7 +40286,7 @@ msgstr "Абонаментът ти е превключен към месечн
msgid "Your subscription has been switched to yearly billing."
msgstr "Абонаментът ти е превключен към годишно таксуване."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Абонаментът ти е активен, но предимствата са временно на пауза."
@@ -40270,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Абонаментът ти преминава към новата цена на {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Абонаментът ти все още приключва на <0>{cancelDate}</0>. Текущата цена вече е {listPriceNewLabel}. Ако го активираш отново, можеш да преминеш към нея оттук."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Je k dispozici aktualizace desktopové aplikace pro Linux. Vyberte formát balíčku pro tento systém a aplikace {productName} jej uloží do počítače."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Je k dispozici nižší cena. Přechod začne platit <0>{listPriceEffectiveDate}</0> a nic jiného se nezmění."
@@ -2639,7 +2639,7 @@ msgstr "Přístup k základním informacím o profilu (uživatelské jméno, ava
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. User settings tab for accessibility preferences (visual, motion, screen reader, etc.).
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:14
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/SettingsConstants.tsx:61
msgid "Accessibility"
msgstr "Přístupnost"
@@ -3487,19 +3487,19 @@ msgstr "Ovládací prvky zarovnání jsou dostupné pouze na širších obrazovk
msgid "All"
msgstr "Vše"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Všechny <0/> za <1>{effectiveMonthlyPrice}/měsíc</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Všechny <0/> za <1>{effectiveYearlyPrice}/rok</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Všechny <0/> jsou součástí vašeho předplatného."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Všechny <0/> napořád. Žádné platby ani obnovování."
@@ -4706,7 +4706,7 @@ msgstr "Přílohy"
#. Generic tab / section / category label for audio content or settings.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:255
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:179
msgid "Audio"
msgstr "Zvuk"
@@ -6210,7 +6210,7 @@ msgid "California"
msgstr "Kalifornie"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
msgid "Call"
msgstr "Volání"
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Zrušit import"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Zrušit změnu ceny"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Zrušit žádost"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Zrušit plánovanou změnu"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Zrušit předplatné"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Zrušit předplatné?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Zrušit naplánovanou změnu a místo toho přejít na aktuální cenu."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Zrušit nahrávání"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Zrušit přechod na roční předplatné"
@@ -6530,7 +6530,7 @@ msgstr "Ruší se"
msgid "Cancellation"
msgstr "Potlačení ozvěny"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Předplatné bude zrušeno dne <0>{cancelDate}</0>. <1/> zůstanou aktivní až do té doby."
@@ -7088,7 +7088,7 @@ msgid "Channel"
msgstr "Kanál"
#. Fallback name for an unnamed channel in the forward modal destination list. Preserve {id}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:78
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:79
msgid "Channel {id}"
msgstr "Kanál {id}"
@@ -7317,7 +7317,7 @@ msgid "Chat font size"
msgstr "Velikost písma chatu"
#. Settings search synonym. Refers to the message composer area.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
msgid "chat input"
msgstr "pole pro psaní zpráv"
@@ -8726,7 +8726,7 @@ msgid "Community updated"
msgstr "Komunita aktualizována"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:35
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:38
msgid "Community voice"
msgstr "Hlasové hovory v komunitě"
@@ -8789,12 +8789,13 @@ msgstr "Dokončete požadované ověření, abyste mohli nadále používat {pro
msgid "Completely hide your {premiumProductName} badge from other users"
msgstr "Zcela skrýt odznak {premiumProductName} před ostatními uživateli"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:134
#: src/features/auth/components/pages/SsoCallbackPage.tsx:118
#: src/features/auth/components/pages/SsoCallbackPage.tsx:168
#: src/features/auth/flow/HandoffApprovalFlow.tsx:218
msgid "Completing sign-in…"
msgstr "Dokončování přihlášení…"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:138
#: src/features/auth/components/pages/SsoCallbackPage.tsx:172
msgid "Completing your sign-in…"
msgstr "Dokončuje se vaše přihlášení…"
@@ -8912,8 +8913,8 @@ msgstr "Potvrdit"
#. Settings search entry label. Names the settings search entry in the settings UI.
#. Short label for an advanced voice-channel safety preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:21
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:15
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:24
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:18
msgid "Confirm before joining voice channels"
msgstr "Vyžadovat potvrzení před připojením k hlasovým kanálům"
@@ -8952,7 +8953,7 @@ msgstr "Potvrďte heslo"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:27
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:30
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:398
msgid "Confirm voice join"
msgstr "Potvrzení připojení k hlasovému hovoru"
@@ -8963,7 +8964,7 @@ msgid "Confirmation"
msgstr "Potvrzení"
#. Settings search entry description. One-line summary of what the settings search entry controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:43
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:46
msgid "Confirmation or double-click for community voice joins"
msgstr "Potvrzení nebo dvojité kliknutí pro připojení k hlasovým kanálům komunity"
@@ -9200,7 +9201,7 @@ msgstr "Omezení přístupu k obsahu"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/ui/action_menu/ContextMenu.tsx:23
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:225
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
msgid "Context menu"
msgstr "Kontextová nabídka"
@@ -10871,7 +10872,7 @@ msgstr "Vlastní…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Zákaznický portál"
@@ -11341,7 +11342,7 @@ msgstr "Delaware"
#: src/features/user/components/modals/tabs/component_gallery_tab/ComponentGalleryTabButtonsTab.tsx:290
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:238
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:174
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
msgid "Delete"
msgstr "Smazat"
@@ -11626,7 +11627,7 @@ msgid "Deleted {duration} of the member's recent message history"
msgstr "Smazána nedávná historie zpráv člena: {duration}"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
msgid "Deleted text"
msgstr "Smazaný text"
@@ -12028,7 +12029,7 @@ msgid "Different sizes & member counts"
msgstr "Různé velikosti a počty členů"
#. Toggle label and settings search entry for slightly muting text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:106
msgid "Dim strikethrough text"
msgstr "Snížit výraznost přeškrtnutého textu"
@@ -12043,7 +12044,7 @@ msgstr "Přímý vstup"
#: src/features/channel/components/bottomsheets/channel_details_bottom_sheet/ChannelDetailsBottomSheetShared.ts:14
#: src/features/channel/components/channel_header_components/developer_tools/MockingMenu.tsx:398
#: src/features/i18n/utils/CommonMessageDescriptors.ts:567
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
msgid "Direct message"
msgstr "Přímá zpráva"
@@ -12480,7 +12481,7 @@ msgid "District of Columbia"
msgstr "Distrikt Columbia"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:180
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
msgid "DM"
msgstr "DM"
@@ -12735,6 +12736,16 @@ msgstr "Stáhnout {productName}"
msgid "Download <0>fluxer-verification</0> and place it in your <1>.well-known</1> folder so we can validate the domain."
msgstr "Stáhněte si <0>fluxer-verification</0> a umístěte jej do složky <1>.well-known</1>, abychom mohli ověřit doménu."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:98
msgid "Download app"
msgstr "Stáhnout aplikaci"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:106
msgid "Download app button in the sidebar"
msgstr "Stáhnout aplikaci"
#. Media context menu action that downloads an audio attachment.
#: src/features/ui/action_menu/items/MediaMenuData.tsx:122
msgid "Download audio"
@@ -13433,7 +13444,7 @@ msgstr "Vložený obsah znovu zobrazen"
#: src/features/app/config/AuditLogConstants.ts:167
#: src/features/emoji/components/emojis/EmojiListItem.tsx:337
#: src/features/theme_studio/sections/TokenGroups.ts:114
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
msgid "Emoji"
msgstr "Emoji"
@@ -13866,15 +13877,15 @@ msgid "End date"
msgstr "Datum konce"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Ukončit dodatečnou lhůtu hned"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Ukončit dodatečnou lhůtu"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Ukončit dodatečnou lhůtu hned?"
@@ -14681,7 +14692,7 @@ msgid "Failed to clear trusted domains."
msgstr "Nepodařilo se vymazat důvěryhodné domény."
#. Short label in the authentication SSO callback page. Keep the tone plain and specific.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:28
#: src/features/auth/components/pages/SsoCallbackPage.tsx:30
msgid "Failed to complete SSO sign-in"
msgstr "Přihlášení přes SSO se nezdařilo"
@@ -15027,7 +15038,7 @@ msgid "Favorite channel"
msgstr "Přidat kanál do oblíbených"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:79
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:82
msgid "Favorite channels"
msgstr "Oblíbené kanály"
@@ -15800,7 +15811,7 @@ msgstr "Přátelský bot"
#: src/features/connection/components/modals/EditConnectionModal.tsx:86
#: src/features/search/utils/QuickSwitcherModalUtils.tsx:50
#: src/features/user/components/modals/tabs/my_profile_tab/TimezoneProfileSettings.tsx:63
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
msgid "Friends"
msgstr "Přátelé"
@@ -16145,7 +16156,7 @@ msgstr "Získejte novou aplikaci {productName}"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Type label for GIF media.
#: src/features/expressions/utils/FavoriteMemeUtils.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
msgid "GIF"
msgstr "GIF"
@@ -16336,7 +16347,7 @@ msgstr "Dárek: brzy vyprší"
msgid "Gift: grace period (still have access)"
msgstr "Dárek: dodatečná lhůta (stále máte přístup)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Darované <0/> platí do <1>{giftEndDate}</1>. Předplatné se automaticky neobnovuje. Pro prodloužení uplatněte další dárkové kódy."
@@ -16549,7 +16560,7 @@ msgid "Graphics"
msgstr "Grafika"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
msgid "Gray text"
msgstr "Šedý text"
@@ -16815,7 +16826,7 @@ msgid "Hate speech"
msgstr "Nenávistné projevy"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Máte dárkový kód? Uplatněte ho a odemkněte {PREMIUM_PRODUCT_NAME}."
@@ -16896,11 +16907,21 @@ msgstr "Vítejte, {username}! Jsme rádi, že jste tady."
msgid "Help"
msgstr "Nápověda"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:94
msgid "Help button"
msgstr "Tlačítko Nápověda"
#. Short label in the sidebar navigation help button.
#: src/features/app/components/layout/sidebar_nav/HelpButton.tsx:27
msgid "Help center"
msgstr "Centrum nápovědy"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:102
msgid "Help center button in the sidebar"
msgstr "Centrum nápovědy"
#: src/features/user/components/modals/tabs/LanguageTab.tsx:348
msgid "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
msgstr "Pomozte přeložit {PRODUCT_NAME} do vašeho jazyka na <0>{I18N_WEBLATE_DOMAIN}</0>."
@@ -17035,7 +17056,7 @@ msgid "Hide join messages"
msgstr "Skrýt zprávy o připojení"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:47
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:50
msgid "Hide keyboard hints"
msgstr "Skrýt tipy pro klávesnici"
@@ -18721,7 +18742,7 @@ msgstr "Připojit se k videohovoru"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/profile/VoiceActivityCard.tsx:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:31
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:34
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:454
msgid "Join voice"
msgstr "Připojit se k hovoru"
@@ -18764,6 +18785,7 @@ msgstr "Přejít na nepřečtené kanály"
msgid "Jump between unread channels with mentions"
msgstr "Přejít mezi nepřečtenými kanály se zmínkami"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:121
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:75
msgid "Jump straight to the app to continue."
msgstr "Pokračujte přímo v aplikaci."
@@ -18904,7 +18926,7 @@ msgstr "Ponechat přílohy při vymazání textu během úprav"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Ponechte bezplatnou i prémiovou úroveň. Úrovně můžete přizpůsobit, prodávat prémiové členství přes Stripe nebo později rozdávat dárkové kódy z administračního panelu."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Ponechat dodatečnou lhůtu"
@@ -18918,7 +18940,7 @@ msgstr "Ponechat Neko na místě"
msgid "Keep running"
msgstr "Pokračovat v běhu"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Ponechat předplatné"
@@ -18980,7 +19002,7 @@ msgid "Keyboard mode"
msgstr "Režim navigace klávesnicí"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:59
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:62
msgid "Keyboard shortcut hints in tooltips"
msgstr "Nápověda klávesových zkratek v popiscích"
@@ -19275,8 +19297,8 @@ msgstr "Levé tlačítko myši"
msgid "Left tooltip"
msgstr "Bublina vlevo"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Původní cena"
@@ -20094,7 +20116,7 @@ msgstr "Označit první kanál v doručených zprávách jako přečtený"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:364
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
msgid "Markdown"
msgstr "Markdown"
@@ -20644,7 +20666,7 @@ msgstr "Zmínit tuto roli?"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/guild/components/modals/GuildNotificationSettingsModal.tsx:136
#: src/features/i18n/utils/CommonMessageDescriptors.ts:648
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
msgid "Mentions"
msgstr "Zmínky"
@@ -21158,7 +21180,7 @@ msgid "Missing client_id"
msgstr "Chybí client_id"
#. SSO callback page error shown when the SSO callback is missing code or state parameters.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:24
#: src/features/auth/components/pages/SsoCallbackPage.tsx:26
msgid "Missing SSO code. Sign in again."
msgstr "Chybí kód SSO. Přihlaste se znovu."
@@ -21317,11 +21339,11 @@ msgstr "Měsíčně"
msgid "Monthly {monthlyPrice}"
msgstr "Měsíčně {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Měsíční fakturace začíná dne <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Měsíční fakturace začíná <0>{pendingChangeDate}</0>. První měsíční poplatek: {pendingInitialPriceLabel}. Budoucí měsíční obnovení: {pendingRecurringPriceLabel}/měsíc."
@@ -21756,7 +21778,7 @@ msgstr "ztlumeno"
#. Status label indicating the surface is currently muted.
#: src/features/app/components/layout/sidebar_nav/UseGuildListItemState.ts:23
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:491
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/lib/overlay/OverlayContextMenu.tsx:24
msgid "Muted"
msgstr "Ztlumeno"
@@ -21779,7 +21801,7 @@ msgstr "Mikrofon ztlumený moderátory"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:495
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
msgid "Muted channels"
msgstr "Ztlumené kanály"
@@ -21992,7 +22014,7 @@ msgid "Narrates only the channel you're viewing. Narration follows you between c
msgstr "Předčítá pouze zprávy z kanálu, který si prohlížíte. Při přechodu do jiného kanálu se předčítání přesune s vámi."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
msgid "Narration"
msgstr "Předčítání"
@@ -22057,12 +22079,12 @@ msgid "Need an account?"
msgstr "Potřebujete účet?"
#. Settings search synonym. Proper name of the optional cat sprite that chases the cursor.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
msgid "Neko"
msgstr "Neko"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:63
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:66
msgid "Neko cat that chases your cursor"
msgstr "Kočka Neko, která honí váš kurzor"
@@ -22247,12 +22269,12 @@ msgid "New password"
msgstr "Nové heslo"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Nová cena naplánována na <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Nová cena naplánovaná na <0>{pendingChangeDate}</0>. Obnovení budou od té doby stát {pendingTargetPriceLabel}."
@@ -23560,6 +23582,8 @@ msgid "Open {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName}
msgstr "Otevřete {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName} → {macosScreenRecordingPermissionName} a povolte aplikaci {productName}. Pokud už je přístup pro aplikaci {productName2} zapnutý, úplně ukončete a znovu spusťte aplikaci {productName3}, aby se oprávnění v systému macOS projevilo."
#. Button label that opens the desktop app. productName is the app name.
#. Button that hands SSO sign-in back to the mobile app. productName is the app name.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:34
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:27
msgid "Open {productName}"
msgstr "Otevřít {productName}"
@@ -24945,7 +24969,7 @@ msgstr "Připnout tuto zprávu do kanálu, aby ji všichni viděli."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Voice stats field label (mobile lobby). Shows current latency in ms.
#. Voice stats field label (mobile voice lobby). Shows current latency in ms.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:184
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/voice/components/bottomsheets/DirectCallLobbyBottomSheet.tsx:118
#: src/features/voice/components/bottomsheets/VoiceLobbyBottomSheet.tsx:86
msgid "Ping"
@@ -25165,7 +25189,7 @@ msgid "Popped out"
msgstr "V samostatném okně"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:204
msgid "Popup"
msgstr "Vyskakovací okno"
@@ -26128,7 +26152,7 @@ msgstr "Reakce"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Znovu aktivovat"
@@ -26139,7 +26163,7 @@ msgid "Reactivate subscription"
msgstr "Znovu aktivovat předplatné"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
msgid "Read aloud"
msgstr "Číst nahlas"
@@ -26156,7 +26180,7 @@ msgstr "Číst historii zpráv"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:177
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
msgid "Read messages"
msgstr "Předčítat zprávy"
@@ -26351,8 +26375,8 @@ msgstr "Uplatnit pro sebe"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Uplatnit dárkový kód"
@@ -26630,7 +26654,7 @@ msgstr "Pamatovat si velikost a pozici okna"
#: src/features/user/components/modals/tabs/chat_settings_tab/SearchEnginesTab.tsx:26
#: src/features/user/components/modals/tabs/LinkedAccountsTab.tsx:55
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:178
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:200
#: src/features/webhook/components/WebhookListItem.tsx:277
msgid "Remove"
msgstr "Odebrat"
@@ -27123,7 +27147,7 @@ msgstr "Prahová hodnota obnovení (dny)"
msgid "Renew window (days)"
msgstr "Období obnovení (dny)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Obnoví se dne <0>{renewalDate}.</0>"
@@ -27321,7 +27345,7 @@ msgid "Require a passkey as your second factor"
msgstr "Vyžadovat přístupový klíč jako druhý faktor"
#. Short label for an advanced voice-channel navigation preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:17
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:20
msgid "Require double-click to join voice channels"
msgstr "Vyžadovat dvojklik pro připojení k hlasovým kanálům"
@@ -27872,8 +27896,8 @@ msgstr "Obnovit okno"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Obnovit předplatné"
@@ -29578,7 +29602,7 @@ msgid "Sending malware or dangerous links"
msgstr "Odesílání malwaru nebo nebezpečných odkazů"
#. Short label under a destination row in the forward modal, shown when the community has messaging disabled.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:54
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:55
msgid "Sending messages is disabled in this community"
msgstr "V této komunitě je odesílání zpráv zakázáno"
@@ -30120,7 +30144,7 @@ msgstr "Zkratka"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:55
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:58
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:370
msgid "Shortcut badges"
msgstr "Odznaky zkratek"
@@ -30280,7 +30304,9 @@ msgid "Show delete button"
msgstr "Zobrazit tlačítko smazat"
#. Short label for an advanced media button preference.
#. Toggle label and settings search entry for showing the download app button in the sidebar.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:76
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
msgid "Show download button"
msgstr "Zobrazit tlačítko pro stažení"
@@ -30322,7 +30348,7 @@ msgid "Show favorite button"
msgstr "Zobrazit tlačítko pro přidání do oblíbených"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:87
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:90
msgid "Show favorites throughout the app"
msgstr "Zobrazovat oblíbené položky v celé aplikaci"
@@ -30350,6 +30376,11 @@ msgstr "Zobrazit indikátor GIF"
msgid "Show GIFs button"
msgstr "Zobrazit tlačítko GIFů"
#. Toggle label and settings search entry for showing the help center button in the sidebar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
msgid "Show help center button"
msgstr "Zobrazit tlačítko centra nápovědy"
#. Switch label in the community-folder settings modal. When on, the folder icon is shown in the sidebar while the folder is collapsed.
#: src/features/guild/components/modals/GuildFolderSettingsModal.tsx:77
msgid "Show icon when collapsed"
@@ -30565,7 +30596,7 @@ msgid "Show stickers in expression autocomplete"
msgstr "Zobrazovat samolepky v automatickém doplňování výrazů"
#. Description for a visual accessibility setting that mutes the color of text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:110
msgid "Show strikethrough Markdown text in a slightly muted color."
msgstr "Zobrazit přeškrtnutý text Markdownu v mírně tlumené barvě."
@@ -31008,7 +31039,7 @@ msgid "Slowmode"
msgstr "Pomalý režim"
#. Short label under a destination row in the forward modal while slowmode blocks sending. Preserve {remaining}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:73
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:74
msgid "Slowmode · wait {remaining}"
msgstr "Pomalý režim · čekejte {remaining}"
@@ -31559,7 +31590,7 @@ msgstr "Diváci – {count}"
#. Native macOS Edit submenu title for text-to-speech actions.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/platform/utils/DesktopLocaleBridge.ts:85
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
msgid "Speech"
msgstr "Řeč"
@@ -31670,12 +31701,12 @@ msgstr "Čtvercová tlačítka s ikonami"
msgid "SSO is required to access this workspace."
msgstr "Pro přístup k tomuto pracovnímu prostoru je vyžadováno jednotné přihlášení (SSO)."
#: src/features/auth/components/pages/SsoCallbackPage.tsx:105
#: src/features/auth/components/pages/SsoCallbackPage.tsx:139
msgid "SSO sign-in failed"
msgstr "Přihlášení přes SSO se nezdařilo"
#. SSO callback page error shown when the SSO sign-in timed out before the callback arrived.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:20
#: src/features/auth/components/pages/SsoCallbackPage.tsx:22
msgid "SSO sign-in timed out. Try again."
msgstr "Vypršel časový limit pro přihlášení pomocí jednotného přihlášení. Zkuste to znovu."
@@ -31714,7 +31745,7 @@ msgid "Star animation"
msgstr "Animace hvězdy"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:83
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:86
msgid "Starred channels"
msgstr "Oblíbené kanály"
@@ -31791,7 +31822,7 @@ msgstr "Začít znovu"
msgid "Start recording"
msgstr "Spustit nahrávání"
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:592
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:582
msgid "Start searches with <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> to narrow down results."
msgstr "Pro zúžení výsledků začněte hledání jednou z předpon <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3>."
@@ -31831,7 +31862,7 @@ msgid "Startup"
msgstr "Spuštění"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:75
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:78
msgid "Static Neko"
msgstr "Statická Neko"
@@ -32038,7 +32069,7 @@ msgid "Still indexing — check back in a moment"
msgstr "Indexování stále probíhá – zkuste to za chvíli znovu"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:71
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:74
msgid "Still Neko"
msgstr "Nehybná Neko"
@@ -32067,7 +32098,7 @@ msgid "Stop mic test"
msgstr "Zastavit test mikrofonu"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:70
msgid "Stop Neko from chasing your cursor while keeping it draggable and interactive."
msgstr "Neko přestane honit kurzor, ale bude možné ji nadále přetahovat a interagovat s ní."
@@ -32259,14 +32290,14 @@ msgid "Streaming privacy on"
msgstr "Soukromí při streamování zapnuto"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:111
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
msgid "Strike through"
msgstr "Přeškrtnuté"
#. Selection formatting toolbar button.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/lexical/composer/SelectionFormattingToolbar.tsx:72
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:107
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
msgid "Strikethrough"
msgstr "Přeškrtnuté"
@@ -32490,7 +32521,7 @@ msgid "Switch price"
msgstr "Změnit cenu"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Přejít na {listPriceNewLabel}"
@@ -32515,7 +32546,7 @@ msgstr "Přepnout na přímý vstup"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Přepnout na měsíční platbu"
@@ -32584,7 +32615,7 @@ msgstr "Přepnout na dva sloupce"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Přepnout na roční platbu"
@@ -33074,7 +33105,7 @@ msgstr "Pošlete nám SMS ze svého telefonu"
#. Feature label / section heading for the text-to-speech feature.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:419
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
msgid "Text-to-speech"
msgstr "Převod textu na řeč"
@@ -34133,7 +34164,7 @@ msgid "This member isn't connected to voice anymore."
msgstr "Tento člen už není připojen k hlasovému chatu."
#. Forward dialog error shown when the forwarded message contains age-restricted media and the target channel is not age-restricted.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:68
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:69
msgid "This message can only be forwarded to age-restricted channels"
msgstr "Tuto zprávu lze přeposlat pouze do kanálů s omezeným věkem"
@@ -34766,7 +34797,7 @@ msgid "Toolbar"
msgstr "Panel nástrojů"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:51
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:54
msgid "Tooltip shortcuts"
msgstr "Klávesové zkratky (nápověda)"
@@ -35080,7 +35111,7 @@ msgid "Try sending your message again."
msgstr "Zkuste zprávu odeslat znovu."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
msgid "TTS"
msgstr "TTS"
@@ -35277,7 +35308,7 @@ msgstr "Čtyřiadvacetihodinový formát"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:39
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:42
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:406
msgid "Two clicks"
msgstr "Dvě kliknutí"
@@ -35834,7 +35865,7 @@ msgstr "Odemkněte vlastní emoji v soukromých konverzacích s {premiumProductN
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Odemkněte sdílení obrazovky v HD rozlišení s {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Odemkněte vyšší limity a exkluzivní funkce a zároveň podpořte nezávislou komunikační platformu."
@@ -36044,7 +36075,7 @@ msgstr "nepřečteno"
#. Tab label in the inbox popout filtering to channels with unread messages.
#: src/features/messaging/components/popouts/InboxPopout.tsx:30
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
msgid "Unread"
msgstr "Nepřečtené"
@@ -37866,7 +37897,7 @@ msgstr "Vizuální indikátory stavu uživatele, vykreslené pomocí stejných m
#: src/features/app/components/layout/MobileBottomNav.tsx:123
#: src/features/channel/utils/ChannelUtils.tsx:31
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:17
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
msgid "Voice"
msgstr "Hlas"
@@ -37961,7 +37992,7 @@ msgstr "Hlasový kanál"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:23
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:26
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:402
msgid "Voice channel confirmation"
msgstr "Potvrzení připojení k hlasovému kanálu"
@@ -37972,7 +38003,7 @@ msgid "Voice channel full"
msgstr "Hlasový kanál je plný"
#. Settings search entry label. Names the settings search entry in the settings UI.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:19
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:22
msgid "Voice channel join behavior"
msgstr "Chování při připojení k hlasovému kanálu"
@@ -38099,7 +38130,7 @@ msgstr "Zrušeno"
#: src/features/i18n/utils/CommonMessageDescriptors.ts:378
#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:181
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:183
msgid "Volume"
msgstr "Hlasitost"
@@ -38984,15 +39015,15 @@ msgstr "Ročně {yearlyPrice}"
msgid "Yearly gift"
msgstr "Roční dárek"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Přechod na roční předplatné je naplánovaný na <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Přechod na roční předplatné je naplánovaný na <0>{pendingChangeDate}</0>. První roční platba: {pendingInitialPriceLabel} po započtení kreditu {pendingCreditPriceLabel}. Další roční obnovení: {pendingRecurringPriceLabel}/rok."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Přechod na roční předplatné je naplánovaný na <0>{pendingChangeDate}</0>. První roční platba: {pendingInitialPriceLabel}. Další roční obnovení: {pendingRecurringPriceLabel}/rok."
@@ -39462,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Právě jste stiskli klávesu Tab. Režim klávesnice je nyní zapnutý, takže můžete procházet aplikaci {productName} bez myši."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Výhody si ponecháte do data příštího obnovení. Poté máte dodatečnou lhůtu 3 dnů na obnovení předplatného a zachování jeho historie."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Výhody si ponecháte do data příštího obnovení. Pokud předplatné do té doby znovu aktivujete, zachováte si jeho historii."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Okamžitě ztratíte všechny výhody {PREMIUM_PRODUCT_NAME} a historie vašeho předplatného se resetuje. Tuto akci nelze vrátit zpět."
@@ -39508,12 +39539,12 @@ msgid "You need access to your current email to change it from here. Use phone v
msgstr "Pro změnu e-mailu potřebujete přístup k tomu stávajícímu. Použijte ověření telefonem, pokud je k dispozici, nebo kontaktujte podporu."
#. Forward dialog error shown when the forwarded message has attachments and the user lacks Attach Files in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:63
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:64
msgid "You need the \"{attachFilesPermissionLabel}\" permission to attach files in this channel"
msgstr "K připojení souborů v tomto kanálu potřebujete oprávnění \"{attachFilesPermissionLabel}\""
#. Forward dialog error shown when the forwarded message contains embeds and the user lacks Embed Links in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:58
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:59
msgid "You need the \"{embedLinksPermissionLabel}\" permission to embed links in this channel"
msgstr "K zobrazování vložených náhledů odkazů v tomto kanálu potřebujete oprávnění „{embedLinksPermissionLabel}“"
@@ -40200,6 +40231,11 @@ msgstr "váš region"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Než budete moct pokračovat, je potřeba provést dodatečnou kontrolu proti spamu."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Platba za obnovení předplatného se nezdařila, ale <0/> zůstávají aktivní do <1>{graceDate}</1>. Do té doby aktualizujte způsob platby, abyste si předplatné zachovali."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40221,7 +40257,7 @@ msgstr "Váš stream je stále aktivní"
msgid "Your subscription can't move to the new price right now."
msgstr "Vaše předplatné se momentálně nemůže přesunout na novou cenu."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Vaše předplatné skončilo, ale <0/> zůstávají aktivní do <1>{graceDate}</1>. Do té doby si předplatné obnovte, abyste zachovali jeho historii."
@@ -40250,7 +40286,7 @@ msgstr "Vaše předplatné bylo změněno na měsíční fakturaci."
msgid "Your subscription has been switched to yearly billing."
msgstr "Vaše předplatné bylo změněno na roční fakturaci."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Vaše předplatné je aktivní, ale výhody jsou dočasně pozastaveny."
@@ -40270,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Vaše předplatné přechází na novou cenu {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Vaše předplatné stále končí <0>{cancelDate}</0>. Aktuální cena je {listPriceNewLabel}. Pokud předplatné znovu aktivujete, můžete zde na tuto cenu přejít."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "En opdatering til Linux-appen er tilgængelig. Vælg pakkeformatet for dette system, så gemmer {productName} det lokalt."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "En lavere pris er tilgængelig. Skiftet træder i kraft den <0>{listPriceEffectiveDate}</0> og ændrer intet andet."
@@ -2639,7 +2639,7 @@ msgstr "Få adgang til dine grundlæggende profiloplysninger (brugernavn, avatar
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. User settings tab for accessibility preferences (visual, motion, screen reader, etc.).
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:14
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/SettingsConstants.tsx:61
msgid "Accessibility"
msgstr "Tilgængelighed"
@@ -3487,19 +3487,19 @@ msgstr "Kontroller til placering er kun tilgængelige på bredere skærme"
msgid "All"
msgstr "Alle"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Alle <0/> for <1>{effectiveMonthlyPrice}/måned</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Alle <0/> for <1>{effectiveYearlyPrice}/år</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Alle <0/> er inkluderet i dit abonnement."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Alle <0/>, for evigt. Ingen fakturering, ingen fornyelser."
@@ -4706,7 +4706,7 @@ msgstr "Vedhæftede filer"
#. Generic tab / section / category label for audio content or settings.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:255
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:179
msgid "Audio"
msgstr "Lyd"
@@ -6210,7 +6210,7 @@ msgid "California"
msgstr "Californien"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
msgid "Call"
msgstr "Opkald"
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Annuller import"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Annuller prisændring"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Annuller anmodning"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Annuller planlagt skift"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Opsig abonnement"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Opsig abonnement?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Annuller den planlagte ændring for at skifte til den aktuelle pris i stedet."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Annuller upload"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Annuller årlig opgradering"
@@ -6530,7 +6530,7 @@ msgstr "Opsigelse planlagt"
msgid "Cancellation"
msgstr "Ekkoannullering"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Udløber efter opsigelse den <0>{cancelDate}</0>. <1/> forbliver aktive indtil da."
@@ -7088,7 +7088,7 @@ msgid "Channel"
msgstr "Kanal"
#. Fallback name for an unnamed channel in the forward modal destination list. Preserve {id}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:78
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:79
msgid "Channel {id}"
msgstr "Kanal {id}"
@@ -7317,7 +7317,7 @@ msgid "Chat font size"
msgstr "Skriftstørrelse i chat"
#. Settings search synonym. Refers to the message composer area.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
msgid "chat input"
msgstr "chatinput"
@@ -8726,7 +8726,7 @@ msgid "Community updated"
msgstr "Fællesskab opdateret"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:35
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:38
msgid "Community voice"
msgstr "Tale i fællesskaber"
@@ -8789,12 +8789,13 @@ msgstr "Gennemfør den påkrævede bekræftelse for at fortsætte med at bruge {
msgid "Completely hide your {premiumProductName} badge from other users"
msgstr "Skjul dit {premiumProductName}-badge fuldstændigt for andre brugere"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:134
#: src/features/auth/components/pages/SsoCallbackPage.tsx:118
#: src/features/auth/components/pages/SsoCallbackPage.tsx:168
#: src/features/auth/flow/HandoffApprovalFlow.tsx:218
msgid "Completing sign-in…"
msgstr "Logger dig ind…"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:138
#: src/features/auth/components/pages/SsoCallbackPage.tsx:172
msgid "Completing your sign-in…"
msgstr "Fuldfører dit login…"
@@ -8912,8 +8913,8 @@ msgstr "Bekræft"
#. Settings search entry label. Names the settings search entry in the settings UI.
#. Short label for an advanced voice-channel safety preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:21
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:15
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:24
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:18
msgid "Confirm before joining voice channels"
msgstr "Bekræft, før du deltager i talekanaler"
@@ -8952,7 +8953,7 @@ msgstr "Bekræft adgangskode"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:27
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:30
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:398
msgid "Confirm voice join"
msgstr "Bekræft deltagelse i taleopkald"
@@ -8963,7 +8964,7 @@ msgid "Confirmation"
msgstr "Bekræftelse"
#. Settings search entry description. One-line summary of what the settings search entry controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:43
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:46
msgid "Confirmation or double-click for community voice joins"
msgstr "Bekræftelse eller dobbeltklik ved deltagelse i fællesskabets talekanaler"
@@ -9200,7 +9201,7 @@ msgstr "Adgangskontrol for indhold"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/ui/action_menu/ContextMenu.tsx:23
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:225
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
msgid "Context menu"
msgstr "Kontekstmenu"
@@ -10871,7 +10872,7 @@ msgstr "Tilpasset…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Kundeportal"
@@ -11341,7 +11342,7 @@ msgstr "Delaware"
#: src/features/user/components/modals/tabs/component_gallery_tab/ComponentGalleryTabButtonsTab.tsx:290
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:238
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:174
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
msgid "Delete"
msgstr "Slet"
@@ -11626,7 +11627,7 @@ msgid "Deleted {duration} of the member's recent message history"
msgstr "Slettede {duration} af medlemmets seneste beskedhistorik"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
msgid "Deleted text"
msgstr "Slettet tekst"
@@ -12028,7 +12029,7 @@ msgid "Different sizes & member counts"
msgstr "Forskellige størrelser og antal medlemmer"
#. Toggle label and settings search entry for slightly muting text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:106
msgid "Dim strikethrough text"
msgstr "Dæmp gennemstreget tekst"
@@ -12043,7 +12044,7 @@ msgstr "Direkte input"
#: src/features/channel/components/bottomsheets/channel_details_bottom_sheet/ChannelDetailsBottomSheetShared.ts:14
#: src/features/channel/components/channel_header_components/developer_tools/MockingMenu.tsx:398
#: src/features/i18n/utils/CommonMessageDescriptors.ts:567
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
msgid "Direct message"
msgstr "Direkte besked"
@@ -12480,7 +12481,7 @@ msgid "District of Columbia"
msgstr "District of Columbia"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:180
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
msgid "DM"
msgstr "DM"
@@ -12735,6 +12736,16 @@ msgstr "Download {productName}"
msgid "Download <0>fluxer-verification</0> and place it in your <1>.well-known</1> folder so we can validate the domain."
msgstr "Download <0>fluxer-verification</0>, og læg den i din <1>.well-known</1>-mappe, så vi kan validere domænet."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:98
msgid "Download app"
msgstr "Download app"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:106
msgid "Download app button in the sidebar"
msgstr "Download app-knap i sidebjælken"
#. Media context menu action that downloads an audio attachment.
#: src/features/ui/action_menu/items/MediaMenuData.tsx:122
msgid "Download audio"
@@ -13433,7 +13444,7 @@ msgstr "Indlejringer vises igen"
#: src/features/app/config/AuditLogConstants.ts:167
#: src/features/emoji/components/emojis/EmojiListItem.tsx:337
#: src/features/theme_studio/sections/TokenGroups.ts:114
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
msgid "Emoji"
msgstr "Emoji"
@@ -13866,15 +13877,15 @@ msgid "End date"
msgstr "Slutdato"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Afslut overgangsperiode nu"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Afslut overgangsperiode"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Afslut overgangsperiode nu?"
@@ -14681,7 +14692,7 @@ msgid "Failed to clear trusted domains."
msgstr "Kunne ikke rydde godkendte domæner."
#. Short label in the authentication SSO callback page. Keep the tone plain and specific.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:28
#: src/features/auth/components/pages/SsoCallbackPage.tsx:30
msgid "Failed to complete SSO sign-in"
msgstr "SSO-login kunne ikke gennemføres"
@@ -15027,7 +15038,7 @@ msgid "Favorite channel"
msgstr "Føj kanal til favoritter"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:79
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:82
msgid "Favorite channels"
msgstr "Favoritkanaler"
@@ -15800,7 +15811,7 @@ msgstr "Venlig bot"
#: src/features/connection/components/modals/EditConnectionModal.tsx:86
#: src/features/search/utils/QuickSwitcherModalUtils.tsx:50
#: src/features/user/components/modals/tabs/my_profile_tab/TimezoneProfileSettings.tsx:63
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
msgid "Friends"
msgstr "Venner"
@@ -16145,7 +16156,7 @@ msgstr "Hent den nye {productName}-app"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Type label for GIF media.
#: src/features/expressions/utils/FavoriteMemeUtils.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
msgid "GIF"
msgstr "GIF"
@@ -16336,7 +16347,7 @@ msgstr "Gave: udløber snart"
msgid "Gift: grace period (still have access)"
msgstr "Gave: overgangsperiode (har stadig adgang)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Du har fået <0/> i gave indtil <1>{giftEndDate}</1>. Fornyes ikke automatisk. Indløs flere gavekoder for at forlænge perioden."
@@ -16549,7 +16560,7 @@ msgid "Graphics"
msgstr "Grafik"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
msgid "Gray text"
msgstr "Grå tekst"
@@ -16815,7 +16826,7 @@ msgid "Hate speech"
msgstr "Hadefuld tale"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Har du en gavekode? Indløs den for at låse op for {PREMIUM_PRODUCT_NAME}."
@@ -16896,11 +16907,21 @@ msgstr "Hej, {username}! Dejligt at have dig her."
msgid "Help"
msgstr "Hjælp"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:94
msgid "Help button"
msgstr "Hjælp-knap"
#. Short label in the sidebar navigation help button.
#: src/features/app/components/layout/sidebar_nav/HelpButton.tsx:27
msgid "Help center"
msgstr "Hjælpecenter"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:102
msgid "Help center button in the sidebar"
msgstr "Hjælpecenterknap i sidebjælken"
#: src/features/user/components/modals/tabs/LanguageTab.tsx:348
msgid "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
msgstr "Hjælp med at oversætte {PRODUCT_NAME} til dit sprog på <0>{I18N_WEBLATE_DOMAIN}</0>."
@@ -17035,7 +17056,7 @@ msgid "Hide join messages"
msgstr "Skjul beskeder om nye medlemmer"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:47
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:50
msgid "Hide keyboard hints"
msgstr "Skjul tastaturvejledninger"
@@ -18721,7 +18742,7 @@ msgstr "Deltag i videoopkald"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/profile/VoiceActivityCard.tsx:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:31
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:34
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:454
msgid "Join voice"
msgstr "Deltag i talechat"
@@ -18764,6 +18785,7 @@ msgstr "Skift mellem ulæste kanaler"
msgid "Jump between unread channels with mentions"
msgstr "Skift mellem ulæste kanaler med omtaler"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:121
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:75
msgid "Jump straight to the app to continue."
msgstr "Gå direkte til appen for at fortsætte."
@@ -18904,7 +18926,7 @@ msgstr "Behold vedhæftede filer, når du rydder en redigering"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Behold gratis og premium-niveauer. Du kan tilpasse niveauerne, sælge premium via Stripe eller uddele gavekoder senere fra adminpanelet."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Behold overgangsperioden"
@@ -18918,7 +18940,7 @@ msgstr "Hold Neko stille"
msgid "Keep running"
msgstr "Fortsæt med at køre"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Behold abonnement"
@@ -18980,7 +19002,7 @@ msgid "Keyboard mode"
msgstr "Tastaturtilstand"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:59
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:62
msgid "Keyboard shortcut hints in tooltips"
msgstr "Vis genvejstips i værktøjstips"
@@ -19275,8 +19297,8 @@ msgstr "Venstre museknap"
msgid "Left tooltip"
msgstr "Værktøjstip til venstre"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Gammel pris"
@@ -20094,7 +20116,7 @@ msgstr "Markér den øverste kanal i indbakken som læst"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:364
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
msgid "Markdown"
msgstr "Markdown"
@@ -20644,7 +20666,7 @@ msgstr "Vil du omtale denne rolle?"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/guild/components/modals/GuildNotificationSettingsModal.tsx:136
#: src/features/i18n/utils/CommonMessageDescriptors.ts:648
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
msgid "Mentions"
msgstr "Omtaler"
@@ -21158,7 +21180,7 @@ msgid "Missing client_id"
msgstr "Manglende client_id"
#. SSO callback page error shown when the SSO callback is missing code or state parameters.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:24
#: src/features/auth/components/pages/SsoCallbackPage.tsx:26
msgid "Missing SSO code. Sign in again."
msgstr "SSO-kode mangler. Log ind igen."
@@ -21317,11 +21339,11 @@ msgstr "Månedligt"
msgid "Monthly {monthlyPrice}"
msgstr "Månedligt {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Månedlig fakturering starter den <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Månedlig fakturering starter den <0>{pendingChangeDate}</0>. Første månedlige betaling: {pendingInitialPriceLabel}. Fremtidige månedlige fornyelser: {pendingRecurringPriceLabel}/måned."
@@ -21756,7 +21778,7 @@ msgstr "sat på lydløs"
#. Status label indicating the surface is currently muted.
#: src/features/app/components/layout/sidebar_nav/UseGuildListItemState.ts:23
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:491
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/lib/overlay/OverlayContextMenu.tsx:24
msgid "Muted"
msgstr "Sat på lydløs"
@@ -21779,7 +21801,7 @@ msgstr "Mikrofonen er slået fra af moderatorer"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:495
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
msgid "Muted channels"
msgstr "Kanaler sat på lydløs"
@@ -21992,7 +22014,7 @@ msgid "Narrates only the channel you're viewing. Narration follows you between c
msgstr "Oplæser kun den kanal, du ser. Oplæsningen følger dig mellem kanaler."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
msgid "Narration"
msgstr "Oplæsning"
@@ -22057,12 +22079,12 @@ msgid "Need an account?"
msgstr "Har du brug for en konto?"
#. Settings search synonym. Proper name of the optional cat sprite that chases the cursor.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
msgid "Neko"
msgstr "Neko"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:63
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:66
msgid "Neko cat that chases your cursor"
msgstr "Neko-kat, der jager din markør"
@@ -22247,12 +22269,12 @@ msgid "New password"
msgstr "Ny adgangskode"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Ny pris planlagt til <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Ny pris planlagt til <0>{pendingChangeDate}</0>. Fornyelser vil koste {pendingTargetPriceLabel} derefter."
@@ -23560,6 +23582,8 @@ msgid "Open {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName}
msgstr "Åbn {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName} → {macosScreenRecordingPermissionName}, og tillad derefter, at {productName} bruger skærmoptagelse. Hvis {productName2} allerede er aktiveret, skal du lukke {productName3} helt ned og genstarte det, så macOS anvender tilladelsen."
#. Button label that opens the desktop app. productName is the app name.
#. Button that hands SSO sign-in back to the mobile app. productName is the app name.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:34
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:27
msgid "Open {productName}"
msgstr "Åbn {productName}"
@@ -24945,7 +24969,7 @@ msgstr "Fastgør denne besked til kanalen, så alle kan se den."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Voice stats field label (mobile lobby). Shows current latency in ms.
#. Voice stats field label (mobile voice lobby). Shows current latency in ms.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:184
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/voice/components/bottomsheets/DirectCallLobbyBottomSheet.tsx:118
#: src/features/voice/components/bottomsheets/VoiceLobbyBottomSheet.tsx:86
msgid "Ping"
@@ -25165,7 +25189,7 @@ msgid "Popped out"
msgstr "Åbnet i separat vindue"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:204
msgid "Popup"
msgstr "Pop op-vindue"
@@ -26128,7 +26152,7 @@ msgstr "Reaktioner"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Genaktiver"
@@ -26139,7 +26163,7 @@ msgid "Reactivate subscription"
msgstr "Genaktiver abonnement"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
msgid "Read aloud"
msgstr "Læs højt"
@@ -26156,7 +26180,7 @@ msgstr "Læs beskedhistorik"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:177
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
msgid "Read messages"
msgstr "Læs beskeder"
@@ -26351,8 +26375,8 @@ msgstr "Indløs til dig selv"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Indløs gavekode"
@@ -26630,7 +26654,7 @@ msgstr "Husk vinduesstørrelse og -placering"
#: src/features/user/components/modals/tabs/chat_settings_tab/SearchEnginesTab.tsx:26
#: src/features/user/components/modals/tabs/LinkedAccountsTab.tsx:55
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:178
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:200
#: src/features/webhook/components/WebhookListItem.tsx:277
msgid "Remove"
msgstr "Fjern"
@@ -27123,7 +27147,7 @@ msgstr "Fornyelsestærskel (dage)"
msgid "Renew window (days)"
msgstr "Fornyelsesvindue (dage)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Fornyes den <0>{renewalDate}.</0>"
@@ -27321,7 +27345,7 @@ msgid "Require a passkey as your second factor"
msgstr "Kræv en adgangsnøgle som din anden faktor"
#. Short label for an advanced voice-channel navigation preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:17
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:20
msgid "Require double-click to join voice channels"
msgstr "Kræv dobbeltklik for at deltage i talekanaler"
@@ -27872,8 +27896,8 @@ msgstr "Gendan vindue"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Forny abonnement"
@@ -29578,7 +29602,7 @@ msgid "Sending malware or dangerous links"
msgstr "Sender malware eller farlige links"
#. Short label under a destination row in the forward modal, shown when the community has messaging disabled.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:54
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:55
msgid "Sending messages is disabled in this community"
msgstr "Afsendelse af beskeder er deaktiveret i dette fællesskab"
@@ -30120,7 +30144,7 @@ msgstr "Genvej"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:55
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:58
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:370
msgid "Shortcut badges"
msgstr "Genvejsikoner"
@@ -30280,7 +30304,9 @@ msgid "Show delete button"
msgstr "Vis slet-knap"
#. Short label for an advanced media button preference.
#. Toggle label and settings search entry for showing the download app button in the sidebar.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:76
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
msgid "Show download button"
msgstr "Vis download-knap"
@@ -30322,7 +30348,7 @@ msgid "Show favorite button"
msgstr "Vis favoritknap"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:87
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:90
msgid "Show favorites throughout the app"
msgstr "Vis favoritter i hele appen"
@@ -30350,6 +30376,11 @@ msgstr "Vis GIF-indikator"
msgid "Show GIFs button"
msgstr "Vis GIF-knap"
#. Toggle label and settings search entry for showing the help center button in the sidebar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
msgid "Show help center button"
msgstr "Vis knappen Hjælp"
#. Switch label in the community-folder settings modal. When on, the folder icon is shown in the sidebar while the folder is collapsed.
#: src/features/guild/components/modals/GuildFolderSettingsModal.tsx:77
msgid "Show icon when collapsed"
@@ -30565,7 +30596,7 @@ msgid "Show stickers in expression autocomplete"
msgstr "Vis klistermærker i autofuldførelse af udtryk"
#. Description for a visual accessibility setting that mutes the color of text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:110
msgid "Show strikethrough Markdown text in a slightly muted color."
msgstr "Vis gennemstreget Markdown-tekst i en let afdæmpet farve."
@@ -31008,7 +31039,7 @@ msgid "Slowmode"
msgstr "Langsom tilstand"
#. Short label under a destination row in the forward modal while slowmode blocks sending. Preserve {remaining}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:73
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:74
msgid "Slowmode · wait {remaining}"
msgstr "Langsom tilstand · vent {remaining}"
@@ -31559,7 +31590,7 @@ msgstr "Seere - {count}"
#. Native macOS Edit submenu title for text-to-speech actions.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/platform/utils/DesktopLocaleBridge.ts:85
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
msgid "Speech"
msgstr "Tale"
@@ -31670,12 +31701,12 @@ msgstr "Firkantede ikonknapper"
msgid "SSO is required to access this workspace."
msgstr "SSO er påkrævet for at få adgang til dette arbejdsområde."
#: src/features/auth/components/pages/SsoCallbackPage.tsx:105
#: src/features/auth/components/pages/SsoCallbackPage.tsx:139
msgid "SSO sign-in failed"
msgstr "SSO-login mislykkedes"
#. SSO callback page error shown when the SSO sign-in timed out before the callback arrived.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:20
#: src/features/auth/components/pages/SsoCallbackPage.tsx:22
msgid "SSO sign-in timed out. Try again."
msgstr "Tidsfristen for SSO-login blev overskredet. Prøv igen."
@@ -31714,7 +31745,7 @@ msgid "Star animation"
msgstr "Stjerneanimation"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:83
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:86
msgid "Starred channels"
msgstr "Favoritkanaler"
@@ -31791,7 +31822,7 @@ msgstr "Start forfra"
msgid "Start recording"
msgstr "Start optagelse"
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:592
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:582
msgid "Start searches with <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> to narrow down results."
msgstr "Start søgninger med <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> for at indsnævre resultaterne."
@@ -31831,7 +31862,7 @@ msgid "Startup"
msgstr "Opstart"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:75
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:78
msgid "Static Neko"
msgstr "Statisk Neko"
@@ -32038,7 +32069,7 @@ msgid "Still indexing — check back in a moment"
msgstr "Indekserer stadig – prøv igen om et øjeblik"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:71
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:74
msgid "Still Neko"
msgstr "Stillestående Neko"
@@ -32067,7 +32098,7 @@ msgid "Stop mic test"
msgstr "Stop mikrofontest"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:70
msgid "Stop Neko from chasing your cursor while keeping it draggable and interactive."
msgstr "Lad Neko blive stående i stedet for at følge markøren. Du kan stadig trække og interagere med katten."
@@ -32259,14 +32290,14 @@ msgid "Streaming privacy on"
msgstr "Privatlivsbeskyttelse under streaming slået til"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:111
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
msgid "Strike through"
msgstr "Gennemstreget"
#. Selection formatting toolbar button.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/lexical/composer/SelectionFormattingToolbar.tsx:72
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:107
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
msgid "Strikethrough"
msgstr "Gennemstreget"
@@ -32490,7 +32521,7 @@ msgid "Switch price"
msgstr "Skift pris"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Skift til {listPriceNewLabel}"
@@ -32515,7 +32546,7 @@ msgstr "Skift til direkte input"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Skift til månedligt abonnement"
@@ -32584,7 +32615,7 @@ msgstr "Skift til to kolonner"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Skift til årligt abonnement"
@@ -33074,7 +33105,7 @@ msgstr "Send os en sms fra din telefon"
#. Feature label / section heading for the text-to-speech feature.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:419
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
msgid "Text-to-speech"
msgstr "Tekst til tale"
@@ -34133,7 +34164,7 @@ msgid "This member isn't connected to voice anymore."
msgstr "Dette medlem er ikke længere i taleopkaldet."
#. Forward dialog error shown when the forwarded message contains age-restricted media and the target channel is not age-restricted.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:68
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:69
msgid "This message can only be forwarded to age-restricted channels"
msgstr "Denne besked kan kun videresendes til kanaler med aldersbegrænsning"
@@ -34766,7 +34797,7 @@ msgid "Toolbar"
msgstr "Værktøjslinje"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:51
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:54
msgid "Tooltip shortcuts"
msgstr "Genvejsværktøjstip"
@@ -35080,7 +35111,7 @@ msgid "Try sending your message again."
msgstr "Prøv at sende din besked igen."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
msgid "TTS"
msgstr "TTS"
@@ -35277,7 +35308,7 @@ msgstr "24-timersformat"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:39
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:42
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:406
msgid "Two clicks"
msgstr "To klik"
@@ -35834,7 +35865,7 @@ msgstr "Lås op for tilpassede emojis i direkte beskeder med {premiumProductName
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Lås op for HD-skærmdeling med {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Lås op for højere grænser og eksklusive funktioner, og støt samtidig en uafhængig kommunikationsplatform."
@@ -36044,7 +36075,7 @@ msgstr "ulæst"
#. Tab label in the inbox popout filtering to channels with unread messages.
#: src/features/messaging/components/popouts/InboxPopout.tsx:30
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
msgid "Unread"
msgstr "Ulæst"
@@ -37866,7 +37897,7 @@ msgstr "Visuelle indikatorer, der viser brugerstatus, gengivet med de samme mask
#: src/features/app/components/layout/MobileBottomNav.tsx:123
#: src/features/channel/utils/ChannelUtils.tsx:31
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:17
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
msgid "Voice"
msgstr "Tale"
@@ -37961,7 +37992,7 @@ msgstr "Talekanal"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:23
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:26
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:402
msgid "Voice channel confirmation"
msgstr "Bekræftelse før deltagelse i talekanal"
@@ -37972,7 +38003,7 @@ msgid "Voice channel full"
msgstr "Talekanalen er fuld"
#. Settings search entry label. Names the settings search entry in the settings UI.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:19
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:22
msgid "Voice channel join behavior"
msgstr "Indstillinger for deltagelse i talekanal"
@@ -38099,7 +38130,7 @@ msgstr "Annulleret"
#: src/features/i18n/utils/CommonMessageDescriptors.ts:378
#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:181
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:183
msgid "Volume"
msgstr "Lydstyrke"
@@ -38984,15 +39015,15 @@ msgstr "Årligt {yearlyPrice}"
msgid "Yearly gift"
msgstr "Gave på et år"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Årlig opgradering planlagt til <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Årlig opgradering planlagt til <0>{pendingChangeDate}</0>. Første årlige betaling: {pendingInitialPriceLabel} efter modregning af {pendingCreditPriceLabel}. Fremtidige årlige fornyelser: {pendingRecurringPriceLabel}/år."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Årlig opgradering planlagt til <0>{pendingChangeDate}</0>. Første årlige betaling: {pendingInitialPriceLabel}. Fremtidige årlige fornyelser: {pendingRecurringPriceLabel}/år."
@@ -39462,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Du har lige trykket på Tab. Tastaturtilstand er nu slået til, så du kan navigere i {productName} uden en mus."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Du beholder dine fordele indtil din næste fornyelsesdato og har derefter en overgangsperiode på 3 dage til at tegne abonnement igen og bevare din abonnementshistorik."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Du beholder dine fordele indtil din næste fornyelsesdato. Genaktiver inden da for at bevare din abonnementshistorik."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Du mister alle dine {PREMIUM_PRODUCT_NAME}-fordele med det samme, og din abonnementshistorik nulstilles. Dette kan ikke fortrydes."
@@ -39508,12 +39539,12 @@ msgid "You need access to your current email to change it from here. Use phone v
msgstr "Du skal have adgang til din nuværende e-mail for at ændre den herfra. Brug telefonbekræftelse, hvis det er muligt, eller kontakt support."
#. Forward dialog error shown when the forwarded message has attachments and the user lacks Attach Files in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:63
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:64
msgid "You need the \"{attachFilesPermissionLabel}\" permission to attach files in this channel"
msgstr "Du skal have tilladelsen \"{attachFilesPermissionLabel}\" for at vedhæfte filer i denne kanal"
#. Forward dialog error shown when the forwarded message contains embeds and the user lacks Embed Links in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:58
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:59
msgid "You need the \"{embedLinksPermissionLabel}\" permission to embed links in this channel"
msgstr "Du skal have tilladelsen \"{embedLinksPermissionLabel}\" for at kunne indlejre links i denne kanal"
@@ -40200,6 +40231,11 @@ msgstr "din region"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Din registrering kræver et ekstra anti-spam-tjek, før du kan fortsætte."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Din fornyelsesbetaling mislykkedes, men <0/> forbliver aktive indtil <1>{graceDate}</1>. Opdater din betalingsmetode inden da for at beholde dit abonnement."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40221,7 +40257,7 @@ msgstr "Din stream er stadig live"
msgid "Your subscription can't move to the new price right now."
msgstr "Dit abonnement kan ikke flyttes til den nye pris lige nu."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Dit abonnement er udløbet, men <0/> forbliver aktive indtil <1>{graceDate}</1>. Tegn abonnement igen inden da for at bevare din abonnementshistorik."
@@ -40250,7 +40286,7 @@ msgstr "Dit abonnement er nu skiftet til månedlig fakturering."
msgid "Your subscription has been switched to yearly billing."
msgstr "Dit abonnement er blevet skiftet til årlig fakturering."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Dit abonnement er aktivt, men fordelene er midlertidigt sat på pause."
@@ -40270,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Dit abonnement skifter til den nye pris den {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Dit abonnement udløber stadig den <0>{cancelDate}</0>. Den aktuelle pris er nu {listPriceNewLabel}. Hvis du genaktiverer, kan du skifte til den herfra."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Ein Desktop-Update für Linux ist verfügbar. Wähle das Paketformat für dieses System und {productName} speichert es lokal."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Ein niedrigerer Preis ist verfügbar. Der Wechsel wird am <0>{listPriceEffectiveDate}</0> wirksam und ändert nichts weiter."
@@ -2639,7 +2639,7 @@ msgstr "Auf deine grundlegenden Profilinformationen (Benutzername, Avatar usw.)
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. User settings tab for accessibility preferences (visual, motion, screen reader, etc.).
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:14
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/SettingsConstants.tsx:61
msgid "Accessibility"
msgstr "Bedienungshilfen"
@@ -3487,19 +3487,19 @@ msgstr "Ausrichtungsoptionen sind nur auf breiteren Bildschirmen verfügbar"
msgid "All"
msgstr "Alle"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Alle <0/> für <1>{effectiveMonthlyPrice}/Monat</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Alle <0/> für <1>{effectiveYearlyPrice}/Jahr</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Alle <0/> sind in deinem Abonnement enthalten."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Alle <0/>, für immer. Keine Abrechnung, keine Verlängerungen."
@@ -4706,7 +4706,7 @@ msgstr "Anhänge"
#. Generic tab / section / category label for audio content or settings.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:255
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:179
msgid "Audio"
msgstr "Audio"
@@ -6210,7 +6210,7 @@ msgid "California"
msgstr "Kalifornien"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
msgid "Call"
msgstr "Anruf"
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Import abbrechen"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Preisänderung abbrechen"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Anfrage zurückziehen"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Geplante Umstellung abbrechen"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Abo kündigen"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Abo kündigen?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Brich die geplante Änderung ab, um stattdessen zum aktuellen Preis zu wechseln."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Upload abbrechen"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Wechsel zum Jahresabonnement abbrechen"
@@ -6530,7 +6530,7 @@ msgstr "Wird gekündigt"
msgid "Cancellation"
msgstr "Echo-Unterdrückung"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Kündigung am <0>{cancelDate}</0>. <1/> bleiben bis dahin aktiv."
@@ -7088,7 +7088,7 @@ msgid "Channel"
msgstr "Kanal"
#. Fallback name for an unnamed channel in the forward modal destination list. Preserve {id}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:78
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:79
msgid "Channel {id}"
msgstr "Kanal {id}"
@@ -7317,7 +7317,7 @@ msgid "Chat font size"
msgstr "Schriftgröße im Chat"
#. Settings search synonym. Refers to the message composer area.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
msgid "chat input"
msgstr "Chateingabe"
@@ -8726,7 +8726,7 @@ msgid "Community updated"
msgstr "Community aktualisiert"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:35
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:38
msgid "Community voice"
msgstr "Community-Sprachchat"
@@ -8789,12 +8789,13 @@ msgstr "Schließe die erforderliche Verifizierung ab, um {productName} weiterhin
msgid "Completely hide your {premiumProductName} badge from other users"
msgstr "Dein {premiumProductName}-Abzeichen vollständig vor anderen Nutzern verbergen"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:134
#: src/features/auth/components/pages/SsoCallbackPage.tsx:118
#: src/features/auth/components/pages/SsoCallbackPage.tsx:168
#: src/features/auth/flow/HandoffApprovalFlow.tsx:218
msgid "Completing sign-in…"
msgstr "Anmeldung wird abgeschlossen …"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:138
#: src/features/auth/components/pages/SsoCallbackPage.tsx:172
msgid "Completing your sign-in…"
msgstr "Anmeldung wird abgeschlossen …"
@@ -8912,8 +8913,8 @@ msgstr "Bestätigen"
#. Settings search entry label. Names the settings search entry in the settings UI.
#. Short label for an advanced voice-channel safety preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:21
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:15
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:24
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:18
msgid "Confirm before joining voice channels"
msgstr "Vor Beitritt zu Sprachkanälen bestätigen"
@@ -8952,7 +8953,7 @@ msgstr "Passwort bestätigen"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:27
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:30
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:398
msgid "Confirm voice join"
msgstr "Beitritt zum Sprachchat bestätigen"
@@ -8963,7 +8964,7 @@ msgid "Confirmation"
msgstr "Bestätigung"
#. Settings search entry description. One-line summary of what the settings search entry controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:43
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:46
msgid "Confirmation or double-click for community voice joins"
msgstr "Bestätigung oder Doppelklick zum Beitreten zu einem Sprachkanal in der Community"
@@ -9200,7 +9201,7 @@ msgstr "Prüfungen zum Schutz vor ungeeigneten Inhalten"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/ui/action_menu/ContextMenu.tsx:23
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:225
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
msgid "Context menu"
msgstr "Kontextmenü"
@@ -10871,7 +10872,7 @@ msgstr "Benutzerdefiniert …"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Kundenportal"
@@ -11341,7 +11342,7 @@ msgstr "Delaware"
#: src/features/user/components/modals/tabs/component_gallery_tab/ComponentGalleryTabButtonsTab.tsx:290
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:238
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:174
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
msgid "Delete"
msgstr "Löschen"
@@ -11626,7 +11627,7 @@ msgid "Deleted {duration} of the member's recent message history"
msgstr "Den Nachrichtenverlauf des Mitglieds für den Zeitraum {duration} gelöscht"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
msgid "Deleted text"
msgstr "Gelöschter Text"
@@ -12028,7 +12029,7 @@ msgid "Different sizes & member counts"
msgstr "Verschiedene Größen & Mitgliederzahlen"
#. Toggle label and settings search entry for slightly muting text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:106
msgid "Dim strikethrough text"
msgstr "Durchgestrichenen Text abdunkeln"
@@ -12043,7 +12044,7 @@ msgstr "Direkteingabe"
#: src/features/channel/components/bottomsheets/channel_details_bottom_sheet/ChannelDetailsBottomSheetShared.ts:14
#: src/features/channel/components/channel_header_components/developer_tools/MockingMenu.tsx:398
#: src/features/i18n/utils/CommonMessageDescriptors.ts:567
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
msgid "Direct message"
msgstr "Direktnachricht"
@@ -12480,7 +12481,7 @@ msgid "District of Columbia"
msgstr "District of Columbia"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:180
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
msgid "DM"
msgstr "DM"
@@ -12735,6 +12736,16 @@ msgstr "{productName} herunterladen"
msgid "Download <0>fluxer-verification</0> and place it in your <1>.well-known</1> folder so we can validate the domain."
msgstr "Lade <0>fluxer-verification</0> herunter und lege die Datei in deinem Ordner <1>.well-known</1> ab, damit wir die Domain überprüfen können."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:98
msgid "Download app"
msgstr "App herunterladen"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:106
msgid "Download app button in the sidebar"
msgstr "App herunterladen"
#. Media context menu action that downloads an audio attachment.
#: src/features/ui/action_menu/items/MediaMenuData.tsx:122
msgid "Download audio"
@@ -13433,7 +13444,7 @@ msgstr "Einbettungen nicht unterdrückt"
#: src/features/app/config/AuditLogConstants.ts:167
#: src/features/emoji/components/emojis/EmojiListItem.tsx:337
#: src/features/theme_studio/sections/TokenGroups.ts:114
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
msgid "Emoji"
msgstr "Emoji"
@@ -13866,15 +13877,15 @@ msgid "End date"
msgstr "Enddatum"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Übergangsfrist jetzt beenden"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Übergangsfrist beenden"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Übergangsfrist jetzt beenden?"
@@ -14681,7 +14692,7 @@ msgid "Failed to clear trusted domains."
msgstr "Vertrauenswürdige Domains konnten nicht gelöscht werden."
#. Short label in the authentication SSO callback page. Keep the tone plain and specific.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:28
#: src/features/auth/components/pages/SsoCallbackPage.tsx:30
msgid "Failed to complete SSO sign-in"
msgstr "SSO-Anmeldung fehlgeschlagen"
@@ -15027,7 +15038,7 @@ msgid "Favorite channel"
msgstr "Kanal favorisieren"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:79
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:82
msgid "Favorite channels"
msgstr "Lieblingskanäle"
@@ -15800,7 +15811,7 @@ msgstr "Freundlicher Bot"
#: src/features/connection/components/modals/EditConnectionModal.tsx:86
#: src/features/search/utils/QuickSwitcherModalUtils.tsx:50
#: src/features/user/components/modals/tabs/my_profile_tab/TimezoneProfileSettings.tsx:63
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
msgid "Friends"
msgstr "Freunde"
@@ -16145,7 +16156,7 @@ msgstr "Hol dir die neue {productName}-App"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Type label for GIF media.
#: src/features/expressions/utils/FavoriteMemeUtils.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
msgid "GIF"
msgstr "GIF"
@@ -16336,7 +16347,7 @@ msgstr "Geschenk: läuft bald ab"
msgid "Gift: grace period (still have access)"
msgstr "Geschenk: Übergangsfrist (Zugriff weiterhin möglich)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "<0/> als Geschenk bis <1>{giftEndDate}</1> erhalten. Wird nicht automatisch verlängert. Löse weitere Geschenkcodes ein, um die Laufzeit zu verlängern."
@@ -16549,7 +16560,7 @@ msgid "Graphics"
msgstr "Grafiken"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
msgid "Gray text"
msgstr "Grauer Text"
@@ -16815,7 +16826,7 @@ msgid "Hate speech"
msgstr "Hassrede"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Hast du einen Geschenke-Code? Löse ihn ein, um {PREMIUM_PRODUCT_NAME} freizuschalten."
@@ -16896,11 +16907,21 @@ msgstr "Hallo, {username}! Schön, dass du da bist."
msgid "Help"
msgstr "Hilfe"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:94
msgid "Help button"
msgstr "Hilfe-Schaltfläche"
#. Short label in the sidebar navigation help button.
#: src/features/app/components/layout/sidebar_nav/HelpButton.tsx:27
msgid "Help center"
msgstr "Hilfebereich"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:102
msgid "Help center button in the sidebar"
msgstr "Hilfe-Center-Schaltfläche in der Seitenleiste"
#: src/features/user/components/modals/tabs/LanguageTab.tsx:348
msgid "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
msgstr "Hilf auf <0>{I18N_WEBLATE_DOMAIN}</0> mit, {PRODUCT_NAME} in deine Sprache zu übersetzen."
@@ -17035,7 +17056,7 @@ msgid "Hide join messages"
msgstr "Beitrittsnachrichten ausblenden"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:47
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:50
msgid "Hide keyboard hints"
msgstr "Tastaturhinweise ausblenden"
@@ -18721,7 +18742,7 @@ msgstr "Videoanruf beitreten"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/profile/VoiceActivityCard.tsx:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:31
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:34
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:454
msgid "Join voice"
msgstr "Sprachanruf beitreten"
@@ -18764,6 +18785,7 @@ msgstr "Zwischen ungelesenen Kanälen springen"
msgid "Jump between unread channels with mentions"
msgstr "Zwischen ungelesenen Kanälen mit Erwähnungen springen"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:121
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:75
msgid "Jump straight to the app to continue."
msgstr "Direkt zur App, um fortzufahren."
@@ -18904,7 +18926,7 @@ msgstr "Anhänge beim Löschen einer Bearbeitung beibehalten"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Behalte kostenlose und Premium-Stufen bei. Du kannst die Stufen anpassen, Premium über Stripe verkaufen oder später Geschenke-Codes im Admin-Panel verteilen."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Übergangsfrist beibehalten"
@@ -18918,7 +18940,7 @@ msgstr "Neko festhalten"
msgid "Keep running"
msgstr "Weiter ausführen"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Abo behalten"
@@ -18980,7 +19002,7 @@ msgid "Keyboard mode"
msgstr "Tastaturmodus"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:59
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:62
msgid "Keyboard shortcut hints in tooltips"
msgstr "Tastenkombinationshinweise in Tooltips anzeigen"
@@ -19275,8 +19297,8 @@ msgstr "Linke Maustaste"
msgid "Left tooltip"
msgstr "Linker Tooltip"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Alter Tarif"
@@ -20094,7 +20116,7 @@ msgstr "Obersten Posteingangskanal als gelesen markieren"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:364
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
msgid "Markdown"
msgstr "Markdown"
@@ -20644,7 +20666,7 @@ msgstr "Diese Rolle erwähnen?"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/guild/components/modals/GuildNotificationSettingsModal.tsx:136
#: src/features/i18n/utils/CommonMessageDescriptors.ts:648
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
msgid "Mentions"
msgstr "Erwähnungen"
@@ -21158,7 +21180,7 @@ msgid "Missing client_id"
msgstr "client_id fehlt"
#. SSO callback page error shown when the SSO callback is missing code or state parameters.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:24
#: src/features/auth/components/pages/SsoCallbackPage.tsx:26
msgid "Missing SSO code. Sign in again."
msgstr "SSO-Code fehlt. Melde dich erneut an."
@@ -21317,11 +21339,11 @@ msgstr "Monatlich"
msgid "Monthly {monthlyPrice}"
msgstr "Monatlich {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Die monatliche Abrechnung beginnt am <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Die monatliche Abrechnung beginnt am <0>{pendingChangeDate}</0>. Erste monatliche Gebühr: {pendingInitialPriceLabel}. Zukünftige monatliche Verlängerungen: {pendingRecurringPriceLabel}/Monat."
@@ -21756,7 +21778,7 @@ msgstr "stummgeschaltet"
#. Status label indicating the surface is currently muted.
#: src/features/app/components/layout/sidebar_nav/UseGuildListItemState.ts:23
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:491
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/lib/overlay/OverlayContextMenu.tsx:24
msgid "Muted"
msgstr "Stummgeschaltet"
@@ -21779,7 +21801,7 @@ msgstr "Von Moderatoren stummgeschaltet"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:495
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
msgid "Muted channels"
msgstr "Stummgeschaltete Kanäle"
@@ -21992,7 +22014,7 @@ msgid "Narrates only the channel you're viewing. Narration follows you between c
msgstr "Liest nur den Kanal vor, den du gerade ansiehst. Die Vorlesefunktion folgt dir beim Wechsel zwischen Kanälen."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
msgid "Narration"
msgstr "Vorlesefunktion"
@@ -22057,12 +22079,12 @@ msgid "Need an account?"
msgstr "Du brauchst einen Account?"
#. Settings search synonym. Proper name of the optional cat sprite that chases the cursor.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
msgid "Neko"
msgstr "Neko"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:63
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:66
msgid "Neko cat that chases your cursor"
msgstr "Neko-Katze, die deinem Mauszeiger folgt"
@@ -22247,12 +22269,12 @@ msgid "New password"
msgstr "Neues Passwort"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Neuer Preis geplant für den <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Neuer Preis geplant für den <0>{pendingChangeDate}</0>. Verlängerungen kosten dann {pendingTargetPriceLabel}."
@@ -23560,6 +23582,8 @@ msgid "Open {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName}
msgstr "Öffne „{macosSystemSettingsName}“ → „{macosPrivacyAndSecuritySettingsName}“ → „{macosScreenRecordingPermissionName}“ und erlaube den Zugriff für {productName}. Wenn {productName2} bereits aktiviert ist, beende {productName3} vollständig und starte es neu, damit macOS die Berechtigung anwendet."
#. Button label that opens the desktop app. productName is the app name.
#. Button that hands SSO sign-in back to the mobile app. productName is the app name.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:34
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:27
msgid "Open {productName}"
msgstr "{productName} öffnen"
@@ -24945,7 +24969,7 @@ msgstr "Diese Nachricht für alle sichtbar im Kanal anpinnen."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Voice stats field label (mobile lobby). Shows current latency in ms.
#. Voice stats field label (mobile voice lobby). Shows current latency in ms.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:184
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/voice/components/bottomsheets/DirectCallLobbyBottomSheet.tsx:118
#: src/features/voice/components/bottomsheets/VoiceLobbyBottomSheet.tsx:86
msgid "Ping"
@@ -25165,7 +25189,7 @@ msgid "Popped out"
msgstr "In separatem Fenster geöffnet"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:204
msgid "Popup"
msgstr "Pop-up"
@@ -26128,7 +26152,7 @@ msgstr "Reaktionen"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Reaktivieren"
@@ -26139,7 +26163,7 @@ msgid "Reactivate subscription"
msgstr "Abo reaktivieren"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
msgid "Read aloud"
msgstr "Vorlesen"
@@ -26156,7 +26180,7 @@ msgstr "Nachrichtenverlauf lesen"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:177
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
msgid "Read messages"
msgstr "Nachrichten lesen"
@@ -26351,8 +26375,8 @@ msgstr "Für dich einlösen"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Geschenkcode einlösen"
@@ -26630,7 +26654,7 @@ msgstr "Fenstergröße und -position merken"
#: src/features/user/components/modals/tabs/chat_settings_tab/SearchEnginesTab.tsx:26
#: src/features/user/components/modals/tabs/LinkedAccountsTab.tsx:55
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:178
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:200
#: src/features/webhook/components/WebhookListItem.tsx:277
msgid "Remove"
msgstr "Entfernen"
@@ -27123,7 +27147,7 @@ msgstr "Erneuerungsschwelle (Tage)"
msgid "Renew window (days)"
msgstr "Erneuerungszeitraum (Tage)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Verlängert sich am <0>{renewalDate}.</0>"
@@ -27321,7 +27345,7 @@ msgid "Require a passkey as your second factor"
msgstr "Passkey als zweiten Faktor verlangen"
#. Short label for an advanced voice-channel navigation preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:17
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:20
msgid "Require double-click to join voice channels"
msgstr "Doppelklick zum Beitreten von Sprachkanälen erforderlich"
@@ -27872,8 +27896,8 @@ msgstr "Fenster wiederherstellen"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Erneut abonnieren"
@@ -29578,7 +29602,7 @@ msgid "Sending malware or dangerous links"
msgstr "Malware oder gefährliche Links senden"
#. Short label under a destination row in the forward modal, shown when the community has messaging disabled.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:54
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:55
msgid "Sending messages is disabled in this community"
msgstr "Das Senden von Nachrichten ist in dieser Community deaktiviert"
@@ -30120,7 +30144,7 @@ msgstr "Tastenkombination"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:55
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:58
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:370
msgid "Shortcut badges"
msgstr "Kennzeichnungen für Tastenkombinationen"
@@ -30280,7 +30304,9 @@ msgid "Show delete button"
msgstr "Löschen-Button anzeigen"
#. Short label for an advanced media button preference.
#. Toggle label and settings search entry for showing the download app button in the sidebar.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:76
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
msgid "Show download button"
msgstr "Download-Button anzeigen"
@@ -30322,7 +30348,7 @@ msgid "Show favorite button"
msgstr "Favoriten-Button anzeigen"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:87
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:90
msgid "Show favorites throughout the app"
msgstr "Favoriten in der gesamten App anzeigen"
@@ -30350,6 +30376,11 @@ msgstr "GIF-Indikator anzeigen"
msgid "Show GIFs button"
msgstr "GIF-Schaltfläche anzeigen"
#. Toggle label and settings search entry for showing the help center button in the sidebar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
msgid "Show help center button"
msgstr "Hilfe-Center-Button anzeigen"
#. Switch label in the community-folder settings modal. When on, the folder icon is shown in the sidebar while the folder is collapsed.
#: src/features/guild/components/modals/GuildFolderSettingsModal.tsx:77
msgid "Show icon when collapsed"
@@ -30565,7 +30596,7 @@ msgid "Show stickers in expression autocomplete"
msgstr "Sticker in der Ausdrucks-Autovervollständigung anzeigen"
#. Description for a visual accessibility setting that mutes the color of text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:110
msgid "Show strikethrough Markdown text in a slightly muted color."
msgstr "Durchgestrichenen Markdown-Text in einer leicht gedämpften Farbe anzeigen."
@@ -31008,7 +31039,7 @@ msgid "Slowmode"
msgstr "Slow-Modus"
#. Short label under a destination row in the forward modal while slowmode blocks sending. Preserve {remaining}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:73
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:74
msgid "Slowmode · wait {remaining}"
msgstr "Slow-Modus · warte {remaining}"
@@ -31559,7 +31590,7 @@ msgstr "Zuschauer – {count}"
#. Native macOS Edit submenu title for text-to-speech actions.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/platform/utils/DesktopLocaleBridge.ts:85
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
msgid "Speech"
msgstr "Sprache"
@@ -31670,12 +31701,12 @@ msgstr "Quadratische Icon-Buttons"
msgid "SSO is required to access this workspace."
msgstr "Für den Zugriff auf diesen Workspace ist SSO erforderlich."
#: src/features/auth/components/pages/SsoCallbackPage.tsx:105
#: src/features/auth/components/pages/SsoCallbackPage.tsx:139
msgid "SSO sign-in failed"
msgstr "SSO-Anmeldung fehlgeschlagen"
#. SSO callback page error shown when the SSO sign-in timed out before the callback arrived.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:20
#: src/features/auth/components/pages/SsoCallbackPage.tsx:22
msgid "SSO sign-in timed out. Try again."
msgstr "Zeitüberschreitung bei der SSO-Anmeldung. Versuche es erneut."
@@ -31714,7 +31745,7 @@ msgid "Star animation"
msgstr "Stern-Animation"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:83
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:86
msgid "Starred channels"
msgstr "Markierte Kanäle"
@@ -31791,7 +31822,7 @@ msgstr "Neu beginnen"
msgid "Start recording"
msgstr "Aufnahme starten"
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:592
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:582
msgid "Start searches with <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> to narrow down results."
msgstr "Beginne Suchvorgänge mit <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3>, um die Ergebnisse einzugrenzen."
@@ -31831,7 +31862,7 @@ msgid "Startup"
msgstr "Start"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:75
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:78
msgid "Static Neko"
msgstr "Statischer Neko"
@@ -32038,7 +32069,7 @@ msgid "Still indexing — check back in a moment"
msgstr "Wird noch indiziert – bitte gleich noch einmal versuchen"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:71
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:74
msgid "Still Neko"
msgstr "Unbeweglicher Neko"
@@ -32067,7 +32098,7 @@ msgid "Stop mic test"
msgstr "Mikrofontest beenden"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:70
msgid "Stop Neko from chasing your cursor while keeping it draggable and interactive."
msgstr "Verhindere, dass Neko deinem Mauszeiger folgt, während er weiterhin ziehbar und interaktiv bleibt."
@@ -32259,14 +32290,14 @@ msgid "Streaming privacy on"
msgstr "Streaming-Datenschutz aktiviert"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:111
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
msgid "Strike through"
msgstr "Durchgestrichen"
#. Selection formatting toolbar button.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/lexical/composer/SelectionFormattingToolbar.tsx:72
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:107
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
msgid "Strikethrough"
msgstr "Durchgestrichen"
@@ -32490,7 +32521,7 @@ msgid "Switch price"
msgstr "Preis wechseln"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Wechseln zu {listPriceNewLabel}"
@@ -32515,7 +32546,7 @@ msgstr "Direkte Eingabe nutzen"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Zum Monatsabo wechseln"
@@ -32584,7 +32615,7 @@ msgstr "Zu zwei Spalten wechseln"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Zum Jahresabo wechseln"
@@ -33074,7 +33105,7 @@ msgstr "Sende uns eine SMS von deinem Telefon"
#. Feature label / section heading for the text-to-speech feature.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:419
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
msgid "Text-to-speech"
msgstr "Text-to-Speech"
@@ -34133,7 +34164,7 @@ msgid "This member isn't connected to voice anymore."
msgstr "Dieses Mitglied ist nicht mehr mit dem Sprachkanal verbunden."
#. Forward dialog error shown when the forwarded message contains age-restricted media and the target channel is not age-restricted.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:68
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:69
msgid "This message can only be forwarded to age-restricted channels"
msgstr "Diese Nachricht kann nur an Kanäle mit Altersbeschränkung weitergeleitet werden"
@@ -34766,7 +34797,7 @@ msgid "Toolbar"
msgstr "Symbolleiste"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:51
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:54
msgid "Tooltip shortcuts"
msgstr "Tastenkombinationen in Tooltips"
@@ -35080,7 +35111,7 @@ msgid "Try sending your message again."
msgstr "Versuch, deine Nachricht noch einmal zu senden."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
msgid "TTS"
msgstr "TTS"
@@ -35277,7 +35308,7 @@ msgstr "24-Stunden-Format"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:39
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:42
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:406
msgid "Two clicks"
msgstr "Zwei Klicks"
@@ -35834,7 +35865,7 @@ msgstr "Schalte benutzerdefinierte Emojis in DMs mit {premiumProductName} frei"
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "HD-Bildschirmfreigabe mit {premiumProductName} freischalten"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Schalte höhere Limits und exklusive Funktionen frei und unterstütze gleichzeitig eine unabhängige Kommunikationsplattform."
@@ -36044,7 +36075,7 @@ msgstr "ungelesen"
#. Tab label in the inbox popout filtering to channels with unread messages.
#: src/features/messaging/components/popouts/InboxPopout.tsx:30
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
msgid "Unread"
msgstr "Ungelesen"
@@ -37866,7 +37897,7 @@ msgstr "Visuelle Indikatoren, die den Benutzerstatus anzeigen, gerendert mit den
#: src/features/app/components/layout/MobileBottomNav.tsx:123
#: src/features/channel/utils/ChannelUtils.tsx:31
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:17
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
msgid "Voice"
msgstr "Sprachanruf"
@@ -37961,7 +37992,7 @@ msgstr "Sprachkanal"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:23
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:26
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:402
msgid "Voice channel confirmation"
msgstr "Sprachkanal-Bestätigung"
@@ -37972,7 +38003,7 @@ msgid "Voice channel full"
msgstr "Sprachkanal voll"
#. Settings search entry label. Names the settings search entry in the settings UI.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:19
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:22
msgid "Voice channel join behavior"
msgstr "Verhalten beim Beitreten von Sprachkanälen"
@@ -38099,7 +38130,7 @@ msgstr "Storniert"
#: src/features/i18n/utils/CommonMessageDescriptors.ts:378
#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:181
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:183
msgid "Volume"
msgstr "Lautstärke"
@@ -38984,15 +39015,15 @@ msgstr "Jährlich {yearlyPrice}"
msgid "Yearly gift"
msgstr "Jährliches Geschenk"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Wechsel zum Jahresabo für <0>{pendingChangeDate}</0> geplant."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Wechsel zum Jahresabo für <0>{pendingChangeDate}</0> geplant. Erste jährliche Abbuchung: {pendingInitialPriceLabel} nach Anrechnung einer Gutschrift von {pendingCreditPriceLabel}. Künftige jährliche Verlängerungen: {pendingRecurringPriceLabel}/Jahr."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Wechsel zum Jahresabo für <0>{pendingChangeDate}</0> geplant. Erste jährliche Abbuchung: {pendingInitialPriceLabel}. Künftige jährliche Verlängerungen: {pendingRecurringPriceLabel}/Jahr."
@@ -39462,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Du hast gerade die Tab-Taste gedrückt. Der Tastaturmodus ist jetzt aktiviert, damit du {productName} ohne Maus navigieren kannst."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Du behältst deine Vorteile bis zum nächsten Verlängerungsdatum. Danach hast du eine Übergangsfrist von 3 Tagen, um erneut zu abonnieren und deinen Abo-Verlauf zu behalten."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Du behältst deine Vorteile bis zum nächsten Verlängerungsdatum. Reaktiviere dein Abo vorher, um deinen Abo-Verlauf zu behalten."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Du verlierst sofort alle {PREMIUM_PRODUCT_NAME}-Vorteile und dein Abonnentenverlauf wird zurückgesetzt. Dies kann nicht rückgängig gemacht werden."
@@ -39508,12 +39539,12 @@ msgid "You need access to your current email to change it from here. Use phone v
msgstr "Du benötigst Zugriff auf deine aktuelle E-Mail-Adresse, um sie hier zu ändern. Nutze, falls verfügbar, die Telefonverifizierung oder kontaktiere den Support."
#. Forward dialog error shown when the forwarded message has attachments and the user lacks Attach Files in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:63
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:64
msgid "You need the \"{attachFilesPermissionLabel}\" permission to attach files in this channel"
msgstr "Du benötigst die Berechtigung \"{attachFilesPermissionLabel}\", um Dateien in diesem Kanal anzuhängen"
#. Forward dialog error shown when the forwarded message contains embeds and the user lacks Embed Links in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:58
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:59
msgid "You need the \"{embedLinksPermissionLabel}\" permission to embed links in this channel"
msgstr "Du benötigst die Berechtigung \"{embedLinksPermissionLabel}\", um Links in diesem Kanal einzubetten"
@@ -40200,6 +40231,11 @@ msgstr "deine Region"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Deine Registrierung erfordert eine zusätzliche Anti-Spam-Prüfung, bevor du fortfahren kannst."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Deine Verlängerungszahlung ist fehlgeschlagen, aber <0/> bleiben bis zum <1>{graceDate}</1> aktiv. Aktualisiere vorher deine Zahlungsmethode, um dein Abo zu behalten."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40221,7 +40257,7 @@ msgstr "Dein Stream ist weiterhin live"
msgid "Your subscription can't move to the new price right now."
msgstr "Dein Abonnement kann im Moment nicht zum neuen Preis übernommen werden."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Dein Abo ist abgelaufen, aber <0/> bleiben bis zum <1>{graceDate}</1> aktiv. Abonniere vorher erneut, um deinen Abo-Verlauf zu behalten."
@@ -40250,7 +40286,7 @@ msgstr "Dein Abo wurde auf monatliche Abrechnung umgestellt."
msgid "Your subscription has been switched to yearly billing."
msgstr "Dein Abo wurde auf jährliche Abrechnung umgestellt."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Dein Abo ist aktiv, aber die Vorteile sind vorübergehend pausiert."
@@ -40270,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Dein Abonnement wird am {effectiveDate} auf den neuen Preis umgestellt."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Dein Abo endet weiterhin am <0>{cancelDate}</0>. Der aktuelle Preis beträgt jetzt {listPriceNewLabel}. Wenn du dein Abo reaktivierst, kannst du hier zu diesem Preis wechseln."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Υπάρχει διαθέσιμη ενημέρωση της εφαρμογής για Linux. Επιλέξτε τη μορφή πακέτου για αυτό το σύστημα και το {productName} θα την αποθηκεύσει τοπικά."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Υπάρχει διαθέσιμη χαμηλότερη τιμή. Η αλλαγή τίθεται σε ισχύ στις <0>{listPriceEffectiveDate}</0> και δεν αλλάζει τίποτα άλλο."
@@ -2639,7 +2639,7 @@ msgstr "Πρόσβαση στις βασικές πληροφορίες του
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. User settings tab for accessibility preferences (visual, motion, screen reader, etc.).
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:14
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/SettingsConstants.tsx:61
msgid "Accessibility"
msgstr "Προσβασιμότητα"
@@ -3487,19 +3487,19 @@ msgstr "Οι ρυθμίσεις στοίχισης είναι διαθέσιμε
msgid "All"
msgstr "Όλα"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Όλα τα <0/> με <1>{effectiveMonthlyPrice}/μήνα</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Όλα τα <0/> με <1>{effectiveYearlyPrice}/έτος</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Όλα τα <0/> περιλαμβάνονται στη συνδρομή σας."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Όλα τα <0/>, για πάντα. Χωρίς χρέωση, χωρίς ανανεώσεις."
@@ -4706,7 +4706,7 @@ msgstr "Συνημμένα"
#. Generic tab / section / category label for audio content or settings.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:255
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:179
msgid "Audio"
msgstr "Ήχος"
@@ -6210,7 +6210,7 @@ msgid "California"
msgstr "Καλιφόρνια"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
msgid "Call"
msgstr "Κλήση"
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Ακύρωση εισαγωγής"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Ακύρωση αλλαγής τιμής"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Ακύρωση αιτήματος"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Ακύρωση προγραμματισμένης αλλαγής"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Ακύρωση συνδρομής"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Ακύρωση συνδρομής;"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Ακυρώστε την προγραμματισμένη αλλαγή για να μεταβείτε στην τρέχουσα τιμή."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Ακύρωση μεταφόρτωσης"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Ακύρωση ετήσιας αναβάθμισης"
@@ -6530,7 +6530,7 @@ msgstr "Ακυρώνεται"
msgid "Cancellation"
msgstr "Ακύρωση ηχούς"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Ακυρώνεται στις <0>{cancelDate}</0>. <1/> παραμένουν ενεργά μέχρι τότε."
@@ -7088,7 +7088,7 @@ msgid "Channel"
msgstr "Κανάλι"
#. Fallback name for an unnamed channel in the forward modal destination list. Preserve {id}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:78
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:79
msgid "Channel {id}"
msgstr "Κανάλι {id}"
@@ -7317,7 +7317,7 @@ msgid "Chat font size"
msgstr "Μέγεθος γραμματοσειράς συνομιλίας"
#. Settings search synonym. Refers to the message composer area.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
msgid "chat input"
msgstr "πεδίο συνομιλίας"
@@ -8726,7 +8726,7 @@ msgid "Community updated"
msgstr "Η κοινότητα ενημερώθηκε"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:35
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:38
msgid "Community voice"
msgstr "Φωνητικό κοινότητας"
@@ -8789,12 +8789,13 @@ msgstr "Ολοκληρώστε την απαιτούμενη επαλήθευσ
msgid "Completely hide your {premiumProductName} badge from other users"
msgstr "Πλήρης απόκρυψη του σήματος {premiumProductName} από τους άλλους χρήστες"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:134
#: src/features/auth/components/pages/SsoCallbackPage.tsx:118
#: src/features/auth/components/pages/SsoCallbackPage.tsx:168
#: src/features/auth/flow/HandoffApprovalFlow.tsx:218
msgid "Completing sign-in…"
msgstr "Ολοκλήρωση σύνδεσης…"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:138
#: src/features/auth/components/pages/SsoCallbackPage.tsx:172
msgid "Completing your sign-in…"
msgstr "Ολοκληρώνεται η σύνδεσή σας…"
@@ -8912,8 +8913,8 @@ msgstr "Επιβεβαίωση"
#. Settings search entry label. Names the settings search entry in the settings UI.
#. Short label for an advanced voice-channel safety preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:21
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:15
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:24
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:18
msgid "Confirm before joining voice channels"
msgstr "Επιβεβαίωση πριν την είσοδο σε φωνητικά κανάλια"
@@ -8952,7 +8953,7 @@ msgstr "Επιβεβαίωση κωδικού πρόσβασης"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:27
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:30
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:398
msgid "Confirm voice join"
msgstr "Επιβεβαίωση εισόδου σε φωνητικό κανάλι"
@@ -8963,7 +8964,7 @@ msgid "Confirmation"
msgstr "Επιβεβαίωση"
#. Settings search entry description. One-line summary of what the settings search entry controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:43
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:46
msgid "Confirmation or double-click for community voice joins"
msgstr "Επιβεβαίωση ή διπλό κλικ για συμμετοχή σε φωνητικά κανάλια της κοινότητας"
@@ -9200,7 +9201,7 @@ msgstr "Φίλτρα ασφάλειας περιεχομένου"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/ui/action_menu/ContextMenu.tsx:23
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:225
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
msgid "Context menu"
msgstr "Μενού περιβάλλοντος"
@@ -10871,7 +10872,7 @@ msgstr "Προσαρμοσμένο…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Πύλη πελατών"
@@ -11341,7 +11342,7 @@ msgstr "Ντέλαγουερ"
#: src/features/user/components/modals/tabs/component_gallery_tab/ComponentGalleryTabButtonsTab.tsx:290
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:238
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:174
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
msgid "Delete"
msgstr "Διαγραφή"
@@ -11626,7 +11627,7 @@ msgid "Deleted {duration} of the member's recent message history"
msgstr "Διαγράφηκε το πρόσφατο ιστορικό μηνυμάτων του μέλους για {duration}"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
msgid "Deleted text"
msgstr "Διαγραμμένο κείμενο"
@@ -12028,7 +12029,7 @@ msgid "Different sizes & member counts"
msgstr "Διαφορετικά μεγέθη και αριθμοί μελών"
#. Toggle label and settings search entry for slightly muting text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:106
msgid "Dim strikethrough text"
msgstr "Αχνό διαγραμμένο κείμενο"
@@ -12043,7 +12044,7 @@ msgstr "Απευθείας είσοδος"
#: src/features/channel/components/bottomsheets/channel_details_bottom_sheet/ChannelDetailsBottomSheetShared.ts:14
#: src/features/channel/components/channel_header_components/developer_tools/MockingMenu.tsx:398
#: src/features/i18n/utils/CommonMessageDescriptors.ts:567
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
msgid "Direct message"
msgstr "Απευθείας μήνυμα"
@@ -12480,7 +12481,7 @@ msgid "District of Columbia"
msgstr "Περιφέρεια της Κολούμπια"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:180
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
msgid "DM"
msgstr "DM"
@@ -12735,6 +12736,16 @@ msgstr "Λήψη του {productName}"
msgid "Download <0>fluxer-verification</0> and place it in your <1>.well-known</1> folder so we can validate the domain."
msgstr "Κατεβάστε το <0>fluxer-verification</0> και τοποθετήστε το στον φάκελο <1>.well-known</1>, ώστε να μπορούμε να επικυρώσουμε τον τομέα."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:98
msgid "Download app"
msgstr "Λήψη εφαρμογής"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:106
msgid "Download app button in the sidebar"
msgstr "Λήψη εφαρμογής"
#. Media context menu action that downloads an audio attachment.
#: src/features/ui/action_menu/items/MediaMenuData.tsx:122
msgid "Download audio"
@@ -13433,7 +13444,7 @@ msgstr "Οι ενσωματώσεις εμφανίστηκαν ξανά"
#: src/features/app/config/AuditLogConstants.ts:167
#: src/features/emoji/components/emojis/EmojiListItem.tsx:337
#: src/features/theme_studio/sections/TokenGroups.ts:114
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
msgid "Emoji"
msgstr "Emoji"
@@ -13866,15 +13877,15 @@ msgid "End date"
msgstr "Ημερομηνία λήξης"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Τερματισμός περιόδου χάριτος τώρα"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Τερματισμός περιόδου χάριτος"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Να τερματιστεί τώρα η περίοδος χάριτος;"
@@ -14681,7 +14692,7 @@ msgid "Failed to clear trusted domains."
msgstr "Αποτυχία εκκαθάρισης αξιόπιστων τομέων."
#. Short label in the authentication SSO callback page. Keep the tone plain and specific.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:28
#: src/features/auth/components/pages/SsoCallbackPage.tsx:30
msgid "Failed to complete SSO sign-in"
msgstr "Αποτυχία ολοκλήρωσης σύνδεσης SSO"
@@ -15027,7 +15038,7 @@ msgid "Favorite channel"
msgstr "Προσθήκη καναλιού στα αγαπημένα"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:79
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:82
msgid "Favorite channels"
msgstr "Αγαπημένα κανάλια"
@@ -15800,7 +15811,7 @@ msgstr "Φιλικό bot"
#: src/features/connection/components/modals/EditConnectionModal.tsx:86
#: src/features/search/utils/QuickSwitcherModalUtils.tsx:50
#: src/features/user/components/modals/tabs/my_profile_tab/TimezoneProfileSettings.tsx:63
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
msgid "Friends"
msgstr "Φίλοι"
@@ -16145,7 +16156,7 @@ msgstr "Λήψη της νέας εφαρμογής {productName}"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Type label for GIF media.
#: src/features/expressions/utils/FavoriteMemeUtils.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
msgid "GIF"
msgstr "GIF"
@@ -16336,7 +16347,7 @@ msgstr "Δώρο: λήγει σύντομα"
msgid "Gift: grace period (still have access)"
msgstr "Δώρο: περίοδος χάριτος (έχετε ακόμα πρόσβαση)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Έχετε ως δώρο <0/> έως <1>{giftEndDate}</1>. Δεν ανανεώνεται αυτόματα. Εξαργυρώστε περισσότερους κωδικούς δώρου για παράταση."
@@ -16549,7 +16560,7 @@ msgid "Graphics"
msgstr "Γραφικά"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
msgid "Gray text"
msgstr "Γκρι κείμενο"
@@ -16815,7 +16826,7 @@ msgid "Hate speech"
msgstr "Ρητορική μίσους"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Έχετε κωδικό δώρου; Εξαργυρώστε τον για να ξεκλειδώσετε το {PREMIUM_PRODUCT_NAME}."
@@ -16896,11 +16907,21 @@ msgstr "Γεια σου, {username}! Χαρά μας που σε έχουμε ε
msgid "Help"
msgstr "Βοήθεια"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:94
msgid "Help button"
msgstr "Κουμπί βοήθειας"
#. Short label in the sidebar navigation help button.
#: src/features/app/components/layout/sidebar_nav/HelpButton.tsx:27
msgid "Help center"
msgstr "Κέντρο βοήθειας"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:102
msgid "Help center button in the sidebar"
msgstr "Κέντρο βοήθειας"
#: src/features/user/components/modals/tabs/LanguageTab.tsx:348
msgid "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
msgstr "Βοηθήστε στη μετάφραση του {PRODUCT_NAME} στη γλώσσα σας στο <0>{I18N_WEBLATE_DOMAIN}</0>."
@@ -17035,7 +17056,7 @@ msgid "Hide join messages"
msgstr "Απόκρυψη μηνυμάτων εισόδου"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:47
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:50
msgid "Hide keyboard hints"
msgstr "Απόκρυψη υποδείξεων πληκτρολογίου"
@@ -18721,7 +18742,7 @@ msgstr "Συμμετοχή σε βιντεοκλήση"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/profile/VoiceActivityCard.tsx:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:31
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:34
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:454
msgid "Join voice"
msgstr "Συμμετοχή σε φωνητική συνομιλία"
@@ -18764,6 +18785,7 @@ msgstr "Μετάβαση μεταξύ μη αναγνωσμένων καναλι
msgid "Jump between unread channels with mentions"
msgstr "Μετάβαση μεταξύ μη αναγνωσμένων καναλιών με αναφορές"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:121
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:75
msgid "Jump straight to the app to continue."
msgstr "Μετάβαση στην εφαρμογή για να συνεχίσετε."
@@ -18904,7 +18926,7 @@ msgstr "Διατήρηση συνημμένων κατά την εκκαθάρι
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Διατήρησε δωρεάν και premium βαθμίδες. Μπορείς να προσαρμόσεις τις βαθμίδες, να πουλήσεις premium μέσω Stripe ή να διανείμεις κωδικούς δώρου αργότερα από τον πίνακα διαχειριστή."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Διατήρηση περιόδου χάριτος"
@@ -18918,7 +18940,7 @@ msgstr "Κράτα το Neko ακίνητο"
msgid "Keep running"
msgstr "Παραμονή σε λειτουργία"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Διατήρηση συνδρομής"
@@ -18980,7 +19002,7 @@ msgid "Keyboard mode"
msgstr "Λειτουργία πληκτρολογίου"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:59
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:62
msgid "Keyboard shortcut hints in tooltips"
msgstr "Υποδείξεις συντομεύσεων πληκτρολογίου στις επεξηγήσεις"
@@ -19275,8 +19297,8 @@ msgstr "Αριστερό κουμπί ποντικιού"
msgid "Left tooltip"
msgstr "Αριστερή επεξήγηση εργαλείου"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Παλιά τιμή"
@@ -20094,7 +20116,7 @@ msgstr "Σήμανση του πρώτου καναλιού εισερχομέν
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:364
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
msgid "Markdown"
msgstr "Markdown"
@@ -20644,7 +20666,7 @@ msgstr "Αναφορά σε αυτόν τον ρόλο;"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/guild/components/modals/GuildNotificationSettingsModal.tsx:136
#: src/features/i18n/utils/CommonMessageDescriptors.ts:648
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
msgid "Mentions"
msgstr "Αναφορές"
@@ -21158,7 +21180,7 @@ msgid "Missing client_id"
msgstr "Λείπει το client_id"
#. SSO callback page error shown when the SSO callback is missing code or state parameters.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:24
#: src/features/auth/components/pages/SsoCallbackPage.tsx:26
msgid "Missing SSO code. Sign in again."
msgstr "Λείπει ο κωδικός SSO. Συνδεθείτε ξανά."
@@ -21317,11 +21339,11 @@ msgstr "Μηνιαία"
msgid "Monthly {monthlyPrice}"
msgstr "Μηνιαία {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Η μηνιαία χρέωση ξεκινά στις <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Η μηνιαία χρέωση ξεκινά στις <0>{pendingChangeDate}</0>. Πρώτη μηνιαία χρέωση: {pendingInitialPriceLabel}. Μελλοντικές μηνιαίες ανανεώσεις: {pendingRecurringPriceLabel}/μήνα."
@@ -21756,7 +21778,7 @@ msgstr "σε σίγαση"
#. Status label indicating the surface is currently muted.
#: src/features/app/components/layout/sidebar_nav/UseGuildListItemState.ts:23
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:491
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/lib/overlay/OverlayContextMenu.tsx:24
msgid "Muted"
msgstr "Σε σίγαση"
@@ -21779,7 +21801,7 @@ msgstr "Σε σίγαση από συντονιστές"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:495
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
msgid "Muted channels"
msgstr "Κανάλια σε σίγαση"
@@ -21992,7 +22014,7 @@ msgid "Narrates only the channel you're viewing. Narration follows you between c
msgstr "Αφηγείται μόνο το κανάλι που βλέπετε. Η αφήγηση σάς ακολουθεί μεταξύ των καναλιών."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
msgid "Narration"
msgstr "Αφήγηση"
@@ -22057,12 +22079,12 @@ msgid "Need an account?"
msgstr "Χρειάζεστε λογαριασμό;"
#. Settings search synonym. Proper name of the optional cat sprite that chases the cursor.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
msgid "Neko"
msgstr "Neko"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:63
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:66
msgid "Neko cat that chases your cursor"
msgstr "Γάτα Neko που κυνηγά τον κέρσορά σου"
@@ -22247,12 +22269,12 @@ msgid "New password"
msgstr "Νέος κωδικός πρόσβασης"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Νέα τιμή προγραμματισμένη για <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Νέα τιμή προγραμματισμένη για <0>{pendingChangeDate}</0>. Οι ανανεώσεις θα είναι {pendingTargetPriceLabel} από εκείνη την ημερομηνία και μετά."
@@ -23560,6 +23582,8 @@ msgid "Open {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName}
msgstr "Ανοίξτε τις {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName} → {macosScreenRecordingPermissionName} και, στη συνέχεια, επιτρέψτε την πρόσβαση στο {productName}. Εάν το {productName2} είναι ήδη ενεργοποιημένο, τερματίστε εντελώς και επανεκκινήστε το {productName3} ώστε το macOS να εφαρμόσει την άδεια."
#. Button label that opens the desktop app. productName is the app name.
#. Button that hands SSO sign-in back to the mobile app. productName is the app name.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:34
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:27
msgid "Open {productName}"
msgstr "Άνοιγμα {productName}"
@@ -24945,7 +24969,7 @@ msgstr "Καρφιτσώστε αυτό το μήνυμα στο κανάλι γ
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Voice stats field label (mobile lobby). Shows current latency in ms.
#. Voice stats field label (mobile voice lobby). Shows current latency in ms.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:184
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/voice/components/bottomsheets/DirectCallLobbyBottomSheet.tsx:118
#: src/features/voice/components/bottomsheets/VoiceLobbyBottomSheet.tsx:86
msgid "Ping"
@@ -25165,7 +25189,7 @@ msgid "Popped out"
msgstr "Εμφανίζεται σε ξεχωριστό παράθυρο"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:204
msgid "Popup"
msgstr "Αναδυόμενο"
@@ -26128,7 +26152,7 @@ msgstr "Αντιδράσεις"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Ενεργοποίηση ξανά"
@@ -26139,7 +26163,7 @@ msgid "Reactivate subscription"
msgstr "Επανενεργοποίηση συνδρομής"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
msgid "Read aloud"
msgstr "Ανάγνωση φωναχτά"
@@ -26156,7 +26180,7 @@ msgstr "Ανάγνωση ιστορικού μηνυμάτων"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:177
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
msgid "Read messages"
msgstr "Ανάγνωση μηνυμάτων"
@@ -26351,8 +26375,8 @@ msgstr "Εξαργύρωση για εσάς"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Εξαργύρωση κωδικού δώρου"
@@ -26630,7 +26654,7 @@ msgstr "Απομνημόνευση μεγέθους και θέσης παραθ
#: src/features/user/components/modals/tabs/chat_settings_tab/SearchEnginesTab.tsx:26
#: src/features/user/components/modals/tabs/LinkedAccountsTab.tsx:55
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:178
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:200
#: src/features/webhook/components/WebhookListItem.tsx:277
msgid "Remove"
msgstr "Αφαίρεση"
@@ -27123,7 +27147,7 @@ msgstr "Όριο ανανέωσης (ημέρες)"
msgid "Renew window (days)"
msgstr "Παράθυρο ανανέωσης (ημέρες)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Ανανεώνεται στις <0>{renewalDate}.</0>"
@@ -27321,7 +27345,7 @@ msgid "Require a passkey as your second factor"
msgstr "Απαίτηση κλειδιού πρόσβασης ως δεύτερου παράγοντα"
#. Short label for an advanced voice-channel navigation preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:17
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:20
msgid "Require double-click to join voice channels"
msgstr "Απαίτηση διπλού κλικ για είσοδο σε φωνητικά κανάλια"
@@ -27872,8 +27896,8 @@ msgstr "Επαναφορά παραθύρου"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Επανεγγραφή"
@@ -29578,7 +29602,7 @@ msgid "Sending malware or dangerous links"
msgstr "Αποστολή κακόβουλου λογισμικού ή επικίνδυνων συνδέσμων"
#. Short label under a destination row in the forward modal, shown when the community has messaging disabled.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:54
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:55
msgid "Sending messages is disabled in this community"
msgstr "Η αποστολή μηνυμάτων έχει απενεργοποιηθεί σε αυτήν την κοινότητα"
@@ -30120,7 +30144,7 @@ msgstr "Συντόμευση"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:55
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:58
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:370
msgid "Shortcut badges"
msgstr "Σήματα συντομεύσεων"
@@ -30280,7 +30304,9 @@ msgid "Show delete button"
msgstr "Εμφάνιση κουμπιού διαγραφής"
#. Short label for an advanced media button preference.
#. Toggle label and settings search entry for showing the download app button in the sidebar.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:76
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
msgid "Show download button"
msgstr "Εμφάνιση κουμπιού λήψης"
@@ -30322,7 +30348,7 @@ msgid "Show favorite button"
msgstr "Εμφάνιση κουμπιού αγαπημένων"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:87
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:90
msgid "Show favorites throughout the app"
msgstr "Εμφάνιση των αγαπημένων σε όλη την εφαρμογή"
@@ -30350,6 +30376,11 @@ msgstr "Εμφάνιση ένδειξης GIF"
msgid "Show GIFs button"
msgstr "Εμφάνιση κουμπιού GIF"
#. Toggle label and settings search entry for showing the help center button in the sidebar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
msgid "Show help center button"
msgstr "Εμφάνιση κουμπιού κέντρου βοήθειας"
#. Switch label in the community-folder settings modal. When on, the folder icon is shown in the sidebar while the folder is collapsed.
#: src/features/guild/components/modals/GuildFolderSettingsModal.tsx:77
msgid "Show icon when collapsed"
@@ -30565,7 +30596,7 @@ msgid "Show stickers in expression autocomplete"
msgstr "Εμφάνιση αυτοκόλλητων στην αυτόματη συμπλήρωση εκφράσεων"
#. Description for a visual accessibility setting that mutes the color of text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:110
msgid "Show strikethrough Markdown text in a slightly muted color."
msgstr "Εμφάνιση του διαγραμμένου κειμένου Markdown σε ελαφρώς πιο απαλό χρώμα."
@@ -31008,7 +31039,7 @@ msgid "Slowmode"
msgstr "Αργή λειτουργία"
#. Short label under a destination row in the forward modal while slowmode blocks sending. Preserve {remaining}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:73
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:74
msgid "Slowmode · wait {remaining}"
msgstr "Αργή λειτουργία · αναμονή {remaining}"
@@ -31559,7 +31590,7 @@ msgstr "Θεατές - {count}"
#. Native macOS Edit submenu title for text-to-speech actions.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/platform/utils/DesktopLocaleBridge.ts:85
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
msgid "Speech"
msgstr "Ομιλία"
@@ -31670,12 +31701,12 @@ msgstr "Τετράγωνα κουμπιά εικονιδίων"
msgid "SSO is required to access this workspace."
msgstr "Απαιτείται SSO για πρόσβαση σε αυτόν τον χώρο εργασίας."
#: src/features/auth/components/pages/SsoCallbackPage.tsx:105
#: src/features/auth/components/pages/SsoCallbackPage.tsx:139
msgid "SSO sign-in failed"
msgstr "Η σύνδεση SSO απέτυχε"
#. SSO callback page error shown when the SSO sign-in timed out before the callback arrived.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:20
#: src/features/auth/components/pages/SsoCallbackPage.tsx:22
msgid "SSO sign-in timed out. Try again."
msgstr "Έληξε ο χρόνος σύνδεσης SSO. Δοκιμάστε ξανά."
@@ -31714,7 +31745,7 @@ msgid "Star animation"
msgstr "Αγαπημένα GIF"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:83
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:86
msgid "Starred channels"
msgstr "Αγαπημένα κανάλια"
@@ -31791,7 +31822,7 @@ msgstr "Από την αρχή"
msgid "Start recording"
msgstr "Έναρξη εγγραφής"
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:592
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:582
msgid "Start searches with <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> to narrow down results."
msgstr "Ξεκινήστε τις αναζητήσεις με <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> για να περιορίσετε τα αποτελέσματα."
@@ -31831,7 +31862,7 @@ msgid "Startup"
msgstr "Εκκίνηση"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:75
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:78
msgid "Static Neko"
msgstr "Στατικό Neko"
@@ -32038,7 +32069,7 @@ msgid "Still indexing — check back in a moment"
msgstr "Γίνεται ακόμα ευρετηρίαση — δοκιμάστε ξανά σε λίγο"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:71
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:74
msgid "Still Neko"
msgstr "Ακίνητο Neko"
@@ -32067,7 +32098,7 @@ msgid "Stop mic test"
msgstr "Διακοπή δοκιμής μικροφώνου"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:70
msgid "Stop Neko from chasing your cursor while keeping it draggable and interactive."
msgstr "Σταματά το Neko να κυνηγά τον κέρσορά σας, διατηρώντας τη δυνατότητα μεταφοράς και αλληλεπίδρασης."
@@ -32259,14 +32290,14 @@ msgid "Streaming privacy on"
msgstr "Απόρρητο ροής ενεργό"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:111
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
msgid "Strike through"
msgstr "Διαγράμμιση"
#. Selection formatting toolbar button.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/lexical/composer/SelectionFormattingToolbar.tsx:72
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:107
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
msgid "Strikethrough"
msgstr "Διακριτή διαγραφή"
@@ -32490,7 +32521,7 @@ msgid "Switch price"
msgstr "Αλλαγή τιμής"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Μετάβαση στο {listPriceNewLabel}"
@@ -32515,7 +32546,7 @@ msgstr "Εναλλαγή σε απευθείας εισαγωγή"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Αλλαγή σε μηνιαία συνδρομή"
@@ -32584,7 +32615,7 @@ msgstr "Εναλλαγή σε δύο στήλες"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Αλλαγή σε ετήσια συνδρομή"
@@ -33074,7 +33105,7 @@ msgstr "Στείλτε μας μήνυμα από το τηλέφωνό σας"
#. Feature label / section heading for the text-to-speech feature.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:419
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
msgid "Text-to-speech"
msgstr "Κείμενο σε ομιλία"
@@ -34133,7 +34164,7 @@ msgid "This member isn't connected to voice anymore."
msgstr "Αυτό το μέλος δεν είναι πλέον συνδεδεμένο στη φωνητική συνομιλία."
#. Forward dialog error shown when the forwarded message contains age-restricted media and the target channel is not age-restricted.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:68
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:69
msgid "This message can only be forwarded to age-restricted channels"
msgstr "Αυτό το μήνυμα μπορεί να προωθηθεί μόνο σε κανάλια με περιορισμό ηλικίας"
@@ -34766,7 +34797,7 @@ msgid "Toolbar"
msgstr "Γραμμή εργαλείων"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:51
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:54
msgid "Tooltip shortcuts"
msgstr "Συντομεύσεις στις επεξηγήσεις"
@@ -35080,7 +35111,7 @@ msgid "Try sending your message again."
msgstr "Δοκιμάστε να στείλετε ξανά το μήνυμά σας."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
msgid "TTS"
msgstr "TTS"
@@ -35277,7 +35308,7 @@ msgstr "Εικοσιτετράωρο"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:39
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:42
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:406
msgid "Two clicks"
msgstr "Δύο κλικ"
@@ -35834,7 +35865,7 @@ msgstr "Ξεκλειδώστε προσαρμοσμένα emoji σε DM με τ
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Ξεκλειδώστε την κοινή χρήση οθόνης HD με το {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Ξεκλειδώστε υψηλότερα όρια και αποκλειστικές λειτουργίες, υποστηρίζοντας ταυτόχρονα μια ανεξάρτητη πλατφόρμα επικοινωνίας."
@@ -36044,7 +36075,7 @@ msgstr "μη αναγνωσμένο"
#. Tab label in the inbox popout filtering to channels with unread messages.
#: src/features/messaging/components/popouts/InboxPopout.tsx:30
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
msgid "Unread"
msgstr "Μη αναγνωσμένα"
@@ -37866,7 +37897,7 @@ msgstr "Οπτικές ενδείξεις που δείχνουν την κατ
#: src/features/app/components/layout/MobileBottomNav.tsx:123
#: src/features/channel/utils/ChannelUtils.tsx:31
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:17
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
msgid "Voice"
msgstr "Φωνή"
@@ -37961,7 +37992,7 @@ msgstr "Φωνητικό κανάλι"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:23
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:26
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:402
msgid "Voice channel confirmation"
msgstr "Επιβεβαίωση φωνητικού καναλιού"
@@ -37972,7 +38003,7 @@ msgid "Voice channel full"
msgstr "Το φωνητικό κανάλι είναι πλήρες"
#. Settings search entry label. Names the settings search entry in the settings UI.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:19
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:22
msgid "Voice channel join behavior"
msgstr "Συμπεριφορά εισόδου σε φωνητικό κανάλι"
@@ -38099,7 +38130,7 @@ msgstr "Άκυρο"
#: src/features/i18n/utils/CommonMessageDescriptors.ts:378
#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:181
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:183
msgid "Volume"
msgstr "Ένταση"
@@ -38984,15 +39015,15 @@ msgstr "Ετήσια {yearlyPrice}"
msgid "Yearly gift"
msgstr "Ετήσιο δώρο"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Η αναβάθμιση σε ετήσια συνδρομή έχει προγραμματιστεί για <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Η ετήσια αναβάθμιση έχει προγραμματιστεί για <0>{pendingChangeDate}</0>. Πρώτη ετήσια χρέωση: {pendingInitialPriceLabel} μετά από πίστωση {pendingCreditPriceLabel}. Μελλοντικές ετήσιες ανανεώσεις: {pendingRecurringPriceLabel}/έτος."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Η ετήσια αναβάθμιση έχει προγραμματιστεί για <0>{pendingChangeDate}</0>. Πρώτη ετήσια χρέωση: {pendingInitialPriceLabel}. Μελλοντικές ετήσιες ανανεώσεις: {pendingRecurringPriceLabel}/έτος."
@@ -39462,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Μόλις πατήσατε Tab. Η λειτουργία πληκτρολογίου είναι πλέον ενεργή, ώστε να μπορείτε να περιηγηθείτε στο {productName} χωρίς ποντίκι."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Διατηρείτε τα προνόμιά σας μέχρι την επόμενη ημερομηνία ανανέωσης και, στη συνέχεια, έχετε μια περίοδο χάριτος 3 ημερών για να εγγραφείτε ξανά και να διατηρήσετε το ιστορικό συνδρομών σας."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Διατηρείτε τα προνόμιά σας μέχρι την επόμενη ημερομηνία ανανέωσης. Ενεργοποιήστε ξανά τη συνδρομή σας πριν από τότε για να διατηρήσετε το ιστορικό συνδρομών σας."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Χάνετε όλα τα προνόμια {PREMIUM_PRODUCT_NAME} αμέσως και το ιστορικό συνδρομών σας μηδενίζεται. Αυτό δεν μπορεί να αναιρεθεί."
@@ -39508,12 +39539,12 @@ msgid "You need access to your current email to change it from here. Use phone v
msgstr "Για να αλλάξετε το email σας από εδώ, πρέπει να έχετε πρόσβαση στο τρέχον email σας. Χρησιμοποιήστε την επαλήθευση μέσω τηλεφώνου, αν είναι διαθέσιμη, ή επικοινωνήστε με την υποστήριξη."
#. Forward dialog error shown when the forwarded message has attachments and the user lacks Attach Files in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:63
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:64
msgid "You need the \"{attachFilesPermissionLabel}\" permission to attach files in this channel"
msgstr "Χρειάζεστε το δικαίωμα «{attachFilesPermissionLabel}» για να επισυνάψετε αρχεία σε αυτό το κανάλι"
#. Forward dialog error shown when the forwarded message contains embeds and the user lacks Embed Links in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:58
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:59
msgid "You need the \"{embedLinksPermissionLabel}\" permission to embed links in this channel"
msgstr "Χρειάζεστε το δικαίωμα «{embedLinksPermissionLabel}» για να ενσωματώσετε συνδέσμους σε αυτό το κανάλι"
@@ -40200,6 +40231,11 @@ msgstr "η περιοχή σας"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Η εγγραφή σας χρειάζεται έναν επιπλέον έλεγχο κατά των ανεπιθύμητων μηνυμάτων πριν συνεχίσετε."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Η πληρωμή ανανέωσης απέτυχε, αλλά τα <0/> παραμένουν ενεργά έως <1>{graceDate}</1>. Ενημερώστε τον τρόπο πληρωμής σας πριν από τότε για να διατηρήσετε τη συνδρομή σας."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40221,7 +40257,7 @@ msgstr "Η ροή σας είναι ακόμα ενεργή"
msgid "Your subscription can't move to the new price right now."
msgstr "Η συνδρομή σας δεν μπορεί να μετακινηθεί στη νέα τιμή αυτήν τη στιγμή."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Η συνδρομή σας έληξε, αλλά τα <0/> παραμένουν ενεργά έως <1>{graceDate}</1>. Κάντε επανεγγραφή πριν από τότε για να διατηρήσετε το ιστορικό συνδρομής σας."
@@ -40250,7 +40286,7 @@ msgstr "Η συνδρομή σας άλλαξε σε μηνιαία χρέωση
msgid "Your subscription has been switched to yearly billing."
msgstr "Η συνδρομή σας έχει αλλάξει σε ετήσια χρέωση."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Η συνδρομή σας είναι ενεργή, αλλά τα προνόμια έχουν προσωρινά τεθεί σε παύση."
@@ -40270,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Η συνδρομή σας μεταβαίνει στη νέα τιμή στις {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Η συνδρομή σας εξακολουθεί να λήγει στις <0>{cancelDate}</0>. Η τρέχουσα τιμή είναι τώρα {listPriceNewLabel}. Αν ενεργοποιήσετε ξανά τη συνδρομή, μπορείτε να περάσετε σε αυτήν την τιμή από εδώ."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "A Linux desktop update is available. Choose the package format for this system and {productName} will save it locally."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
@@ -2639,7 +2639,7 @@ msgstr "Access your basic profile information (username, avatar, etc.)"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. User settings tab for accessibility preferences (visual, motion, screen reader, etc.).
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:14
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/SettingsConstants.tsx:61
msgid "Accessibility"
msgstr "Accessibility"
@@ -3487,19 +3487,19 @@ msgstr "Alignment controls are only available on wider screens"
msgid "All"
msgstr "All"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "All <0/> included with your subscription."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "All <0/>, forever. No billing, no renewals."
@@ -4706,7 +4706,7 @@ msgstr "Attachments"
#. Generic tab / section / category label for audio content or settings.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:255
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:179
msgid "Audio"
msgstr "Audio"
@@ -6210,7 +6210,7 @@ msgid "California"
msgstr "California"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
msgid "Call"
msgstr "Call"
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Cancel import"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Cancel price change"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Cancel request"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Cancel scheduled switch"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Cancel subscription"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Cancel subscription?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Cancel the scheduled change to move to the current price instead."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Cancel upload"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Cancel yearly upgrade"
@@ -6530,7 +6530,7 @@ msgstr "Cancelling"
msgid "Cancellation"
msgstr "Cancellation"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
@@ -7088,7 +7088,7 @@ msgid "Channel"
msgstr "Channel"
#. Fallback name for an unnamed channel in the forward modal destination list. Preserve {id}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:78
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:79
msgid "Channel {id}"
msgstr "Channel {id}"
@@ -7317,7 +7317,7 @@ msgid "Chat font size"
msgstr "Chat font size"
#. Settings search synonym. Refers to the message composer area.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
msgid "chat input"
msgstr "chat input"
@@ -8726,7 +8726,7 @@ msgid "Community updated"
msgstr "Community updated"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:35
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:38
msgid "Community voice"
msgstr "Community voice"
@@ -8789,12 +8789,13 @@ msgstr "Complete the required verification to continue using {productName}."
msgid "Completely hide your {premiumProductName} badge from other users"
msgstr "Completely hide your {premiumProductName} badge from other users"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:134
#: src/features/auth/components/pages/SsoCallbackPage.tsx:118
#: src/features/auth/components/pages/SsoCallbackPage.tsx:168
#: src/features/auth/flow/HandoffApprovalFlow.tsx:218
msgid "Completing sign-in…"
msgstr "Completing sign-in…"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:138
#: src/features/auth/components/pages/SsoCallbackPage.tsx:172
msgid "Completing your sign-in…"
msgstr "Completing your sign-in…"
@@ -8912,8 +8913,8 @@ msgstr "Confirm"
#. Settings search entry label. Names the settings search entry in the settings UI.
#. Short label for an advanced voice-channel safety preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:21
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:15
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:24
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:18
msgid "Confirm before joining voice channels"
msgstr "Confirm before joining voice channels"
@@ -8952,7 +8953,7 @@ msgstr "Confirm password"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:27
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:30
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:398
msgid "Confirm voice join"
msgstr "Confirm voice join"
@@ -8963,7 +8964,7 @@ msgid "Confirmation"
msgstr "Confirmation"
#. Settings search entry description. One-line summary of what the settings search entry controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:43
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:46
msgid "Confirmation or double-click for community voice joins"
msgstr "Confirmation or double-click for community voice joins"
@@ -9200,7 +9201,7 @@ msgstr "Content safety gates"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/ui/action_menu/ContextMenu.tsx:23
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:225
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
msgid "Context menu"
msgstr "Context menu"
@@ -10871,7 +10872,7 @@ msgstr "Custom…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Customer portal"
@@ -11341,7 +11342,7 @@ msgstr "Delaware"
#: src/features/user/components/modals/tabs/component_gallery_tab/ComponentGalleryTabButtonsTab.tsx:290
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:238
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:174
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
msgid "Delete"
msgstr "Delete"
@@ -11626,7 +11627,7 @@ msgid "Deleted {duration} of the member's recent message history"
msgstr "Deleted {duration} of the member's recent message history"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
msgid "Deleted text"
msgstr "Deleted text"
@@ -12028,7 +12029,7 @@ msgid "Different sizes & member counts"
msgstr "Different sizes & member counts"
#. Toggle label and settings search entry for slightly muting text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:106
msgid "Dim strikethrough text"
msgstr "Dim strikethrough text"
@@ -12043,7 +12044,7 @@ msgstr "Direct input"
#: src/features/channel/components/bottomsheets/channel_details_bottom_sheet/ChannelDetailsBottomSheetShared.ts:14
#: src/features/channel/components/channel_header_components/developer_tools/MockingMenu.tsx:398
#: src/features/i18n/utils/CommonMessageDescriptors.ts:567
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
msgid "Direct message"
msgstr "Direct message"
@@ -12480,7 +12481,7 @@ msgid "District of Columbia"
msgstr "District of Columbia"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:180
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
msgid "DM"
msgstr "DM"
@@ -12735,6 +12736,16 @@ msgstr "Download {productName}"
msgid "Download <0>fluxer-verification</0> and place it in your <1>.well-known</1> folder so we can validate the domain."
msgstr "Download <0>fluxer-verification</0> and place it in your <1>.well-known</1> folder so we can validate the domain."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:98
msgid "Download app"
msgstr "Download app"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:106
msgid "Download app button in the sidebar"
msgstr "Download app button in the sidebar"
#. Media context menu action that downloads an audio attachment.
#: src/features/ui/action_menu/items/MediaMenuData.tsx:122
msgid "Download audio"
@@ -13227,7 +13238,6 @@ msgstr "Edit the bot avatar, tag, bio, banner, and friend request behaviour"
msgid "Edit translation provider"
msgstr "Edit translation provider"
# auto-i18n: reviewed unchanged
#. Keyboard shortcut action label shown in the shortcuts list and keybind editor. Keep short, sentence case.
#: src/features/input/state/input_keybind/shared.ts:13
msgid "Edit your messages above or below"
@@ -13434,7 +13444,7 @@ msgstr "Embeds unsuppressed"
#: src/features/app/config/AuditLogConstants.ts:167
#: src/features/emoji/components/emojis/EmojiListItem.tsx:337
#: src/features/theme_studio/sections/TokenGroups.ts:114
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
msgid "Emoji"
msgstr "Emoji"
@@ -13867,15 +13877,15 @@ msgid "End date"
msgstr "End date"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "End grace now"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "End grace period"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "End grace period now?"
@@ -14682,7 +14692,7 @@ msgid "Failed to clear trusted domains."
msgstr "Failed to clear trusted domains."
#. Short label in the authentication SSO callback page. Keep the tone plain and specific.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:28
#: src/features/auth/components/pages/SsoCallbackPage.tsx:30
msgid "Failed to complete SSO sign-in"
msgstr "Failed to complete SSO sign-in"
@@ -15028,7 +15038,7 @@ msgid "Favorite channel"
msgstr "Favourite channel"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:79
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:82
msgid "Favorite channels"
msgstr "Favourite channels"
@@ -15801,7 +15811,7 @@ msgstr "Friendly bot"
#: src/features/connection/components/modals/EditConnectionModal.tsx:86
#: src/features/search/utils/QuickSwitcherModalUtils.tsx:50
#: src/features/user/components/modals/tabs/my_profile_tab/TimezoneProfileSettings.tsx:63
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
msgid "Friends"
msgstr "Friends"
@@ -16146,7 +16156,7 @@ msgstr "Get the new {productName} app"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Type label for GIF media.
#: src/features/expressions/utils/FavoriteMemeUtils.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
msgid "GIF"
msgstr "GIF"
@@ -16337,7 +16347,7 @@ msgstr "Gift: expiring soon"
msgid "Gift: grace period (still have access)"
msgstr "Gift: grace period (still have access)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
@@ -16550,7 +16560,7 @@ msgid "Graphics"
msgstr "Graphics"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
msgid "Gray text"
msgstr "Grey text"
@@ -16816,7 +16826,7 @@ msgid "Hate speech"
msgstr "Hate speech"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
@@ -16897,11 +16907,21 @@ msgstr "Hello, {username}! Nice to have you here."
msgid "Help"
msgstr "Help"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:94
msgid "Help button"
msgstr "Help button"
#. Short label in the sidebar navigation help button.
#: src/features/app/components/layout/sidebar_nav/HelpButton.tsx:27
msgid "Help center"
msgstr "Help centre"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:102
msgid "Help center button in the sidebar"
msgstr "Help centre button in the sidebar"
#: src/features/user/components/modals/tabs/LanguageTab.tsx:348
msgid "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
msgstr "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
@@ -17036,7 +17056,7 @@ msgid "Hide join messages"
msgstr "Hide join messages"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:47
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:50
msgid "Hide keyboard hints"
msgstr "Hide keyboard hints"
@@ -18722,7 +18742,7 @@ msgstr "Join video call"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/profile/VoiceActivityCard.tsx:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:31
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:34
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:454
msgid "Join voice"
msgstr "Join voice"
@@ -18765,6 +18785,7 @@ msgstr "Jump between unread channels"
msgid "Jump between unread channels with mentions"
msgstr "Jump between unread channels with mentions"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:121
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:75
msgid "Jump straight to the app to continue."
msgstr "Jump straight to the app to continue."
@@ -18905,7 +18926,7 @@ msgstr "Keep attachments when clearing an edit"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Keep free and premium tiers. You can customise the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Keep grace period"
@@ -18919,7 +18940,7 @@ msgstr "Keep Neko still"
msgid "Keep running"
msgstr "Keep running"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Keep subscription"
@@ -18981,7 +19002,7 @@ msgid "Keyboard mode"
msgstr "Keyboard mode"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:59
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:62
msgid "Keyboard shortcut hints in tooltips"
msgstr "Keyboard shortcut hints in tooltips"
@@ -19276,8 +19297,8 @@ msgstr "Left mouse button"
msgid "Left tooltip"
msgstr "Left tooltip"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Legacy rate"
@@ -20095,7 +20116,7 @@ msgstr "Mark top inbox channel as read"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:364
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
msgid "Markdown"
msgstr "Markdown"
@@ -20645,7 +20666,7 @@ msgstr "Mention this role?"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/guild/components/modals/GuildNotificationSettingsModal.tsx:136
#: src/features/i18n/utils/CommonMessageDescriptors.ts:648
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
msgid "Mentions"
msgstr "Mentions"
@@ -21159,7 +21180,7 @@ msgid "Missing client_id"
msgstr "Missing client_id"
#. SSO callback page error shown when the SSO callback is missing code or state parameters.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:24
#: src/features/auth/components/pages/SsoCallbackPage.tsx:26
msgid "Missing SSO code. Sign in again."
msgstr "Missing SSO code. Sign in again."
@@ -21318,11 +21339,11 @@ msgstr "Monthly"
msgid "Monthly {monthlyPrice}"
msgstr "Monthly {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Monthly billing starts on <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
@@ -21757,7 +21778,7 @@ msgstr "muted"
#. Status label indicating the surface is currently muted.
#: src/features/app/components/layout/sidebar_nav/UseGuildListItemState.ts:23
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:491
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/lib/overlay/OverlayContextMenu.tsx:24
msgid "Muted"
msgstr "Muted"
@@ -21780,7 +21801,7 @@ msgstr "Muted by moderators"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:495
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
msgid "Muted channels"
msgstr "Muted channels"
@@ -21993,7 +22014,7 @@ msgid "Narrates only the channel you're viewing. Narration follows you between c
msgstr "Narrates only the channel you're viewing. Narration follows you between channels."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
msgid "Narration"
msgstr "Narration"
@@ -22058,12 +22079,12 @@ msgid "Need an account?"
msgstr "Need an account?"
#. Settings search synonym. Proper name of the optional cat sprite that chases the cursor.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
msgid "Neko"
msgstr "Neko"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:63
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:66
msgid "Neko cat that chases your cursor"
msgstr "Neko cat that chases your cursor"
@@ -22248,12 +22269,12 @@ msgid "New password"
msgstr "New password"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "New price scheduled for <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
@@ -23561,6 +23582,8 @@ msgid "Open {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName}
msgstr "Open {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName} → {macosScreenRecordingPermissionName}, then allow {productName}. If {productName2} is already enabled, fully quit and restart {productName3} so macOS applies the permission."
#. Button label that opens the desktop app. productName is the app name.
#. Button that hands SSO sign-in back to the mobile app. productName is the app name.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:34
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:27
msgid "Open {productName}"
msgstr "Open {productName}"
@@ -24946,7 +24969,7 @@ msgstr "Pin this message to the channel for everyone to see."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Voice stats field label (mobile lobby). Shows current latency in ms.
#. Voice stats field label (mobile voice lobby). Shows current latency in ms.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:184
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/voice/components/bottomsheets/DirectCallLobbyBottomSheet.tsx:118
#: src/features/voice/components/bottomsheets/VoiceLobbyBottomSheet.tsx:86
msgid "Ping"
@@ -25166,7 +25189,7 @@ msgid "Popped out"
msgstr "Popped out"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:204
msgid "Popup"
msgstr "Popup"
@@ -26129,7 +26152,7 @@ msgstr "Reactions"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Reactivate"
@@ -26140,7 +26163,7 @@ msgid "Reactivate subscription"
msgstr "Reactivate subscription"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
msgid "Read aloud"
msgstr "Read aloud"
@@ -26157,7 +26180,7 @@ msgstr "Read message history"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:177
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
msgid "Read messages"
msgstr "Read messages"
@@ -26352,8 +26375,8 @@ msgstr "Redeem for yourself"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Redeem gift code"
@@ -26631,7 +26654,7 @@ msgstr "Remember window size and position"
#: src/features/user/components/modals/tabs/chat_settings_tab/SearchEnginesTab.tsx:26
#: src/features/user/components/modals/tabs/LinkedAccountsTab.tsx:55
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:178
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:200
#: src/features/webhook/components/WebhookListItem.tsx:277
msgid "Remove"
msgstr "Remove"
@@ -27124,7 +27147,7 @@ msgstr "Renew threshold (days)"
msgid "Renew window (days)"
msgstr "Renew window (days)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Renews on <0>{renewalDate}.</0>"
@@ -27196,7 +27219,6 @@ msgstr "Reply mention preference for this community"
msgid "Reply to message"
msgstr "Reply to message"
# auto-i18n: reviewed unchanged
#. Keyboard shortcut action label shown in the shortcuts list and keybind editor. Keep short, sentence case.
#: src/features/input/state/input_keybind/shared.ts:29
msgid "Reply to messages above or below"
@@ -27323,7 +27345,7 @@ msgid "Require a passkey as your second factor"
msgstr "Require a passkey as your second factor"
#. Short label for an advanced voice-channel navigation preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:17
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:20
msgid "Require double-click to join voice channels"
msgstr "Require double-click to join voice channels"
@@ -27874,8 +27896,8 @@ msgstr "Restore window"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Resubscribe"
@@ -29580,7 +29602,7 @@ msgid "Sending malware or dangerous links"
msgstr "Sending malware or dangerous links"
#. Short label under a destination row in the forward modal, shown when the community has messaging disabled.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:54
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:55
msgid "Sending messages is disabled in this community"
msgstr "Sending messages is disabled in this community"
@@ -30122,7 +30144,7 @@ msgstr "Shortcut"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:55
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:58
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:370
msgid "Shortcut badges"
msgstr "Shortcut badges"
@@ -30282,7 +30304,9 @@ msgid "Show delete button"
msgstr "Show delete button"
#. Short label for an advanced media button preference.
#. Toggle label and settings search entry for showing the download app button in the sidebar.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:76
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
msgid "Show download button"
msgstr "Show download button"
@@ -30324,7 +30348,7 @@ msgid "Show favorite button"
msgstr "Show favourite button"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:87
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:90
msgid "Show favorites throughout the app"
msgstr "Show favourites throughout the app"
@@ -30352,6 +30376,11 @@ msgstr "Show GIF indicator"
msgid "Show GIFs button"
msgstr "Show GIFs button"
#. Toggle label and settings search entry for showing the help center button in the sidebar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
msgid "Show help center button"
msgstr "Show help centre button"
#. Switch label in the community-folder settings modal. When on, the folder icon is shown in the sidebar while the folder is collapsed.
#: src/features/guild/components/modals/GuildFolderSettingsModal.tsx:77
msgid "Show icon when collapsed"
@@ -30567,7 +30596,7 @@ msgid "Show stickers in expression autocomplete"
msgstr "Show stickers in expression autocomplete"
#. Description for a visual accessibility setting that mutes the color of text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:110
msgid "Show strikethrough Markdown text in a slightly muted color."
msgstr "Show strikethrough Markdown text in a slightly muted colour."
@@ -31010,7 +31039,7 @@ msgid "Slowmode"
msgstr "Slowmode"
#. Short label under a destination row in the forward modal while slowmode blocks sending. Preserve {remaining}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:73
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:74
msgid "Slowmode · wait {remaining}"
msgstr "Slowmode · wait {remaining}"
@@ -31561,7 +31590,7 @@ msgstr "Spectators - {count}"
#. Native macOS Edit submenu title for text-to-speech actions.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/platform/utils/DesktopLocaleBridge.ts:85
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
msgid "Speech"
msgstr "Speech"
@@ -31672,12 +31701,12 @@ msgstr "Square icon buttons"
msgid "SSO is required to access this workspace."
msgstr "SSO is required to access this workspace."
#: src/features/auth/components/pages/SsoCallbackPage.tsx:105
#: src/features/auth/components/pages/SsoCallbackPage.tsx:139
msgid "SSO sign-in failed"
msgstr "SSO sign-in failed"
#. SSO callback page error shown when the SSO sign-in timed out before the callback arrived.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:20
#: src/features/auth/components/pages/SsoCallbackPage.tsx:22
msgid "SSO sign-in timed out. Try again."
msgstr "SSO sign-in timed out. Try again."
@@ -31716,7 +31745,7 @@ msgid "Star animation"
msgstr "Star animation"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:83
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:86
msgid "Starred channels"
msgstr "Starred channels"
@@ -31793,7 +31822,7 @@ msgstr "Start over"
msgid "Start recording"
msgstr "Start recording"
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:592
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:582
msgid "Start searches with <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> to narrow down results."
msgstr "Start searches with <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> to narrow down results."
@@ -31833,7 +31862,7 @@ msgid "Startup"
msgstr "Startup"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:75
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:78
msgid "Static Neko"
msgstr "Static Neko"
@@ -32040,11 +32069,10 @@ msgid "Still indexing — check back in a moment"
msgstr "Still indexing — check back in a moment"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:71
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:74
msgid "Still Neko"
msgstr "Still Neko"
# auto-i18n: reviewed unchanged
#. Small toast shown only when an automatic background check before sign-in, sign-up or a similar request takes more than a couple of seconds. No user action needed. Keep it short and calm.
#: src/features/auth/altcha/CaptchaInterceptor.ts:13
msgid "Still working on it…"
@@ -32070,7 +32098,7 @@ msgid "Stop mic test"
msgstr "Stop mic test"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:70
msgid "Stop Neko from chasing your cursor while keeping it draggable and interactive."
msgstr "Stop Neko from chasing your cursor while keeping it draggable and interactive."
@@ -32262,14 +32290,14 @@ msgid "Streaming privacy on"
msgstr "Streaming privacy on"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:111
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
msgid "Strike through"
msgstr "Strike through"
#. Selection formatting toolbar button.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/lexical/composer/SelectionFormattingToolbar.tsx:72
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:107
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
msgid "Strikethrough"
msgstr "Strikethrough"
@@ -32493,7 +32521,7 @@ msgid "Switch price"
msgstr "Switch price"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Switch to {listPriceNewLabel}"
@@ -32518,7 +32546,7 @@ msgstr "Switch to direct input"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Switch to monthly"
@@ -32587,7 +32615,7 @@ msgstr "Switch to two columns"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Switch to yearly"
@@ -33077,7 +33105,7 @@ msgstr "Text us from your phone"
#. Feature label / section heading for the text-to-speech feature.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:419
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
msgid "Text-to-speech"
msgstr "Text-to-speech"
@@ -34136,7 +34164,7 @@ msgid "This member isn't connected to voice anymore."
msgstr "This member isn't connected to voice anymore."
#. Forward dialog error shown when the forwarded message contains age-restricted media and the target channel is not age-restricted.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:68
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:69
msgid "This message can only be forwarded to age-restricted channels"
msgstr "This message can only be forwarded to age-restricted channels"
@@ -34769,7 +34797,7 @@ msgid "Toolbar"
msgstr "Toolbar"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:51
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:54
msgid "Tooltip shortcuts"
msgstr "Tooltip shortcuts"
@@ -35083,7 +35111,7 @@ msgid "Try sending your message again."
msgstr "Try sending your message again."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
msgid "TTS"
msgstr "TTS"
@@ -35280,7 +35308,7 @@ msgstr "Twenty-four-hour"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:39
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:42
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:406
msgid "Two clicks"
msgstr "Two clicks"
@@ -35837,7 +35865,7 @@ msgstr "Unlock custom emojis in DMs with {premiumProductName}"
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Unlock HD screen share with {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Unlock higher limits and exclusive features while supporting an independent communication platform."
@@ -36047,7 +36075,7 @@ msgstr "unread"
#. Tab label in the inbox popout filtering to channels with unread messages.
#: src/features/messaging/components/popouts/InboxPopout.tsx:30
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
msgid "Unread"
msgstr "Unread"
@@ -37869,7 +37897,7 @@ msgstr "Visual indicators showing user status, rendered using the same masked st
#: src/features/app/components/layout/MobileBottomNav.tsx:123
#: src/features/channel/utils/ChannelUtils.tsx:31
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:17
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
msgid "Voice"
msgstr "Voice"
@@ -37964,7 +37992,7 @@ msgstr "Voice channel"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:23
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:26
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:402
msgid "Voice channel confirmation"
msgstr "Voice channel confirmation"
@@ -37975,7 +38003,7 @@ msgid "Voice channel full"
msgstr "Voice channel full"
#. Settings search entry label. Names the settings search entry in the settings UI.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:19
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:22
msgid "Voice channel join behavior"
msgstr "Voice channel join behaviour"
@@ -38102,7 +38130,7 @@ msgstr "Void"
#: src/features/i18n/utils/CommonMessageDescriptors.ts:378
#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:181
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:183
msgid "Volume"
msgstr "Volume"
@@ -38987,15 +39015,15 @@ msgstr "Yearly {yearlyPrice}"
msgid "Yearly gift"
msgstr "Yearly gift"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
@@ -39465,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "You just pressed Tab. Keyboard mode is now on so you can navigate {productName} without a mouse."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
@@ -39511,12 +39539,12 @@ msgid "You need access to your current email to change it from here. Use phone v
msgstr "You need access to your current email to change it from here. Use phone verification if available or contact support."
#. Forward dialog error shown when the forwarded message has attachments and the user lacks Attach Files in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:63
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:64
msgid "You need the \"{attachFilesPermissionLabel}\" permission to attach files in this channel"
msgstr "You need the \"{attachFilesPermissionLabel}\" permission to attach files in this channel"
#. Forward dialog error shown when the forwarded message contains embeds and the user lacks Embed Links in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:58
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:59
msgid "You need the \"{embedLinksPermissionLabel}\" permission to embed links in this channel"
msgstr "You need the \"{embedLinksPermissionLabel}\" permission to embed links in this channel"
@@ -40203,6 +40231,11 @@ msgstr "your region"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Your registration needs an extra anti-spam check before you can continue."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40224,7 +40257,7 @@ msgstr "Your stream is still live"
msgid "Your subscription can't move to the new price right now."
msgstr "Your subscription can't move to the new price right now."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
@@ -40253,7 +40286,7 @@ msgstr "Your subscription has been switched to monthly billing."
msgid "Your subscription has been switched to yearly billing."
msgstr "Your subscription has been switched to yearly billing."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Your subscription is active but perks are temporarily paused."
@@ -40273,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Your subscription moves to the new price on {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "A Linux desktop update is available. Choose the package format for this system and {productName} will save it locally."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
@@ -2639,7 +2639,7 @@ msgstr "Access your basic profile information (username, avatar, etc.)"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. User settings tab for accessibility preferences (visual, motion, screen reader, etc.).
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:14
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/SettingsConstants.tsx:61
msgid "Accessibility"
msgstr "Accessibility"
@@ -3487,19 +3487,19 @@ msgstr "Alignment controls are only available on wider screens"
msgid "All"
msgstr "All"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "All <0/> included with your subscription."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "All <0/>, forever. No billing, no renewals."
@@ -4706,7 +4706,7 @@ msgstr "Attachments"
#. Generic tab / section / category label for audio content or settings.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:255
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:179
msgid "Audio"
msgstr "Audio"
@@ -6210,7 +6210,7 @@ msgid "California"
msgstr "California"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
msgid "Call"
msgstr "Call"
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Cancel import"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Cancel price change"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Cancel request"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Cancel scheduled switch"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Cancel subscription"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Cancel subscription?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Cancel the scheduled change to move to the current price instead."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Cancel upload"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Cancel yearly upgrade"
@@ -6530,7 +6530,7 @@ msgstr "Canceling"
msgid "Cancellation"
msgstr "Cancellation"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
@@ -7088,7 +7088,7 @@ msgid "Channel"
msgstr "Channel"
#. Fallback name for an unnamed channel in the forward modal destination list. Preserve {id}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:78
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:79
msgid "Channel {id}"
msgstr "Channel {id}"
@@ -7317,7 +7317,7 @@ msgid "Chat font size"
msgstr "Chat font size"
#. Settings search synonym. Refers to the message composer area.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
msgid "chat input"
msgstr "chat input"
@@ -8726,7 +8726,7 @@ msgid "Community updated"
msgstr "Community updated"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:35
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:38
msgid "Community voice"
msgstr "Community voice"
@@ -8789,12 +8789,13 @@ msgstr "Complete the required verification to continue using {productName}."
msgid "Completely hide your {premiumProductName} badge from other users"
msgstr "Completely hide your {premiumProductName} badge from other users"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:134
#: src/features/auth/components/pages/SsoCallbackPage.tsx:118
#: src/features/auth/components/pages/SsoCallbackPage.tsx:168
#: src/features/auth/flow/HandoffApprovalFlow.tsx:218
msgid "Completing sign-in…"
msgstr "Completing sign-in…"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:138
#: src/features/auth/components/pages/SsoCallbackPage.tsx:172
msgid "Completing your sign-in…"
msgstr "Completing your sign-in…"
@@ -8912,8 +8913,8 @@ msgstr "Confirm"
#. Settings search entry label. Names the settings search entry in the settings UI.
#. Short label for an advanced voice-channel safety preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:21
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:15
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:24
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:18
msgid "Confirm before joining voice channels"
msgstr "Confirm before joining voice channels"
@@ -8952,7 +8953,7 @@ msgstr "Confirm password"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:27
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:30
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:398
msgid "Confirm voice join"
msgstr "Confirm voice join"
@@ -8963,7 +8964,7 @@ msgid "Confirmation"
msgstr "Confirmation"
#. Settings search entry description. One-line summary of what the settings search entry controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:43
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:46
msgid "Confirmation or double-click for community voice joins"
msgstr "Confirmation or double-click for community voice joins"
@@ -9200,7 +9201,7 @@ msgstr "Content safety gates"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/ui/action_menu/ContextMenu.tsx:23
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:225
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
msgid "Context menu"
msgstr "Context menu"
@@ -10871,7 +10872,7 @@ msgstr "Custom…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Customer portal"
@@ -11341,7 +11342,7 @@ msgstr "Delaware"
#: src/features/user/components/modals/tabs/component_gallery_tab/ComponentGalleryTabButtonsTab.tsx:290
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:238
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:174
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
msgid "Delete"
msgstr "Delete"
@@ -11626,7 +11627,7 @@ msgid "Deleted {duration} of the member's recent message history"
msgstr "Deleted {duration} of the member's recent message history"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
msgid "Deleted text"
msgstr "Deleted text"
@@ -12028,7 +12029,7 @@ msgid "Different sizes & member counts"
msgstr "Different sizes & member counts"
#. Toggle label and settings search entry for slightly muting text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:106
msgid "Dim strikethrough text"
msgstr "Dim strikethrough text"
@@ -12043,7 +12044,7 @@ msgstr "Direct input"
#: src/features/channel/components/bottomsheets/channel_details_bottom_sheet/ChannelDetailsBottomSheetShared.ts:14
#: src/features/channel/components/channel_header_components/developer_tools/MockingMenu.tsx:398
#: src/features/i18n/utils/CommonMessageDescriptors.ts:567
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
msgid "Direct message"
msgstr "Direct message"
@@ -12480,7 +12481,7 @@ msgid "District of Columbia"
msgstr "District of Columbia"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:180
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
msgid "DM"
msgstr "DM"
@@ -12735,6 +12736,16 @@ msgstr "Download {productName}"
msgid "Download <0>fluxer-verification</0> and place it in your <1>.well-known</1> folder so we can validate the domain."
msgstr "Download <0>fluxer-verification</0> and place it in your <1>.well-known</1> folder so we can validate the domain."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:98
msgid "Download app"
msgstr "Download app"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:106
msgid "Download app button in the sidebar"
msgstr "Download app button in the sidebar"
#. Media context menu action that downloads an audio attachment.
#: src/features/ui/action_menu/items/MediaMenuData.tsx:122
msgid "Download audio"
@@ -13433,7 +13444,7 @@ msgstr "Embeds unsuppressed"
#: src/features/app/config/AuditLogConstants.ts:167
#: src/features/emoji/components/emojis/EmojiListItem.tsx:337
#: src/features/theme_studio/sections/TokenGroups.ts:114
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
msgid "Emoji"
msgstr "Emoji"
@@ -13866,15 +13877,15 @@ msgid "End date"
msgstr "End date"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "End grace now"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "End grace period"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "End grace period now?"
@@ -14681,7 +14692,7 @@ msgid "Failed to clear trusted domains."
msgstr "Failed to clear trusted domains."
#. Short label in the authentication SSO callback page. Keep the tone plain and specific.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:28
#: src/features/auth/components/pages/SsoCallbackPage.tsx:30
msgid "Failed to complete SSO sign-in"
msgstr "Failed to complete SSO sign-in"
@@ -15027,7 +15038,7 @@ msgid "Favorite channel"
msgstr "Favorite channel"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:79
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:82
msgid "Favorite channels"
msgstr "Favorite channels"
@@ -15800,7 +15811,7 @@ msgstr "Friendly bot"
#: src/features/connection/components/modals/EditConnectionModal.tsx:86
#: src/features/search/utils/QuickSwitcherModalUtils.tsx:50
#: src/features/user/components/modals/tabs/my_profile_tab/TimezoneProfileSettings.tsx:63
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
msgid "Friends"
msgstr "Friends"
@@ -16145,7 +16156,7 @@ msgstr "Get the new {productName} app"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Type label for GIF media.
#: src/features/expressions/utils/FavoriteMemeUtils.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
msgid "GIF"
msgstr "GIF"
@@ -16336,7 +16347,7 @@ msgstr "Gift: expiring soon"
msgid "Gift: grace period (still have access)"
msgstr "Gift: grace period (still have access)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
@@ -16549,7 +16560,7 @@ msgid "Graphics"
msgstr "Graphics"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
msgid "Gray text"
msgstr "Gray text"
@@ -16815,7 +16826,7 @@ msgid "Hate speech"
msgstr "Hate speech"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
@@ -16896,11 +16907,21 @@ msgstr "Hello, {username}! Nice to have you here."
msgid "Help"
msgstr "Help"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:94
msgid "Help button"
msgstr "Help button"
#. Short label in the sidebar navigation help button.
#: src/features/app/components/layout/sidebar_nav/HelpButton.tsx:27
msgid "Help center"
msgstr "Help center"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:102
msgid "Help center button in the sidebar"
msgstr "Help center button in the sidebar"
#: src/features/user/components/modals/tabs/LanguageTab.tsx:348
msgid "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
msgstr "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
@@ -17035,7 +17056,7 @@ msgid "Hide join messages"
msgstr "Hide join messages"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:47
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:50
msgid "Hide keyboard hints"
msgstr "Hide keyboard hints"
@@ -18721,7 +18742,7 @@ msgstr "Join video call"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/profile/VoiceActivityCard.tsx:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:31
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:34
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:454
msgid "Join voice"
msgstr "Join voice"
@@ -18764,6 +18785,7 @@ msgstr "Jump between unread channels"
msgid "Jump between unread channels with mentions"
msgstr "Jump between unread channels with mentions"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:121
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:75
msgid "Jump straight to the app to continue."
msgstr "Jump straight to the app to continue."
@@ -18904,7 +18926,7 @@ msgstr "Keep attachments when clearing an edit"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Keep grace period"
@@ -18918,7 +18940,7 @@ msgstr "Keep Neko still"
msgid "Keep running"
msgstr "Keep running"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Keep subscription"
@@ -18980,7 +19002,7 @@ msgid "Keyboard mode"
msgstr "Keyboard mode"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:59
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:62
msgid "Keyboard shortcut hints in tooltips"
msgstr "Keyboard shortcut hints in tooltips"
@@ -19275,8 +19297,8 @@ msgstr "Left mouse button"
msgid "Left tooltip"
msgstr "Left tooltip"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Legacy rate"
@@ -20094,7 +20116,7 @@ msgstr "Mark top inbox channel as read"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:364
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
msgid "Markdown"
msgstr "Markdown"
@@ -20644,7 +20666,7 @@ msgstr "Mention this role?"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/guild/components/modals/GuildNotificationSettingsModal.tsx:136
#: src/features/i18n/utils/CommonMessageDescriptors.ts:648
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
msgid "Mentions"
msgstr "Mentions"
@@ -21158,7 +21180,7 @@ msgid "Missing client_id"
msgstr "Missing client_id"
#. SSO callback page error shown when the SSO callback is missing code or state parameters.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:24
#: src/features/auth/components/pages/SsoCallbackPage.tsx:26
msgid "Missing SSO code. Sign in again."
msgstr "Missing SSO code. Sign in again."
@@ -21317,11 +21339,11 @@ msgstr "Monthly"
msgid "Monthly {monthlyPrice}"
msgstr "Monthly {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Monthly billing starts on <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
@@ -21756,7 +21778,7 @@ msgstr "muted"
#. Status label indicating the surface is currently muted.
#: src/features/app/components/layout/sidebar_nav/UseGuildListItemState.ts:23
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:491
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/lib/overlay/OverlayContextMenu.tsx:24
msgid "Muted"
msgstr "Muted"
@@ -21779,7 +21801,7 @@ msgstr "Muted by moderators"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:495
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
msgid "Muted channels"
msgstr "Muted channels"
@@ -21992,7 +22014,7 @@ msgid "Narrates only the channel you're viewing. Narration follows you between c
msgstr "Narrates only the channel you're viewing. Narration follows you between channels."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
msgid "Narration"
msgstr "Narration"
@@ -22057,12 +22079,12 @@ msgid "Need an account?"
msgstr "Need an account?"
#. Settings search synonym. Proper name of the optional cat sprite that chases the cursor.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
msgid "Neko"
msgstr "Neko"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:63
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:66
msgid "Neko cat that chases your cursor"
msgstr "Neko cat that chases your cursor"
@@ -22247,12 +22269,12 @@ msgid "New password"
msgstr "New password"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "New price scheduled for <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
@@ -23560,6 +23582,8 @@ msgid "Open {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName}
msgstr "Open {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName} → {macosScreenRecordingPermissionName}, then allow {productName}. If {productName2} is already enabled, fully quit and restart {productName3} so macOS applies the permission."
#. Button label that opens the desktop app. productName is the app name.
#. Button that hands SSO sign-in back to the mobile app. productName is the app name.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:34
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:27
msgid "Open {productName}"
msgstr "Open {productName}"
@@ -24945,7 +24969,7 @@ msgstr "Pin this message to the channel for everyone to see."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Voice stats field label (mobile lobby). Shows current latency in ms.
#. Voice stats field label (mobile voice lobby). Shows current latency in ms.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:184
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/voice/components/bottomsheets/DirectCallLobbyBottomSheet.tsx:118
#: src/features/voice/components/bottomsheets/VoiceLobbyBottomSheet.tsx:86
msgid "Ping"
@@ -25165,7 +25189,7 @@ msgid "Popped out"
msgstr "Popped out"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:204
msgid "Popup"
msgstr "Popup"
@@ -26128,7 +26152,7 @@ msgstr "Reactions"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Reactivate"
@@ -26139,7 +26163,7 @@ msgid "Reactivate subscription"
msgstr "Reactivate subscription"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
msgid "Read aloud"
msgstr "Read aloud"
@@ -26156,7 +26180,7 @@ msgstr "Read message history"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:177
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
msgid "Read messages"
msgstr "Read messages"
@@ -26351,8 +26375,8 @@ msgstr "Redeem for yourself"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Redeem gift code"
@@ -26630,7 +26654,7 @@ msgstr "Remember window size and position"
#: src/features/user/components/modals/tabs/chat_settings_tab/SearchEnginesTab.tsx:26
#: src/features/user/components/modals/tabs/LinkedAccountsTab.tsx:55
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:178
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:200
#: src/features/webhook/components/WebhookListItem.tsx:277
msgid "Remove"
msgstr "Remove"
@@ -27123,7 +27147,7 @@ msgstr "Renew threshold (days)"
msgid "Renew window (days)"
msgstr "Renew window (days)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Renews on <0>{renewalDate}.</0>"
@@ -27321,7 +27345,7 @@ msgid "Require a passkey as your second factor"
msgstr "Require a passkey as your second factor"
#. Short label for an advanced voice-channel navigation preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:17
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:20
msgid "Require double-click to join voice channels"
msgstr "Require double-click to join voice channels"
@@ -27872,8 +27896,8 @@ msgstr "Restore window"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Resubscribe"
@@ -29578,7 +29602,7 @@ msgid "Sending malware or dangerous links"
msgstr "Sending malware or dangerous links"
#. Short label under a destination row in the forward modal, shown when the community has messaging disabled.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:54
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:55
msgid "Sending messages is disabled in this community"
msgstr "Sending messages is disabled in this community"
@@ -30120,7 +30144,7 @@ msgstr "Shortcut"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:55
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:58
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:370
msgid "Shortcut badges"
msgstr "Shortcut badges"
@@ -30280,7 +30304,9 @@ msgid "Show delete button"
msgstr "Show delete button"
#. Short label for an advanced media button preference.
#. Toggle label and settings search entry for showing the download app button in the sidebar.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:76
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
msgid "Show download button"
msgstr "Show download button"
@@ -30322,7 +30348,7 @@ msgid "Show favorite button"
msgstr "Show favorite button"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:87
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:90
msgid "Show favorites throughout the app"
msgstr "Show favorites throughout the app"
@@ -30350,6 +30376,11 @@ msgstr "Show GIF indicator"
msgid "Show GIFs button"
msgstr "Show GIFs button"
#. Toggle label and settings search entry for showing the help center button in the sidebar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
msgid "Show help center button"
msgstr "Show help center button"
#. Switch label in the community-folder settings modal. When on, the folder icon is shown in the sidebar while the folder is collapsed.
#: src/features/guild/components/modals/GuildFolderSettingsModal.tsx:77
msgid "Show icon when collapsed"
@@ -30565,7 +30596,7 @@ msgid "Show stickers in expression autocomplete"
msgstr "Show stickers in expression autocomplete"
#. Description for a visual accessibility setting that mutes the color of text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:110
msgid "Show strikethrough Markdown text in a slightly muted color."
msgstr "Show strikethrough Markdown text in a slightly muted color."
@@ -31008,7 +31039,7 @@ msgid "Slowmode"
msgstr "Slowmode"
#. Short label under a destination row in the forward modal while slowmode blocks sending. Preserve {remaining}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:73
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:74
msgid "Slowmode · wait {remaining}"
msgstr "Slowmode · wait {remaining}"
@@ -31559,7 +31590,7 @@ msgstr "Spectators - {count}"
#. Native macOS Edit submenu title for text-to-speech actions.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/platform/utils/DesktopLocaleBridge.ts:85
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
msgid "Speech"
msgstr "Speech"
@@ -31670,12 +31701,12 @@ msgstr "Square icon buttons"
msgid "SSO is required to access this workspace."
msgstr "SSO is required to access this workspace."
#: src/features/auth/components/pages/SsoCallbackPage.tsx:105
#: src/features/auth/components/pages/SsoCallbackPage.tsx:139
msgid "SSO sign-in failed"
msgstr "SSO sign-in failed"
#. SSO callback page error shown when the SSO sign-in timed out before the callback arrived.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:20
#: src/features/auth/components/pages/SsoCallbackPage.tsx:22
msgid "SSO sign-in timed out. Try again."
msgstr "SSO sign-in timed out. Try again."
@@ -31714,7 +31745,7 @@ msgid "Star animation"
msgstr "Star animation"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:83
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:86
msgid "Starred channels"
msgstr "Starred channels"
@@ -31791,7 +31822,7 @@ msgstr "Start over"
msgid "Start recording"
msgstr "Start recording"
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:592
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:582
msgid "Start searches with <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> to narrow down results."
msgstr "Start searches with <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> to narrow down results."
@@ -31831,7 +31862,7 @@ msgid "Startup"
msgstr "Startup"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:75
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:78
msgid "Static Neko"
msgstr "Static Neko"
@@ -32038,7 +32069,7 @@ msgid "Still indexing — check back in a moment"
msgstr "Still indexing — check back in a moment"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:71
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:74
msgid "Still Neko"
msgstr "Still Neko"
@@ -32067,7 +32098,7 @@ msgid "Stop mic test"
msgstr "Stop mic test"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:70
msgid "Stop Neko from chasing your cursor while keeping it draggable and interactive."
msgstr "Stop Neko from chasing your cursor while keeping it draggable and interactive."
@@ -32259,14 +32290,14 @@ msgid "Streaming privacy on"
msgstr "Streaming privacy on"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:111
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
msgid "Strike through"
msgstr "Strike through"
#. Selection formatting toolbar button.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/lexical/composer/SelectionFormattingToolbar.tsx:72
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:107
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
msgid "Strikethrough"
msgstr "Strikethrough"
@@ -32490,7 +32521,7 @@ msgid "Switch price"
msgstr "Switch price"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Switch to {listPriceNewLabel}"
@@ -32515,7 +32546,7 @@ msgstr "Switch to direct input"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Switch to monthly"
@@ -32584,7 +32615,7 @@ msgstr "Switch to two columns"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Switch to yearly"
@@ -33074,7 +33105,7 @@ msgstr "Text us from your phone"
#. Feature label / section heading for the text-to-speech feature.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:419
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
msgid "Text-to-speech"
msgstr "Text-to-speech"
@@ -34133,7 +34164,7 @@ msgid "This member isn't connected to voice anymore."
msgstr "This member isn't connected to voice anymore."
#. Forward dialog error shown when the forwarded message contains age-restricted media and the target channel is not age-restricted.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:68
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:69
msgid "This message can only be forwarded to age-restricted channels"
msgstr "This message can only be forwarded to age-restricted channels"
@@ -34766,7 +34797,7 @@ msgid "Toolbar"
msgstr "Toolbar"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:51
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:54
msgid "Tooltip shortcuts"
msgstr "Tooltip shortcuts"
@@ -35080,7 +35111,7 @@ msgid "Try sending your message again."
msgstr "Try sending your message again."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
msgid "TTS"
msgstr "TTS"
@@ -35277,7 +35308,7 @@ msgstr "Twenty-four-hour"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:39
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:42
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:406
msgid "Two clicks"
msgstr "Two clicks"
@@ -35834,7 +35865,7 @@ msgstr "Unlock custom emojis in DMs with {premiumProductName}"
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Unlock HD screen share with {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Unlock higher limits and exclusive features while supporting an independent communication platform."
@@ -36044,7 +36075,7 @@ msgstr "unread"
#. Tab label in the inbox popout filtering to channels with unread messages.
#: src/features/messaging/components/popouts/InboxPopout.tsx:30
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
msgid "Unread"
msgstr "Unread"
@@ -37866,7 +37897,7 @@ msgstr "Visual indicators showing user status, rendered using the same masked st
#: src/features/app/components/layout/MobileBottomNav.tsx:123
#: src/features/channel/utils/ChannelUtils.tsx:31
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:17
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
msgid "Voice"
msgstr "Voice"
@@ -37961,7 +37992,7 @@ msgstr "Voice channel"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:23
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:26
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:402
msgid "Voice channel confirmation"
msgstr "Voice channel confirmation"
@@ -37972,7 +38003,7 @@ msgid "Voice channel full"
msgstr "Voice channel full"
#. Settings search entry label. Names the settings search entry in the settings UI.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:19
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:22
msgid "Voice channel join behavior"
msgstr "Voice channel join behavior"
@@ -38099,7 +38130,7 @@ msgstr "Void"
#: src/features/i18n/utils/CommonMessageDescriptors.ts:378
#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:181
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:183
msgid "Volume"
msgstr "Volume"
@@ -38984,15 +39015,15 @@ msgstr "Yearly {yearlyPrice}"
msgid "Yearly gift"
msgstr "Yearly gift"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
@@ -39462,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "You just pressed Tab. Keyboard mode is now on so you can navigate {productName} without a mouse."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
@@ -39508,12 +39539,12 @@ msgid "You need access to your current email to change it from here. Use phone v
msgstr "You need access to your current email to change it from here. Use phone verification if available or contact support."
#. Forward dialog error shown when the forwarded message has attachments and the user lacks Attach Files in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:63
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:64
msgid "You need the \"{attachFilesPermissionLabel}\" permission to attach files in this channel"
msgstr "You need the \"{attachFilesPermissionLabel}\" permission to attach files in this channel"
#. Forward dialog error shown when the forwarded message contains embeds and the user lacks Embed Links in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:58
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:59
msgid "You need the \"{embedLinksPermissionLabel}\" permission to embed links in this channel"
msgstr "You need the \"{embedLinksPermissionLabel}\" permission to embed links in this channel"
@@ -40200,6 +40231,11 @@ msgstr "your region"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Your registration needs an extra anti-spam check before you can continue."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40221,7 +40257,7 @@ msgstr "Your stream is still live"
msgid "Your subscription can't move to the new price right now."
msgstr "Your subscription can't move to the new price right now."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
@@ -40250,7 +40286,7 @@ msgstr "Your subscription has been switched to monthly billing."
msgid "Your subscription has been switched to yearly billing."
msgstr "Your subscription has been switched to yearly billing."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Your subscription is active but perks are temporarily paused."
@@ -40270,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Your subscription moves to the new price on {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Hay una actualización de escritorio para Linux disponible. Elige el formato del paquete para este sistema y {productName} lo guardará localmente."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Hay un precio más bajo disponible. El cambio entra en vigor el <0>{listPriceEffectiveDate}</0> y no cambia nada más."
@@ -2639,7 +2639,7 @@ msgstr "Accede a tu información básica de perfil (nombre de usuario, avatar, e
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. User settings tab for accessibility preferences (visual, motion, screen reader, etc.).
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:14
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/SettingsConstants.tsx:61
msgid "Accessibility"
msgstr "Accesibilidad"
@@ -3487,19 +3487,19 @@ msgstr "Los controles de alineación solo están disponibles en pantallas más a
msgid "All"
msgstr "Todo"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Todos los <0/> por <1>{effectiveMonthlyPrice}/mes</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Todos los <0/> por <1>{effectiveYearlyPrice}/año</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Tu suscripción incluye todos los <0/>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Todos los <0/>, para siempre. Sin facturación ni renovaciones."
@@ -4706,7 +4706,7 @@ msgstr "Archivos adjuntos"
#. Generic tab / section / category label for audio content or settings.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:255
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:179
msgid "Audio"
msgstr "Audio"
@@ -6210,7 +6210,7 @@ msgid "California"
msgstr "California"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
msgid "Call"
msgstr "Llamada"
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Cancelar importación"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Cancelar cambio de precio"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Cancelar solicitud"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Cancelar cambio programado"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Cancelar suscripción"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "¿Cancelar suscripción?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Cancela el cambio programado para pasar al precio actual en su lugar."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Cancelar carga"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Cancelar cambio al plan anual"
@@ -6530,7 +6530,7 @@ msgstr "Cancelando"
msgid "Cancellation"
msgstr "Cancelación de eco"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Se cancela el <0>{cancelDate}</0>. Los <1/> seguirán activos hasta entonces."
@@ -7088,7 +7088,7 @@ msgid "Channel"
msgstr "Canal"
#. Fallback name for an unnamed channel in the forward modal destination list. Preserve {id}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:78
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:79
msgid "Channel {id}"
msgstr "Canal {id}"
@@ -7317,7 +7317,7 @@ msgid "Chat font size"
msgstr "Tamaño de fuente del chat"
#. Settings search synonym. Refers to the message composer area.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
msgid "chat input"
msgstr "entrada de chat"
@@ -8726,7 +8726,7 @@ msgid "Community updated"
msgstr "Comunidad actualizada"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:35
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:38
msgid "Community voice"
msgstr "Voz de la comunidad"
@@ -8789,12 +8789,13 @@ msgstr "Completa la verificación requerida para seguir usando {productName}."
msgid "Completely hide your {premiumProductName} badge from other users"
msgstr "Ocultar completamente tu insignia de {premiumProductName} a otros usuarios"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:134
#: src/features/auth/components/pages/SsoCallbackPage.tsx:118
#: src/features/auth/components/pages/SsoCallbackPage.tsx:168
#: src/features/auth/flow/HandoffApprovalFlow.tsx:218
msgid "Completing sign-in…"
msgstr "Completando inicio de sesión…"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:138
#: src/features/auth/components/pages/SsoCallbackPage.tsx:172
msgid "Completing your sign-in…"
msgstr "Completando tu inicio de sesión…"
@@ -8912,8 +8913,8 @@ msgstr "Confirmar"
#. Settings search entry label. Names the settings search entry in the settings UI.
#. Short label for an advanced voice-channel safety preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:21
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:15
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:24
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:18
msgid "Confirm before joining voice channels"
msgstr "Confirmar antes de unirte a canales de voz"
@@ -8952,7 +8953,7 @@ msgstr "Confirmar contraseña"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:27
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:30
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:398
msgid "Confirm voice join"
msgstr "Confirmar conexión a canales de voz"
@@ -8963,7 +8964,7 @@ msgid "Confirmation"
msgstr "Confirmación"
#. Settings search entry description. One-line summary of what the settings search entry controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:43
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:46
msgid "Confirmation or double-click for community voice joins"
msgstr "Confirmación o doble clic para unirse a canales de voz de la comunidad"
@@ -9200,7 +9201,7 @@ msgstr "Filtros de seguridad de contenido"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/ui/action_menu/ContextMenu.tsx:23
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:225
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
msgid "Context menu"
msgstr "Menú contextual"
@@ -10871,7 +10872,7 @@ msgstr "Personalizar…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Portal de clientes"
@@ -11341,7 +11342,7 @@ msgstr "Delaware"
#: src/features/user/components/modals/tabs/component_gallery_tab/ComponentGalleryTabButtonsTab.tsx:290
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:238
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:174
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
msgid "Delete"
msgstr "Eliminar"
@@ -11626,7 +11627,7 @@ msgid "Deleted {duration} of the member's recent message history"
msgstr "Se eliminó el historial de mensajes del miembro de hasta {duration} de antigüedad"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
msgid "Deleted text"
msgstr "Texto eliminado"
@@ -12028,7 +12029,7 @@ msgid "Different sizes & member counts"
msgstr "Diferentes tamaños y recuentos de miembros"
#. Toggle label and settings search entry for slightly muting text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:106
msgid "Dim strikethrough text"
msgstr "Atenuar texto tachado"
@@ -12043,7 +12044,7 @@ msgstr "Entrada directa"
#: src/features/channel/components/bottomsheets/channel_details_bottom_sheet/ChannelDetailsBottomSheetShared.ts:14
#: src/features/channel/components/channel_header_components/developer_tools/MockingMenu.tsx:398
#: src/features/i18n/utils/CommonMessageDescriptors.ts:567
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
msgid "Direct message"
msgstr "Mensaje directo"
@@ -12480,7 +12481,7 @@ msgid "District of Columbia"
msgstr "Distrito de Columbia"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:180
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
msgid "DM"
msgstr "MD"
@@ -12735,6 +12736,16 @@ msgstr "Descargar {productName}"
msgid "Download <0>fluxer-verification</0> and place it in your <1>.well-known</1> folder so we can validate the domain."
msgstr "Descarga <0>fluxer-verification</0> y colócalo en tu carpeta <1>.well-known</1> para que podamos validar el dominio."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:98
msgid "Download app"
msgstr "Descargar app"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:106
msgid "Download app button in the sidebar"
msgstr "Descargar la app"
#. Media context menu action that downloads an audio attachment.
#: src/features/ui/action_menu/items/MediaMenuData.tsx:122
msgid "Download audio"
@@ -13433,7 +13444,7 @@ msgstr "Contenido incrustado restaurado"
#: src/features/app/config/AuditLogConstants.ts:167
#: src/features/emoji/components/emojis/EmojiListItem.tsx:337
#: src/features/theme_studio/sections/TokenGroups.ts:114
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
msgid "Emoji"
msgstr "Emoji"
@@ -13866,15 +13877,15 @@ msgid "End date"
msgstr "Fecha de finalización"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Terminar período de gracia ahora"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Finalizar período de gracia"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "¿Terminar período de gracia ahora?"
@@ -14681,7 +14692,7 @@ msgid "Failed to clear trusted domains."
msgstr "No se pudieron borrar los dominios de confianza."
#. Short label in the authentication SSO callback page. Keep the tone plain and specific.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:28
#: src/features/auth/components/pages/SsoCallbackPage.tsx:30
msgid "Failed to complete SSO sign-in"
msgstr "No se pudo completar el inicio de sesión único"
@@ -15027,7 +15038,7 @@ msgid "Favorite channel"
msgstr "Marcar canal como favorito"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:79
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:82
msgid "Favorite channels"
msgstr "Canales favoritos"
@@ -15800,7 +15811,7 @@ msgstr "Bot amigable"
#: src/features/connection/components/modals/EditConnectionModal.tsx:86
#: src/features/search/utils/QuickSwitcherModalUtils.tsx:50
#: src/features/user/components/modals/tabs/my_profile_tab/TimezoneProfileSettings.tsx:63
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
msgid "Friends"
msgstr "Amigos"
@@ -16145,7 +16156,7 @@ msgstr "Descarga la nueva app {productName}"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Type label for GIF media.
#: src/features/expressions/utils/FavoriteMemeUtils.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
msgid "GIF"
msgstr "GIF"
@@ -16336,7 +16347,7 @@ msgstr "Regalo: vence pronto"
msgid "Gift: grace period (still have access)"
msgstr "Regalo: período de gracia (aún tiene acceso)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Los <0/> de regalo están activos hasta el <1>{giftEndDate}</1>. No se renuevan automáticamente. Canjea más códigos de regalo para prolongarlos."
@@ -16549,7 +16560,7 @@ msgid "Graphics"
msgstr "Gráficos"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
msgid "Gray text"
msgstr "Texto gris"
@@ -16815,7 +16826,7 @@ msgid "Hate speech"
msgstr "Discurso de odio"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "¿Tienes un código de regalo? Canjéalo para desbloquear {PREMIUM_PRODUCT_NAME}."
@@ -16896,11 +16907,21 @@ msgstr "¡Hola, {username}! Qué bueno tenerte aquí."
msgid "Help"
msgstr "Ayuda"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:94
msgid "Help button"
msgstr "Botón de ayuda"
#. Short label in the sidebar navigation help button.
#: src/features/app/components/layout/sidebar_nav/HelpButton.tsx:27
msgid "Help center"
msgstr "Centro de ayuda"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:102
msgid "Help center button in the sidebar"
msgstr "Centro de ayuda"
#: src/features/user/components/modals/tabs/LanguageTab.tsx:348
msgid "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
msgstr "Ayuda a traducir {PRODUCT_NAME} a tu idioma en <0>{I18N_WEBLATE_DOMAIN}</0>."
@@ -17035,7 +17056,7 @@ msgid "Hide join messages"
msgstr "Ocultar avisos de incorporación"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:47
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:50
msgid "Hide keyboard hints"
msgstr "Ocultar sugerencias del teclado"
@@ -18721,7 +18742,7 @@ msgstr "Unirse a la videollamada"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/profile/VoiceActivityCard.tsx:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:31
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:34
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:454
msgid "Join voice"
msgstr "Unirse a la llamada de voz"
@@ -18764,6 +18785,7 @@ msgstr "Saltar entre canales no leídos"
msgid "Jump between unread channels with mentions"
msgstr "Saltar entre canales no leídos con menciones"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:121
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:75
msgid "Jump straight to the app to continue."
msgstr "Ve directo a la app para continuar."
@@ -18904,7 +18926,7 @@ msgstr "Conservar archivos adjuntos al borrar el texto de una edición"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Mantén los niveles gratuito y premium. Puedes personalizar los niveles, vender premium a través de Stripe o entregar códigos de regalo más tarde desde el panel de administración."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Mantener período de gracia"
@@ -18918,7 +18940,7 @@ msgstr "Mantener a Neko quieto"
msgid "Keep running"
msgstr "Seguir ejecutándose"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Mantener suscripción"
@@ -18980,7 +19002,7 @@ msgid "Keyboard mode"
msgstr "Modo teclado"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:59
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:62
msgid "Keyboard shortcut hints in tooltips"
msgstr "Indicaciones de atajos de teclado en la ayuda emergente"
@@ -19275,8 +19297,8 @@ msgstr "Botón izquierdo del mouse"
msgid "Left tooltip"
msgstr "Ayuda emergente a la izquierda"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Tarifa anterior"
@@ -20094,7 +20116,7 @@ msgstr "Marcar como leído el primer canal de la bandeja de entrada"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:364
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
msgid "Markdown"
msgstr "Markdown"
@@ -20644,7 +20666,7 @@ msgstr "¿Mencionar este rol?"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/guild/components/modals/GuildNotificationSettingsModal.tsx:136
#: src/features/i18n/utils/CommonMessageDescriptors.ts:648
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
msgid "Mentions"
msgstr "Menciones"
@@ -21158,7 +21180,7 @@ msgid "Missing client_id"
msgstr "Falta client_id"
#. SSO callback page error shown when the SSO callback is missing code or state parameters.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:24
#: src/features/auth/components/pages/SsoCallbackPage.tsx:26
msgid "Missing SSO code. Sign in again."
msgstr "Falta el código de SSO. Inicia sesión de nuevo."
@@ -21317,11 +21339,11 @@ msgstr "Mensual"
msgid "Monthly {monthlyPrice}"
msgstr "Mensual {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "La facturación mensual comienza el <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "La facturación mensual comienza el <0>{pendingChangeDate}</0>. Primer cargo mensual: {pendingInitialPriceLabel}. Renovaciones mensuales futuras: {pendingRecurringPriceLabel}/mes."
@@ -21756,7 +21778,7 @@ msgstr "silenciado"
#. Status label indicating the surface is currently muted.
#: src/features/app/components/layout/sidebar_nav/UseGuildListItemState.ts:23
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:491
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/lib/overlay/OverlayContextMenu.tsx:24
msgid "Muted"
msgstr "Silenciado"
@@ -21779,7 +21801,7 @@ msgstr "Silenciado por los moderadores"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:495
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
msgid "Muted channels"
msgstr "Canales silenciados"
@@ -21992,7 +22014,7 @@ msgid "Narrates only the channel you're viewing. Narration follows you between c
msgstr "Narra solo el canal que estás viendo. La narración te sigue entre canales."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
msgid "Narration"
msgstr "Narración"
@@ -22057,12 +22079,12 @@ msgid "Need an account?"
msgstr "¿Necesitas una cuenta?"
#. Settings search synonym. Proper name of the optional cat sprite that chases the cursor.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
msgid "Neko"
msgstr "Neko"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:63
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:66
msgid "Neko cat that chases your cursor"
msgstr "Gato Neko que persigue tu cursor"
@@ -22247,12 +22269,12 @@ msgid "New password"
msgstr "Nueva contraseña"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Nuevo precio programado para el <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Nuevo precio programado para el <0>{pendingChangeDate}</0>. Las renovaciones serán de {pendingTargetPriceLabel} en adelante."
@@ -23560,6 +23582,8 @@ msgid "Open {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName}
msgstr "Abre {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName} → {macosScreenRecordingPermissionName} y luego permite que {productName} acceda. Si {productName2} ya está habilitado, cierra completamente y reinicia {productName3} para que macOS aplique el permiso."
#. Button label that opens the desktop app. productName is the app name.
#. Button that hands SSO sign-in back to the mobile app. productName is the app name.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:34
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:27
msgid "Open {productName}"
msgstr "Abrir {productName}"
@@ -24945,7 +24969,7 @@ msgstr "Fija este mensaje en el canal para que todos lo vean."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Voice stats field label (mobile lobby). Shows current latency in ms.
#. Voice stats field label (mobile voice lobby). Shows current latency in ms.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:184
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/voice/components/bottomsheets/DirectCallLobbyBottomSheet.tsx:118
#: src/features/voice/components/bottomsheets/VoiceLobbyBottomSheet.tsx:86
msgid "Ping"
@@ -25165,7 +25189,7 @@ msgid "Popped out"
msgstr "En ventana separada"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:204
msgid "Popup"
msgstr "Ventana emergente"
@@ -26128,7 +26152,7 @@ msgstr "Reacciones"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Reactivar"
@@ -26139,7 +26163,7 @@ msgid "Reactivate subscription"
msgstr "Reactivar suscripción"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
msgid "Read aloud"
msgstr "Leer en voz alta"
@@ -26156,7 +26180,7 @@ msgstr "Leer historial de mensajes"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:177
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
msgid "Read messages"
msgstr "Leer mensajes"
@@ -26351,8 +26375,8 @@ msgstr "Canjear para ti"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Canjear código de regalo"
@@ -26630,7 +26654,7 @@ msgstr "Recordar tamaño y posición de la ventana"
#: src/features/user/components/modals/tabs/chat_settings_tab/SearchEnginesTab.tsx:26
#: src/features/user/components/modals/tabs/LinkedAccountsTab.tsx:55
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:178
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:200
#: src/features/webhook/components/WebhookListItem.tsx:277
msgid "Remove"
msgstr "Eliminar"
@@ -27123,7 +27147,7 @@ msgstr "Umbral de renovación (días)"
msgid "Renew window (days)"
msgstr "Ventana de renovación (días)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Se renueva el <0>{renewalDate}.</0>"
@@ -27321,7 +27345,7 @@ msgid "Require a passkey as your second factor"
msgstr "Requerir una llave de acceso como segundo factor"
#. Short label for an advanced voice-channel navigation preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:17
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:20
msgid "Require double-click to join voice channels"
msgstr "Requerir doble clic para unirse a canales de voz"
@@ -27872,8 +27896,8 @@ msgstr "Restaurar ventana"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Volver a suscribirte"
@@ -29578,7 +29602,7 @@ msgid "Sending malware or dangerous links"
msgstr "Enviar malware o enlaces peligrosos"
#. Short label under a destination row in the forward modal, shown when the community has messaging disabled.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:54
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:55
msgid "Sending messages is disabled in this community"
msgstr "No se pueden enviar mensajes en esta comunidad"
@@ -30120,7 +30144,7 @@ msgstr "Atajo"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:55
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:58
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:370
msgid "Shortcut badges"
msgstr "Insignias de atajos"
@@ -30280,7 +30304,9 @@ msgid "Show delete button"
msgstr "Mostrar botón para eliminar"
#. Short label for an advanced media button preference.
#. Toggle label and settings search entry for showing the download app button in the sidebar.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:76
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
msgid "Show download button"
msgstr "Mostrar botón de descarga"
@@ -30322,7 +30348,7 @@ msgid "Show favorite button"
msgstr "Mostrar botón de favoritos"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:87
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:90
msgid "Show favorites throughout the app"
msgstr "Mostrar favoritos en toda la aplicación"
@@ -30350,6 +30376,11 @@ msgstr "Mostrar indicador de GIF"
msgid "Show GIFs button"
msgstr "Mostrar botón de GIF"
#. Toggle label and settings search entry for showing the help center button in the sidebar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
msgid "Show help center button"
msgstr "Mostrar botón del centro de ayuda"
#. Switch label in the community-folder settings modal. When on, the folder icon is shown in the sidebar while the folder is collapsed.
#: src/features/guild/components/modals/GuildFolderSettingsModal.tsx:77
msgid "Show icon when collapsed"
@@ -30565,7 +30596,7 @@ msgid "Show stickers in expression autocomplete"
msgstr "Mostrar stickers en el autocompletado de expresiones"
#. Description for a visual accessibility setting that mutes the color of text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:110
msgid "Show strikethrough Markdown text in a slightly muted color."
msgstr "Mostrar el texto tachado de Markdown en un color ligeramente atenuado."
@@ -31008,7 +31039,7 @@ msgid "Slowmode"
msgstr "Modo lento"
#. Short label under a destination row in the forward modal while slowmode blocks sending. Preserve {remaining}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:73
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:74
msgid "Slowmode · wait {remaining}"
msgstr "Modo lento · espera {remaining}"
@@ -31559,7 +31590,7 @@ msgstr "Espectadores - {count}"
#. Native macOS Edit submenu title for text-to-speech actions.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/platform/utils/DesktopLocaleBridge.ts:85
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
msgid "Speech"
msgstr "Voz"
@@ -31670,12 +31701,12 @@ msgstr "Botones de icono cuadrados"
msgid "SSO is required to access this workspace."
msgstr "Se requiere SSO para acceder a este espacio de trabajo."
#: src/features/auth/components/pages/SsoCallbackPage.tsx:105
#: src/features/auth/components/pages/SsoCallbackPage.tsx:139
msgid "SSO sign-in failed"
msgstr "Error al iniciar sesión con SSO"
#. SSO callback page error shown when the SSO sign-in timed out before the callback arrived.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:20
#: src/features/auth/components/pages/SsoCallbackPage.tsx:22
msgid "SSO sign-in timed out. Try again."
msgstr "Se agotó el tiempo de espera del inicio de sesión único (SSO). Intenta de nuevo."
@@ -31714,7 +31745,7 @@ msgid "Star animation"
msgstr "Animación de estrella"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:83
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:86
msgid "Starred channels"
msgstr "Canales favoritos"
@@ -31791,7 +31822,7 @@ msgstr "Volver a empezar"
msgid "Start recording"
msgstr "Iniciar grabación"
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:592
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:582
msgid "Start searches with <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> to narrow down results."
msgstr "Comienza las búsquedas con <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> para reducir los resultados."
@@ -31831,7 +31862,7 @@ msgid "Startup"
msgstr "Inicio"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:75
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:78
msgid "Static Neko"
msgstr "Neko estático"
@@ -32038,7 +32069,7 @@ msgid "Still indexing — check back in a moment"
msgstr "Aún indexando; vuelve a intentarlo en un momento"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:71
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:74
msgid "Still Neko"
msgstr "Neko inmóvil"
@@ -32067,7 +32098,7 @@ msgid "Stop mic test"
msgstr "Detener prueba del micrófono"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:70
msgid "Stop Neko from chasing your cursor while keeping it draggable and interactive."
msgstr "Evita que Neko persiga tu cursor, pero permite seguir arrastrándolo e interactuando con él."
@@ -32259,14 +32290,14 @@ msgid "Streaming privacy on"
msgstr "Privacidad de la transmisión activada"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:111
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
msgid "Strike through"
msgstr "Tachado"
#. Selection formatting toolbar button.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/lexical/composer/SelectionFormattingToolbar.tsx:72
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:107
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
msgid "Strikethrough"
msgstr "Tachado"
@@ -32490,7 +32521,7 @@ msgid "Switch price"
msgstr "Cambiar precio"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Cambiar a {listPriceNewLabel}"
@@ -32515,7 +32546,7 @@ msgstr "Cambiar a entrada directa"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Cambiar a mensual"
@@ -32584,7 +32615,7 @@ msgstr "Cambiar a dos columnas"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Cambiar a anual"
@@ -33074,7 +33105,7 @@ msgstr "Envíanos un mensaje de texto desde tu teléfono"
#. Feature label / section heading for the text-to-speech feature.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:419
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
msgid "Text-to-speech"
msgstr "Síntesis de voz"
@@ -34133,7 +34164,7 @@ msgid "This member isn't connected to voice anymore."
msgstr "Este miembro ya no está conectado al chat de voz."
#. Forward dialog error shown when the forwarded message contains age-restricted media and the target channel is not age-restricted.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:68
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:69
msgid "This message can only be forwarded to age-restricted channels"
msgstr "Este mensaje solo se puede reenviar a canales con restricción de edad"
@@ -34766,7 +34797,7 @@ msgid "Toolbar"
msgstr "Barra de herramientas"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:51
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:54
msgid "Tooltip shortcuts"
msgstr "Atajos en las ayudas emergentes"
@@ -35080,7 +35111,7 @@ msgid "Try sending your message again."
msgstr "Intenta enviar tu mensaje de nuevo."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
msgid "TTS"
msgstr "TTS"
@@ -35277,7 +35308,7 @@ msgstr "24 horas"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:39
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:42
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:406
msgid "Two clicks"
msgstr "Dos clics"
@@ -35834,7 +35865,7 @@ msgstr "Desbloquea los emojis personalizados en los MD con {premiumProductName}"
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Desbloquea la pantalla compartida en HD con {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Desbloquea límites más altos y funciones exclusivas mientras apoyas una plataforma de comunicación independiente."
@@ -36044,7 +36075,7 @@ msgstr "no leído"
#. Tab label in the inbox popout filtering to channels with unread messages.
#: src/features/messaging/components/popouts/InboxPopout.tsx:30
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
msgid "Unread"
msgstr "No leídos"
@@ -37866,7 +37897,7 @@ msgstr "Indicadores visuales que muestran el estado del usuario, representados c
#: src/features/app/components/layout/MobileBottomNav.tsx:123
#: src/features/channel/utils/ChannelUtils.tsx:31
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:17
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
msgid "Voice"
msgstr "Voz"
@@ -37961,7 +37992,7 @@ msgstr "Canal de voz"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:23
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:26
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:402
msgid "Voice channel confirmation"
msgstr "Confirmación de canal de voz"
@@ -37972,7 +38003,7 @@ msgid "Voice channel full"
msgstr "Canal de voz lleno"
#. Settings search entry label. Names the settings search entry in the settings UI.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:19
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:22
msgid "Voice channel join behavior"
msgstr "Comportamiento al unirse a canales de voz"
@@ -38099,7 +38130,7 @@ msgstr "Anulada"
#: src/features/i18n/utils/CommonMessageDescriptors.ts:378
#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:181
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:183
msgid "Volume"
msgstr "Volumen"
@@ -38984,15 +39015,15 @@ msgstr "Anual {yearlyPrice}"
msgid "Yearly gift"
msgstr "Regalo de un año"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Cambio a facturación anual programado para el <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Cambio a facturación anual programado para el <0>{pendingChangeDate}</0>. Primer cargo anual: {pendingInitialPriceLabel} después de aplicar un crédito de {pendingCreditPriceLabel}. Futuras renovaciones anuales: {pendingRecurringPriceLabel}/año."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Cambio a facturación anual programado para el <0>{pendingChangeDate}</0>. Primer cargo anual: {pendingInitialPriceLabel}. Futuras renovaciones anuales: {pendingRecurringPriceLabel}/año."
@@ -39462,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Acabas de presionar Tab. El modo de teclado está activado para que puedas navegar por {productName} sin mouse."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Conservarás tus beneficios hasta la próxima fecha de renovación y luego tendrás un período de gracia de 3 días para volver a suscribirte y mantener tu historial de suscriptor."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Conservarás tus beneficios hasta la próxima fecha de renovación. Reactiva tu suscripción antes de esa fecha para mantener tu historial de suscriptor."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Perderás todos los beneficios de {PREMIUM_PRODUCT_NAME} inmediatamente y tu historial de suscripción se restablecerá. Esto no se puede deshacer."
@@ -39508,12 +39539,12 @@ msgid "You need access to your current email to change it from here. Use phone v
msgstr "Necesitas acceso a tu correo electrónico actual para cambiarlo desde aquí. Usa la verificación por teléfono si está disponible o contacta a soporte."
#. Forward dialog error shown when the forwarded message has attachments and the user lacks Attach Files in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:63
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:64
msgid "You need the \"{attachFilesPermissionLabel}\" permission to attach files in this channel"
msgstr "Necesitas el permiso \"{attachFilesPermissionLabel}\" para adjuntar archivos en este canal"
#. Forward dialog error shown when the forwarded message contains embeds and the user lacks Embed Links in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:58
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:59
msgid "You need the \"{embedLinksPermissionLabel}\" permission to embed links in this channel"
msgstr "Necesitas el permiso \"{embedLinksPermissionLabel}\" para incrustar enlaces en este canal"
@@ -40200,6 +40231,11 @@ msgstr "tu región"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Tu registro necesita una verificación antispam adicional antes de que puedas continuar."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Tu pago de renovación falló, pero los <0/> siguen activos hasta el <1>{graceDate}</1>. Actualiza tu método de pago antes de esa fecha para conservar tu suscripción."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40221,7 +40257,7 @@ msgstr "Tu transmisión sigue activa"
msgid "Your subscription can't move to the new price right now."
msgstr "Tu suscripción no puede cambiarse al nuevo precio en este momento."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Tu suscripción finalizó, pero los <0/> siguen activos hasta el <1>{graceDate}</1>. Vuelve a suscribirte antes de esa fecha para conservar tu historial de suscriptor."
@@ -40250,7 +40286,7 @@ msgstr "Tu suscripción se cambió a facturación mensual."
msgid "Your subscription has been switched to yearly billing."
msgstr "Tu suscripción se cambió a facturación anual."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Tu suscripción está activa, pero los beneficios están pausados temporalmente."
@@ -40270,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Tu suscripción cambia al nuevo precio el {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Tu suscripción sigue programada para finalizar el <0>{cancelDate}</0>. El precio actual es {listPriceNewLabel}. Si la reactivas, podrás cambiar a ese precio desde aquí."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Hay una actualización de escritorio para Linux disponible. Elige el formato del paquete para este sistema y {productName} lo guardará localmente."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Hay un precio más bajo disponible. El cambio entrará en vigor el <0>{listPriceEffectiveDate}</0> y no cambia nada más."
@@ -2639,7 +2639,7 @@ msgstr "Accede a tu información básica de perfil (nombre de usuario, avatar, e
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. User settings tab for accessibility preferences (visual, motion, screen reader, etc.).
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:14
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/SettingsConstants.tsx:61
msgid "Accessibility"
msgstr "Accesibilidad"
@@ -3487,19 +3487,19 @@ msgstr "Los controles de alineación solo están disponibles en pantallas más a
msgid "All"
msgstr "Todo"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Todas las <0/> por <1>{effectiveMonthlyPrice}/mes</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Todas las <0/> por <1>{effectiveYearlyPrice}/año</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Tu suscripción incluye todas las <0/>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Todas las <0/>, para siempre. Sin facturación ni renovaciones."
@@ -4706,7 +4706,7 @@ msgstr "Archivos adjuntos"
#. Generic tab / section / category label for audio content or settings.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:255
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:179
msgid "Audio"
msgstr "Audio"
@@ -6210,7 +6210,7 @@ msgid "California"
msgstr "California"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
msgid "Call"
msgstr "Llamada"
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Cancelar importación"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Cancelar cambio de precio"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Cancelar solicitud"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Cancelar cambio programado"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Cancelar suscripción"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "¿Cancelar suscripción?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Cancela el cambio programado para pasar al precio actual en su lugar."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Cancelar subida"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Cancelar cambio al plan anual"
@@ -6530,7 +6530,7 @@ msgstr "Cancelando"
msgid "Cancellation"
msgstr "Cancelación de eco"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Se cancela el <0>{cancelDate}</0>. Las <1/> seguirán activas hasta entonces."
@@ -7088,7 +7088,7 @@ msgid "Channel"
msgstr "Canal"
#. Fallback name for an unnamed channel in the forward modal destination list. Preserve {id}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:78
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:79
msgid "Channel {id}"
msgstr "Canal {id}"
@@ -7317,7 +7317,7 @@ msgid "Chat font size"
msgstr "Tamaño de fuente del chat"
#. Settings search synonym. Refers to the message composer area.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
msgid "chat input"
msgstr "entrada de chat"
@@ -8726,7 +8726,7 @@ msgid "Community updated"
msgstr "Comunidad actualizada"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:35
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:38
msgid "Community voice"
msgstr "Voz de la comunidad"
@@ -8789,12 +8789,13 @@ msgstr "Completa la verificación requerida para seguir usando {productName}."
msgid "Completely hide your {premiumProductName} badge from other users"
msgstr "Ocultar completamente tu insignia de {premiumProductName} a otros usuarios"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:134
#: src/features/auth/components/pages/SsoCallbackPage.tsx:118
#: src/features/auth/components/pages/SsoCallbackPage.tsx:168
#: src/features/auth/flow/HandoffApprovalFlow.tsx:218
msgid "Completing sign-in…"
msgstr "Completando el inicio de sesión…"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:138
#: src/features/auth/components/pages/SsoCallbackPage.tsx:172
msgid "Completing your sign-in…"
msgstr "Completando tu inicio de sesión…"
@@ -8912,8 +8913,8 @@ msgstr "Confirmar"
#. Settings search entry label. Names the settings search entry in the settings UI.
#. Short label for an advanced voice-channel safety preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:21
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:15
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:24
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:18
msgid "Confirm before joining voice channels"
msgstr "Confirmar antes de unirte a canales de voz"
@@ -8952,7 +8953,7 @@ msgstr "Confirmar contraseña"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:27
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:30
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:398
msgid "Confirm voice join"
msgstr "Confirmar conexión a canales de voz"
@@ -8963,7 +8964,7 @@ msgid "Confirmation"
msgstr "Confirmación"
#. Settings search entry description. One-line summary of what the settings search entry controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:43
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:46
msgid "Confirmation or double-click for community voice joins"
msgstr "Confirmación o doble clic para unirse a los canales de voz de la comunidad."
@@ -9200,7 +9201,7 @@ msgstr "Controles de seguridad del contenido"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/ui/action_menu/ContextMenu.tsx:23
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:225
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
msgid "Context menu"
msgstr "Menú contextual"
@@ -10871,7 +10872,7 @@ msgstr "Personalizar…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Portal de clientes"
@@ -11341,7 +11342,7 @@ msgstr "Delaware"
#: src/features/user/components/modals/tabs/component_gallery_tab/ComponentGalleryTabButtonsTab.tsx:290
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:238
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:174
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
msgid "Delete"
msgstr "Eliminar"
@@ -11626,7 +11627,7 @@ msgid "Deleted {duration} of the member's recent message history"
msgstr "Se eliminó el historial de mensajes del miembro de hasta {duration} de antigüedad"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
msgid "Deleted text"
msgstr "Texto eliminado"
@@ -12028,7 +12029,7 @@ msgid "Different sizes & member counts"
msgstr "Diferentes tamaños y número de miembros"
#. Toggle label and settings search entry for slightly muting text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:106
msgid "Dim strikethrough text"
msgstr "Atenuar texto tachado"
@@ -12043,7 +12044,7 @@ msgstr "Entrada directa"
#: src/features/channel/components/bottomsheets/channel_details_bottom_sheet/ChannelDetailsBottomSheetShared.ts:14
#: src/features/channel/components/channel_header_components/developer_tools/MockingMenu.tsx:398
#: src/features/i18n/utils/CommonMessageDescriptors.ts:567
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
msgid "Direct message"
msgstr "Mensaje directo"
@@ -12480,7 +12481,7 @@ msgid "District of Columbia"
msgstr "Distrito de Columbia"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:180
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
msgid "DM"
msgstr "MD"
@@ -12735,6 +12736,16 @@ msgstr "Descargar {productName}"
msgid "Download <0>fluxer-verification</0> and place it in your <1>.well-known</1> folder so we can validate the domain."
msgstr "Descarga <0>fluxer-verification</0> y colócalo en tu carpeta <1>.well-known</1> para que podamos validar el dominio."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:98
msgid "Download app"
msgstr "Descargar app"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:106
msgid "Download app button in the sidebar"
msgstr "Descargar la app"
#. Media context menu action that downloads an audio attachment.
#: src/features/ui/action_menu/items/MediaMenuData.tsx:122
msgid "Download audio"
@@ -13433,7 +13444,7 @@ msgstr "Contenido incrustado restaurado"
#: src/features/app/config/AuditLogConstants.ts:167
#: src/features/emoji/components/emojis/EmojiListItem.tsx:337
#: src/features/theme_studio/sections/TokenGroups.ts:114
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
msgid "Emoji"
msgstr "Emoji"
@@ -13866,15 +13877,15 @@ msgid "End date"
msgstr "Fecha de finalización"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Finalizar período de gracia ahora"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Finalizar período de gracia"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "¿Finalizar el período de gracia ahora?"
@@ -14681,7 +14692,7 @@ msgid "Failed to clear trusted domains."
msgstr "No se pudieron borrar los dominios de confianza."
#. Short label in the authentication SSO callback page. Keep the tone plain and specific.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:28
#: src/features/auth/components/pages/SsoCallbackPage.tsx:30
msgid "Failed to complete SSO sign-in"
msgstr "No se pudo completar el inicio de sesión único (SSO)"
@@ -15027,7 +15038,7 @@ msgid "Favorite channel"
msgstr "Marcar canal como favorito"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:79
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:82
msgid "Favorite channels"
msgstr "Canales favoritos"
@@ -15800,7 +15811,7 @@ msgstr "Bot amistoso"
#: src/features/connection/components/modals/EditConnectionModal.tsx:86
#: src/features/search/utils/QuickSwitcherModalUtils.tsx:50
#: src/features/user/components/modals/tabs/my_profile_tab/TimezoneProfileSettings.tsx:63
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
msgid "Friends"
msgstr "Amigos"
@@ -16145,7 +16156,7 @@ msgstr "Descarga la nueva app {productName}"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Type label for GIF media.
#: src/features/expressions/utils/FavoriteMemeUtils.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
msgid "GIF"
msgstr "GIF"
@@ -16336,7 +16347,7 @@ msgstr "Regalo: caduca pronto"
msgid "Gift: grace period (still have access)"
msgstr "Regalo: período de gracia (aún tienes acceso)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Las <0/> de regalo están activas hasta el <1>{giftEndDate}</1>. No se renuevan automáticamente. Canjea más códigos de regalo para prolongarlas."
@@ -16549,7 +16560,7 @@ msgid "Graphics"
msgstr "Gráficos"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
msgid "Gray text"
msgstr "Texto gris"
@@ -16815,7 +16826,7 @@ msgid "Hate speech"
msgstr "Discurso de odio"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "¿Tienes un código de regalo? Canjéalo para desbloquear {PREMIUM_PRODUCT_NAME}."
@@ -16896,11 +16907,21 @@ msgstr "¡Hola, {username}! Nos alegramos de que estés aquí."
msgid "Help"
msgstr "Ayuda"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:94
msgid "Help button"
msgstr "Botón de ayuda"
#. Short label in the sidebar navigation help button.
#: src/features/app/components/layout/sidebar_nav/HelpButton.tsx:27
msgid "Help center"
msgstr "Centro de ayuda"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:102
msgid "Help center button in the sidebar"
msgstr "Centro de ayuda"
#: src/features/user/components/modals/tabs/LanguageTab.tsx:348
msgid "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
msgstr "Ayuda a traducir {PRODUCT_NAME} a tu idioma en <0>{I18N_WEBLATE_DOMAIN}</0>."
@@ -17035,7 +17056,7 @@ msgid "Hide join messages"
msgstr "Ocultar avisos de incorporación"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:47
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:50
msgid "Hide keyboard hints"
msgstr "Ocultar sugerencias del teclado"
@@ -18721,7 +18742,7 @@ msgstr "Unirse a la videollamada"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/profile/VoiceActivityCard.tsx:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:31
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:34
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:454
msgid "Join voice"
msgstr "Unirse a la llamada de voz"
@@ -18764,6 +18785,7 @@ msgstr "Saltar entre canales no leídos"
msgid "Jump between unread channels with mentions"
msgstr "Saltar entre canales no leídos con menciones"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:121
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:75
msgid "Jump straight to the app to continue."
msgstr "Ve directamente a la aplicación para continuar."
@@ -18904,7 +18926,7 @@ msgstr "Conservar archivos adjuntos al borrar el texto de una edición"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Mantén los niveles gratuito y premium. Puedes personalizar los niveles, vender premium a través de Stripe o entregar códigos de regalo más tarde desde el panel de administración."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Mantener período de gracia"
@@ -18918,7 +18940,7 @@ msgstr "Mantener a Neko quieto"
msgid "Keep running"
msgstr "Seguir ejecutando"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Mantener suscripción"
@@ -18980,7 +19002,7 @@ msgid "Keyboard mode"
msgstr "Modo teclado"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:59
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:62
msgid "Keyboard shortcut hints in tooltips"
msgstr "Indicaciones de atajos de teclado en la ayuda emergente"
@@ -19275,8 +19297,8 @@ msgstr "Botón izquierdo del ratón"
msgid "Left tooltip"
msgstr "Ayuda emergente a la izquierda"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Tarifa antigua"
@@ -20094,7 +20116,7 @@ msgstr "Marcar como leído el primer canal de la bandeja de entrada"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:364
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
msgid "Markdown"
msgstr "Markdown"
@@ -20644,7 +20666,7 @@ msgstr "¿Mencionar este rol?"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/guild/components/modals/GuildNotificationSettingsModal.tsx:136
#: src/features/i18n/utils/CommonMessageDescriptors.ts:648
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
msgid "Mentions"
msgstr "Menciones"
@@ -21158,7 +21180,7 @@ msgid "Missing client_id"
msgstr "Falta client_id"
#. SSO callback page error shown when the SSO callback is missing code or state parameters.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:24
#: src/features/auth/components/pages/SsoCallbackPage.tsx:26
msgid "Missing SSO code. Sign in again."
msgstr "Falta el código de inicio de sesión único. Inicia sesión de nuevo."
@@ -21317,11 +21339,11 @@ msgstr "Mensual"
msgid "Monthly {monthlyPrice}"
msgstr "Mensual {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "La facturación mensual comienza el <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "La facturación mensual comienza el <0>{pendingChangeDate}</0>. Primer cargo mensual: {pendingInitialPriceLabel}. Futuras renovaciones mensuales: {pendingRecurringPriceLabel}/mes."
@@ -21756,7 +21778,7 @@ msgstr "silenciado"
#. Status label indicating the surface is currently muted.
#: src/features/app/components/layout/sidebar_nav/UseGuildListItemState.ts:23
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:491
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/lib/overlay/OverlayContextMenu.tsx:24
msgid "Muted"
msgstr "Silenciado"
@@ -21779,7 +21801,7 @@ msgstr "Silenciado por los moderadores"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:495
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
msgid "Muted channels"
msgstr "Canales silenciados"
@@ -21992,7 +22014,7 @@ msgid "Narrates only the channel you're viewing. Narration follows you between c
msgstr "Narra solo el canal que estás viendo. La narración te sigue entre canales."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
msgid "Narration"
msgstr "Narración"
@@ -22057,12 +22079,12 @@ msgid "Need an account?"
msgstr "¿Necesitas una cuenta?"
#. Settings search synonym. Proper name of the optional cat sprite that chases the cursor.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
msgid "Neko"
msgstr "Neko"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:63
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:66
msgid "Neko cat that chases your cursor"
msgstr "Gato Neko que persigue tu cursor"
@@ -22247,12 +22269,12 @@ msgid "New password"
msgstr "Nueva contraseña"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Nuevo precio programado para el <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Nuevo precio programado para el <0>{pendingChangeDate}</0>. Las renovaciones serán de {pendingTargetPriceLabel} a partir de entonces."
@@ -23560,6 +23582,8 @@ msgid "Open {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName}
msgstr "Abre {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName} → {macosScreenRecordingPermissionName} y permite que {productName} acceda a la función. Si {productName2} ya está habilitada, cierra completamente y reinicia {productName3} para que macOS aplique el permiso."
#. Button label that opens the desktop app. productName is the app name.
#. Button that hands SSO sign-in back to the mobile app. productName is the app name.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:34
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:27
msgid "Open {productName}"
msgstr "Abrir {productName}"
@@ -24945,7 +24969,7 @@ msgstr "Fija este mensaje en el canal para que todos lo vean."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Voice stats field label (mobile lobby). Shows current latency in ms.
#. Voice stats field label (mobile voice lobby). Shows current latency in ms.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:184
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/voice/components/bottomsheets/DirectCallLobbyBottomSheet.tsx:118
#: src/features/voice/components/bottomsheets/VoiceLobbyBottomSheet.tsx:86
msgid "Ping"
@@ -25165,7 +25189,7 @@ msgid "Popped out"
msgstr "En ventana emergente"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:204
msgid "Popup"
msgstr "Ventana emergente"
@@ -26128,7 +26152,7 @@ msgstr "Reacciones"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Reactivar"
@@ -26139,7 +26163,7 @@ msgid "Reactivate subscription"
msgstr "Reactivar suscripción"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
msgid "Read aloud"
msgstr "Leer en voz alta"
@@ -26156,7 +26180,7 @@ msgstr "Leer historial de mensajes"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:177
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
msgid "Read messages"
msgstr "Leer mensajes"
@@ -26351,8 +26375,8 @@ msgstr "Canjear para mí"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Canjear código de regalo"
@@ -26630,7 +26654,7 @@ msgstr "Recordar tamaño y posición de la ventana"
#: src/features/user/components/modals/tabs/chat_settings_tab/SearchEnginesTab.tsx:26
#: src/features/user/components/modals/tabs/LinkedAccountsTab.tsx:55
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:178
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:200
#: src/features/webhook/components/WebhookListItem.tsx:277
msgid "Remove"
msgstr "Eliminar"
@@ -27123,7 +27147,7 @@ msgstr "Umbral de renovación (días)"
msgid "Renew window (days)"
msgstr "Ventana de renovación (días)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Se renueva el <0>{renewalDate}.</0>"
@@ -27321,7 +27345,7 @@ msgid "Require a passkey as your second factor"
msgstr "Requerir una clave de acceso como segundo factor"
#. Short label for an advanced voice-channel navigation preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:17
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:20
msgid "Require double-click to join voice channels"
msgstr "Requerir doble clic para unirse a canales de voz"
@@ -27872,8 +27896,8 @@ msgstr "Restaurar ventana"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Volver a suscribirse"
@@ -29578,7 +29602,7 @@ msgid "Sending malware or dangerous links"
msgstr "Enviar malware o enlaces peligrosos"
#. Short label under a destination row in the forward modal, shown when the community has messaging disabled.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:54
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:55
msgid "Sending messages is disabled in this community"
msgstr "El envío de mensajes está deshabilitado en esta comunidad"
@@ -30120,7 +30144,7 @@ msgstr "Atajo"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:55
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:58
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:370
msgid "Shortcut badges"
msgstr "Insignias de atajos"
@@ -30280,7 +30304,9 @@ msgid "Show delete button"
msgstr "Mostrar botón de eliminar"
#. Short label for an advanced media button preference.
#. Toggle label and settings search entry for showing the download app button in the sidebar.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:76
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
msgid "Show download button"
msgstr "Mostrar botón de descarga"
@@ -30322,7 +30348,7 @@ msgid "Show favorite button"
msgstr "Mostrar botón de favoritos"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:87
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:90
msgid "Show favorites throughout the app"
msgstr "Mostrar favoritos en toda la aplicación"
@@ -30350,6 +30376,11 @@ msgstr "Mostrar indicador de GIF"
msgid "Show GIFs button"
msgstr "Mostrar botón de GIF"
#. Toggle label and settings search entry for showing the help center button in the sidebar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
msgid "Show help center button"
msgstr "Mostrar botón del centro de ayuda"
#. Switch label in the community-folder settings modal. When on, the folder icon is shown in the sidebar while the folder is collapsed.
#: src/features/guild/components/modals/GuildFolderSettingsModal.tsx:77
msgid "Show icon when collapsed"
@@ -30565,7 +30596,7 @@ msgid "Show stickers in expression autocomplete"
msgstr "Mostrar pegatinas en el autocompletado de expresiones"
#. Description for a visual accessibility setting that mutes the color of text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:110
msgid "Show strikethrough Markdown text in a slightly muted color."
msgstr "Mostrar el texto tachado de Markdown en un color ligeramente atenuado."
@@ -31008,7 +31039,7 @@ msgid "Slowmode"
msgstr "Modo lento"
#. Short label under a destination row in the forward modal while slowmode blocks sending. Preserve {remaining}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:73
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:74
msgid "Slowmode · wait {remaining}"
msgstr "Modo lento · espera {remaining}"
@@ -31559,7 +31590,7 @@ msgstr "Espectadores - {count}"
#. Native macOS Edit submenu title for text-to-speech actions.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/platform/utils/DesktopLocaleBridge.ts:85
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
msgid "Speech"
msgstr "Voz"
@@ -31670,12 +31701,12 @@ msgstr "Botones de icono cuadrados"
msgid "SSO is required to access this workspace."
msgstr "Se requiere SSO para acceder a este espacio de trabajo."
#: src/features/auth/components/pages/SsoCallbackPage.tsx:105
#: src/features/auth/components/pages/SsoCallbackPage.tsx:139
msgid "SSO sign-in failed"
msgstr "Error al iniciar sesión con SSO"
#. SSO callback page error shown when the SSO sign-in timed out before the callback arrived.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:20
#: src/features/auth/components/pages/SsoCallbackPage.tsx:22
msgid "SSO sign-in timed out. Try again."
msgstr "Se agotó el tiempo de espera del inicio de sesión único (SSO). Inténtalo de nuevo."
@@ -31714,7 +31745,7 @@ msgid "Star animation"
msgstr "Animación de estrellas"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:83
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:86
msgid "Starred channels"
msgstr "Canales favoritos"
@@ -31791,7 +31822,7 @@ msgstr "Empezar de nuevo"
msgid "Start recording"
msgstr "Iniciar grabación"
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:592
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:582
msgid "Start searches with <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> to narrow down results."
msgstr "Comienza las búsquedas con <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> para reducir los resultados."
@@ -31831,7 +31862,7 @@ msgid "Startup"
msgstr "Inicio"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:75
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:78
msgid "Static Neko"
msgstr "Neko estático"
@@ -32038,7 +32069,7 @@ msgid "Still indexing — check back in a moment"
msgstr "Aún indexando. Vuelve a intentarlo en un momento"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:71
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:74
msgid "Still Neko"
msgstr "Neko inmóvil"
@@ -32067,7 +32098,7 @@ msgid "Stop mic test"
msgstr "Detener prueba del micrófono"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:70
msgid "Stop Neko from chasing your cursor while keeping it draggable and interactive."
msgstr "Evita que Neko persiga tu cursor, pero permite seguir arrastrándolo e interactuando con él."
@@ -32259,14 +32290,14 @@ msgid "Streaming privacy on"
msgstr "Privacidad de la transmisión activada"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:111
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
msgid "Strike through"
msgstr "Tachado"
#. Selection formatting toolbar button.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/lexical/composer/SelectionFormattingToolbar.tsx:72
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:107
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
msgid "Strikethrough"
msgstr "Tachado"
@@ -32490,7 +32521,7 @@ msgid "Switch price"
msgstr "Cambiar a este precio"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Cambiar a {listPriceNewLabel}"
@@ -32515,7 +32546,7 @@ msgstr "Cambiar a entrada directa"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Cambiar a mensual"
@@ -32584,7 +32615,7 @@ msgstr "Cambiar a dos columnas"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Cambiar a anual"
@@ -33074,7 +33105,7 @@ msgstr "Envíanos un mensaje desde tu teléfono"
#. Feature label / section heading for the text-to-speech feature.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:419
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
msgid "Text-to-speech"
msgstr "Síntesis de voz"
@@ -34133,7 +34164,7 @@ msgid "This member isn't connected to voice anymore."
msgstr "Este miembro ya no está conectado al chat de voz."
#. Forward dialog error shown when the forwarded message contains age-restricted media and the target channel is not age-restricted.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:68
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:69
msgid "This message can only be forwarded to age-restricted channels"
msgstr "Este mensaje solo se puede reenviar a canales con restricción de edad"
@@ -34766,7 +34797,7 @@ msgid "Toolbar"
msgstr "Barra de herramientas"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:51
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:54
msgid "Tooltip shortcuts"
msgstr "Atajos en las ayudas emergentes"
@@ -35080,7 +35111,7 @@ msgid "Try sending your message again."
msgstr "Intenta enviar tu mensaje de nuevo."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
msgid "TTS"
msgstr "TTS"
@@ -35277,7 +35308,7 @@ msgstr "Veinticuatro horas"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:39
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:42
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:406
msgid "Two clicks"
msgstr "Dos clics"
@@ -35834,7 +35865,7 @@ msgstr "Desbloquea los emojis personalizados en los MD con {premiumProductName}"
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Desbloquea la pantalla compartida en HD con {premiumProductName}"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Desbloquea límites más altos y funciones exclusivas mientras apoyas una plataforma de comunicación independiente."
@@ -36044,7 +36075,7 @@ msgstr "no leído"
#. Tab label in the inbox popout filtering to channels with unread messages.
#: src/features/messaging/components/popouts/InboxPopout.tsx:30
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
msgid "Unread"
msgstr "No leídos"
@@ -37866,7 +37897,7 @@ msgstr "Indicadores visuales que muestran el estado del usuario, representados c
#: src/features/app/components/layout/MobileBottomNav.tsx:123
#: src/features/channel/utils/ChannelUtils.tsx:31
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:17
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
msgid "Voice"
msgstr "Voz"
@@ -37961,7 +37992,7 @@ msgstr "Canal de voz"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:23
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:26
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:402
msgid "Voice channel confirmation"
msgstr "Confirmación del canal de voz"
@@ -37972,7 +38003,7 @@ msgid "Voice channel full"
msgstr "Canal de voz lleno"
#. Settings search entry label. Names the settings search entry in the settings UI.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:19
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:22
msgid "Voice channel join behavior"
msgstr "Comportamiento al unirse a un canal de voz"
@@ -38099,7 +38130,7 @@ msgstr "Anulada"
#: src/features/i18n/utils/CommonMessageDescriptors.ts:378
#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:181
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:183
msgid "Volume"
msgstr "Volumen"
@@ -38984,15 +39015,15 @@ msgstr "Anual {yearlyPrice}"
msgid "Yearly gift"
msgstr "Regalo de un año"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Cambio a facturación anual programado para el <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Cambio a facturación anual programado para el <0>{pendingChangeDate}</0>. Primer cargo anual: {pendingInitialPriceLabel} después de aplicar un crédito de {pendingCreditPriceLabel}. Futuras renovaciones anuales: {pendingRecurringPriceLabel}/año."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Cambio a facturación anual programado para el <0>{pendingChangeDate}</0>. Primer cargo anual: {pendingInitialPriceLabel}. Futuras renovaciones anuales: {pendingRecurringPriceLabel}/año."
@@ -39462,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Acabas de pulsar Tab. El modo de teclado está activado para que puedas navegar por {productName} sin ratón."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Conservarás tus ventajas hasta la próxima fecha de renovación y, después, tendrás un periodo de gracia de 3 días para volver a suscribirte y mantener tu historial de suscriptor."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Conservarás tus ventajas hasta la próxima fecha de renovación. Reactiva tu suscripción antes de esa fecha para mantener tu historial de suscriptor."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Perderás todas las ventajas de {PREMIUM_PRODUCT_NAME} inmediatamente y tu historial de suscripción se restablecerá. Esto no se puede deshacer."
@@ -39508,12 +39539,12 @@ msgid "You need access to your current email to change it from here. Use phone v
msgstr "Necesitas acceder a tu correo electrónico actual para cambiarlo desde aquí. Usa la verificación por teléfono si está disponible o contacta con soporte."
#. Forward dialog error shown when the forwarded message has attachments and the user lacks Attach Files in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:63
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:64
msgid "You need the \"{attachFilesPermissionLabel}\" permission to attach files in this channel"
msgstr "Necesitas el permiso \"{attachFilesPermissionLabel}\" para adjuntar archivos en este canal"
#. Forward dialog error shown when the forwarded message contains embeds and the user lacks Embed Links in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:58
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:59
msgid "You need the \"{embedLinksPermissionLabel}\" permission to embed links in this channel"
msgstr "Necesitas el permiso \"{embedLinksPermissionLabel}\" para incrustar enlaces en este canal"
@@ -40200,6 +40231,11 @@ msgstr "tu región"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Tu registro necesita una comprobación antispam adicional antes de que puedas continuar."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "El pago de renovación ha fallado, pero las <0/> siguen activas hasta el <1>{graceDate}</1>. Actualiza tu método de pago antes de esa fecha para mantener tu suscripción."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40221,7 +40257,7 @@ msgstr "Tu transmisión sigue activa"
msgid "Your subscription can't move to the new price right now."
msgstr "Tu suscripción no puede cambiarse al nuevo precio en este momento."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Tu suscripción ha terminado, pero las <0/> siguen activas hasta el <1>{graceDate}</1>. Vuelve a suscribirte antes de esa fecha para mantener tu historial de suscriptor."
@@ -40250,7 +40286,7 @@ msgstr "Tu suscripción se ha cambiado a facturación mensual."
msgid "Your subscription has been switched to yearly billing."
msgstr "Tu suscripción se ha cambiado a facturación anual."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Tu suscripción está activa, pero las ventajas están en pausa temporalmente."
@@ -40270,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Tu suscripción cambiará al nuevo precio el {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Tu suscripción sigue activa hasta el <0>{cancelDate}</0>. El precio actual es de {listPriceNewLabel}. Si la reactivas, podrás cambiar a él desde aquí."
@@ -2471,7 +2471,7 @@ msgid "A Linux desktop update is available. Choose the package format for this s
msgstr "Linux-työpöytäpäivitys on saatavilla. Valitse pakettimuoto tälle järjestelmälle, niin {productName} tallentaa sen paikallisesti."
#. Plutonium subscription card line offering a move to a lower price. {listPriceEffectiveDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:684
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:700
msgid "A lower price is available. Switching takes effect on <0>{listPriceEffectiveDate}</0> and changes nothing else."
msgstr "Saatavilla on edullisempi hinta. Vaihto astuu voimaan <0>{listPriceEffectiveDate}</0>, eikä se muuta mitään muuta."
@@ -2639,7 +2639,7 @@ msgstr "Käyttää profiilisi perustietoja (käyttäjänimi, avatar jne.)"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. User settings tab for accessibility preferences (visual, motion, screen reader, etc.).
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:14
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/SettingsConstants.tsx:61
msgid "Accessibility"
msgstr "Saavutettavuus"
@@ -3487,19 +3487,19 @@ msgstr "Kohdistussäätimet ovat käytettävissä vain leveämmillä näytöill
msgid "All"
msgstr "Kaikki"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:524
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:540
msgid "All <0/> for <1>{effectiveMonthlyPrice}/month</1>."
msgstr "Kaikki <0/> hintaan <1>{effectiveMonthlyPrice}/kuukausi</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:546
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:562
msgid "All <0/> for <1>{effectiveYearlyPrice}/year</1>."
msgstr "Kaikki <0/> hintaan <1>{effectiveYearlyPrice}/vuosi</1>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:567
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:583
msgid "All <0/> included with your subscription."
msgstr "Kaikki <0/> sisältyvät tilaukseesi."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:514
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:530
msgid "All <0/>, forever. No billing, no renewals."
msgstr "Kaikki <0/> ikuisesti. Ei laskutusta, ei uusimisia."
@@ -4706,7 +4706,7 @@ msgstr "Liitteet"
#. Generic tab / section / category label for audio content or settings.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:255
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:179
msgid "Audio"
msgstr "Ääni"
@@ -6210,7 +6210,7 @@ msgid "California"
msgstr "Kalifornia"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
msgid "Call"
msgstr "Puhelu"
@@ -6469,7 +6469,7 @@ msgid "Cancel import"
msgstr "Peruuta tuonti"
#. Billing button that cancels a scheduled move to a lower subscription price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:821
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:837
msgid "Cancel price change"
msgstr "Peruuta hinnanmuutos"
@@ -6484,14 +6484,14 @@ msgid "Cancel request"
msgstr "Peruuta pyyntö"
#. Billing button that cancels a scheduled billing-cycle change.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:829
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:845
msgid "Cancel scheduled switch"
msgstr "Peruuta ajoitettu vaihto"
#. Billing button that starts subscription cancellation.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:844
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:142
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:860
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:141
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:31
msgid "Cancel subscription"
msgstr "Peruuta tilaus"
@@ -6501,7 +6501,7 @@ msgid "Cancel subscription?"
msgstr "Peruuta tilaus?"
#. Plutonium subscription card hint shown to a subscriber who could move to a lower price but has another billing change already scheduled.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:663
msgid "Cancel the scheduled change to move to the current price instead."
msgstr "Peruuta ajoitettu muutos ja siirry sen sijaan nykyiseen hintaan."
@@ -6511,7 +6511,7 @@ msgid "Cancel upload"
msgstr "Peruuta lähetys"
#. Billing button that cancels a scheduled yearly upgrade.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:825
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:841
msgid "Cancel yearly upgrade"
msgstr "Peruuta vaihto vuositilaukseen"
@@ -6530,7 +6530,7 @@ msgstr "Peruutetaan"
msgid "Cancellation"
msgstr "Kaiunvaimennus"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:501
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:517
msgid "Cancels on <0>{cancelDate}</0>. <1/> remain active until then."
msgstr "Peruuntuu <0>{cancelDate}</0>. <1/> pysyvät aktiivisina siihen asti."
@@ -7088,7 +7088,7 @@ msgid "Channel"
msgstr "Kanava"
#. Fallback name for an unnamed channel in the forward modal destination list. Preserve {id}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:78
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:79
msgid "Channel {id}"
msgstr "Kanava {id}"
@@ -7317,7 +7317,7 @@ msgid "Chat font size"
msgstr "Keskustelun fonttikoko"
#. Settings search synonym. Refers to the message composer area.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
msgid "chat input"
msgstr "viestikenttä"
@@ -8726,7 +8726,7 @@ msgid "Community updated"
msgstr "Yhteisö päivitetty"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:35
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:38
msgid "Community voice"
msgstr "Yhteisön ääni"
@@ -8789,12 +8789,13 @@ msgstr "Suorita vaadittu vahvistus, jotta voit jatkaa {productName}-palvelun kä
msgid "Completely hide your {premiumProductName} badge from other users"
msgstr "Piilota {premiumProductName}-merkki kokonaan muilta käyttäjiltä"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:134
#: src/features/auth/components/pages/SsoCallbackPage.tsx:118
#: src/features/auth/components/pages/SsoCallbackPage.tsx:168
#: src/features/auth/flow/HandoffApprovalFlow.tsx:218
msgid "Completing sign-in…"
msgstr "Kirjautuminen viimeistellään…"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:138
#: src/features/auth/components/pages/SsoCallbackPage.tsx:172
msgid "Completing your sign-in…"
msgstr "Kirjautuminen viimeistellään…"
@@ -8912,8 +8913,8 @@ msgstr "Vahvista"
#. Settings search entry label. Names the settings search entry in the settings UI.
#. Short label for an advanced voice-channel safety preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:21
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:15
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:24
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:18
msgid "Confirm before joining voice channels"
msgstr "Vahvista ennen äänikanaville liittymistä"
@@ -8952,7 +8953,7 @@ msgstr "Vahvista salasana"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:27
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:30
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:398
msgid "Confirm voice join"
msgstr "Vahvista äänikanavaan liittyminen"
@@ -8963,7 +8964,7 @@ msgid "Confirmation"
msgstr "Vahvistus"
#. Settings search entry description. One-line summary of what the settings search entry controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:43
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:46
msgid "Confirmation or double-click for community voice joins"
msgstr "Vahvistus tai kaksoisnapsautus yhteisön äänikanaviin liittyessä"
@@ -9200,7 +9201,7 @@ msgstr "Sisällön turvaportit"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/ui/action_menu/ContextMenu.tsx:23
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:225
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
msgid "Context menu"
msgstr "Pikavalikko"
@@ -10871,7 +10872,7 @@ msgstr "Mukautettu…"
#. Billing button that opens the external customer portal.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:750
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:766
#: src/features/user/components/settings_utils/search_index/PlutoniumIndex.ts:39
msgid "Customer portal"
msgstr "Asiakasportaali"
@@ -11341,7 +11342,7 @@ msgstr "Delaware"
#: src/features/user/components/modals/tabs/component_gallery_tab/ComponentGalleryTabButtonsTab.tsx:290
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:238
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:174
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
msgid "Delete"
msgstr "Poista"
@@ -11626,7 +11627,7 @@ msgid "Deleted {duration} of the member's recent message history"
msgstr "Poistettiin jäsenen viimeaikaisesta viestihistoriasta {duration}"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
msgid "Deleted text"
msgstr "Poistettu teksti"
@@ -12028,7 +12029,7 @@ msgid "Different sizes & member counts"
msgstr "Eri kokoja ja jäsenmääriä"
#. Toggle label and settings search entry for slightly muting text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:106
msgid "Dim strikethrough text"
msgstr "Himmennä yliviivattua tekstiä"
@@ -12043,7 +12044,7 @@ msgstr "Suora syöte"
#: src/features/channel/components/bottomsheets/channel_details_bottom_sheet/ChannelDetailsBottomSheetShared.ts:14
#: src/features/channel/components/channel_header_components/developer_tools/MockingMenu.tsx:398
#: src/features/i18n/utils/CommonMessageDescriptors.ts:567
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:94
msgid "Direct message"
msgstr "Yksityisviesti"
@@ -12480,7 +12481,7 @@ msgid "District of Columbia"
msgstr "Columbian liittopiiri"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:180
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:188
msgid "DM"
msgstr "DM"
@@ -12735,6 +12736,16 @@ msgstr "Lataa {productName}"
msgid "Download <0>fluxer-verification</0> and place it in your <1>.well-known</1> folder so we can validate the domain."
msgstr "Lataa <0>fluxer-verification</0> ja siirrä se <1>.well-known</1>-kansioosi, jotta voimme vahvistaa verkkotunnuksen."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:98
msgid "Download app"
msgstr "Lataa sovellus"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:106
msgid "Download app button in the sidebar"
msgstr "Lataa sovellus"
#. Media context menu action that downloads an audio attachment.
#: src/features/ui/action_menu/items/MediaMenuData.tsx:122
msgid "Download audio"
@@ -13433,7 +13444,7 @@ msgstr "Upotukset näkyvät taas"
#: src/features/app/config/AuditLogConstants.ts:167
#: src/features/emoji/components/emojis/EmojiListItem.tsx:337
#: src/features/theme_studio/sections/TokenGroups.ts:114
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:163
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:171
msgid "Emoji"
msgstr "Emoji"
@@ -13866,15 +13877,15 @@ msgid "End date"
msgstr "Päättymispäivä"
#. Billing button that ends premium grace period immediately.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:856
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:872
msgid "End grace now"
msgstr "Lopeta armonaika nyt"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:164
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:163
msgid "End grace period"
msgstr "Lopeta armonaika"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:157
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:156
msgid "End grace period now?"
msgstr "Päätetäänkö armonaika nyt?"
@@ -14681,7 +14692,7 @@ msgid "Failed to clear trusted domains."
msgstr "Luotettujen verkkotunnusten tyhjennys epäonnistui."
#. Short label in the authentication SSO callback page. Keep the tone plain and specific.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:28
#: src/features/auth/components/pages/SsoCallbackPage.tsx:30
msgid "Failed to complete SSO sign-in"
msgstr "SSO-kirjautuminen epäonnistui"
@@ -15027,7 +15038,7 @@ msgid "Favorite channel"
msgstr "Lisää kanava suosikkeihin"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:79
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:82
msgid "Favorite channels"
msgstr "Suosikkikanavat"
@@ -15800,7 +15811,7 @@ msgstr "Ystävällinen botti"
#: src/features/connection/components/modals/EditConnectionModal.tsx:86
#: src/features/search/utils/QuickSwitcherModalUtils.tsx:50
#: src/features/user/components/modals/tabs/my_profile_tab/TimezoneProfileSettings.tsx:63
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:98
msgid "Friends"
msgstr "Kaverit"
@@ -16145,7 +16156,7 @@ msgstr "Hanki uusi {productName}-sovellus"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Type label for GIF media.
#: src/features/expressions/utils/FavoriteMemeUtils.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:159
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
msgid "GIF"
msgstr "GIF"
@@ -16336,7 +16347,7 @@ msgstr "Lahja: vanhenee pian"
msgid "Gift: grace period (still have access)"
msgstr "Lahja: armonaika (käyttöoikeus on yhä voimassa)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:502
msgid "Gifted <0/> until <1>{giftEndDate}</1>. Does not renew automatically. Redeem more gift codes to extend."
msgstr "Sait <0/> lahjaksi <1>{giftEndDate}</1> asti. Lahja ei uusiudu automaattisesti. Lunasta lisää lahjakoodeja jatkaaksesi."
@@ -16549,7 +16560,7 @@ msgid "Graphics"
msgstr "Grafiikka"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
msgid "Gray text"
msgstr "Harmaa teksti"
@@ -16815,7 +16826,7 @@ msgid "Hate speech"
msgstr "Vihapuhe"
#. Premium page text shown on an instance where the premium tier cannot be bought, only redeemed. {PREMIUM_PRODUCT_NAME} is the premium tier name.
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:297
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:296
msgid "Have a gift code? Redeem it to unlock {PREMIUM_PRODUCT_NAME}."
msgstr "Onko sinulla lahjakoodi? Lunasta se avataksesi {PREMIUM_PRODUCT_NAME}."
@@ -16896,11 +16907,21 @@ msgstr "Hei, {username}! Mukava, että olet täällä."
msgid "Help"
msgstr "Ohje"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:94
msgid "Help button"
msgstr "Apupainike"
#. Short label in the sidebar navigation help button.
#: src/features/app/components/layout/sidebar_nav/HelpButton.tsx:27
msgid "Help center"
msgstr "Ohjekeskus"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:102
msgid "Help center button in the sidebar"
msgstr "Ohjekeskus"
#: src/features/user/components/modals/tabs/LanguageTab.tsx:348
msgid "Help translate {PRODUCT_NAME} into your language on <0>{I18N_WEBLATE_DOMAIN}</0>."
msgstr "Auta kääntämään {PRODUCT_NAME} kielellesi osoitteessa <0>{I18N_WEBLATE_DOMAIN}</0>."
@@ -17035,7 +17056,7 @@ msgid "Hide join messages"
msgstr "Piilota liittymisviestit"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:47
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:50
msgid "Hide keyboard hints"
msgstr "Piilota näppäimistövihjeet"
@@ -18721,7 +18742,7 @@ msgstr "Liity videopuheluun"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/profile/VoiceActivityCard.tsx:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:31
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:34
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:454
msgid "Join voice"
msgstr "Liity puheluun"
@@ -18764,6 +18785,7 @@ msgstr "Siirry lukemattomien kanavien välillä"
msgid "Jump between unread channels with mentions"
msgstr "Siirry lukemattomien kanavien välillä, joissa on mainintoja"
#: src/features/auth/components/pages/SsoCallbackPage.tsx:121
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:75
msgid "Jump straight to the app to continue."
msgstr "Jatka suoraan sovelluksessa."
@@ -18904,7 +18926,7 @@ msgstr "Säilytä liitteet muokkauksen tyhjentämisen yhteydessä"
msgid "Keep free and premium tiers. You can customize the tiers, sell premium through Stripe, or hand out gift codes later from the admin panel."
msgstr "Pidä ilmaiset ja premium-tasot. Voit muokata tasoja, myydä premiumia Stripellä tai jakaa lahjakoodeja myöhemmin ylläpitopaneelista."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:166
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:165
msgid "Keep grace period"
msgstr "Säilytä armonaika"
@@ -18918,7 +18940,7 @@ msgstr "Pidä Neko paikallaan"
msgid "Keep running"
msgstr "Pidä käynnissä"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:144
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:143
msgid "Keep subscription"
msgstr "Säilytä tilaus"
@@ -18980,7 +19002,7 @@ msgid "Keyboard mode"
msgstr "Näppäimistötila"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:59
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:62
msgid "Keyboard shortcut hints in tooltips"
msgstr "Pikanäppäinvihjeet työkaluvihjeissä"
@@ -19275,8 +19297,8 @@ msgstr "Hiiren vasen painike"
msgid "Left tooltip"
msgstr "Vasen työkaluvihje"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:539
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:561
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:555
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:577
msgid "Legacy rate"
msgstr "Vanha hinta"
@@ -20094,7 +20116,7 @@ msgstr "Merkitse ylin saapuneet-kanava luetuksi"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/modals/tabs/component_gallery_tab/index.tsx:364
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:123
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
msgid "Markdown"
msgstr "Markdown"
@@ -20644,7 +20666,7 @@ msgstr "Mainitaanko tämä rooli?"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/guild/components/modals/GuildNotificationSettingsModal.tsx:136
#: src/features/i18n/utils/CommonMessageDescriptors.ts:648
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:167
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
msgid "Mentions"
msgstr "Maininnat"
@@ -21158,7 +21180,7 @@ msgid "Missing client_id"
msgstr "client_id puuttuu"
#. SSO callback page error shown when the SSO callback is missing code or state parameters.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:24
#: src/features/auth/components/pages/SsoCallbackPage.tsx:26
msgid "Missing SSO code. Sign in again."
msgstr "SSO-koodi puuttuu. Kirjaudu sisään uudelleen."
@@ -21317,11 +21339,11 @@ msgstr "Kuukausittain"
msgid "Monthly {monthlyPrice}"
msgstr "Kuukausittain {monthlyPrice}"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:631
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:647
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>."
msgstr "Kuukausilaskutus alkaa <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:624
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:640
msgid "Monthly billing starts on <0>{pendingChangeDate}</0>. First monthly charge: {pendingInitialPriceLabel}. Future monthly renewals: {pendingRecurringPriceLabel}/month."
msgstr "Kuukausilaskutus alkaa <0>{pendingChangeDate}</0>. Ensimmäinen kuukausimaksu: {pendingInitialPriceLabel}. Tulevat kuukausittaiset uusinnat: {pendingRecurringPriceLabel}/kuukausi."
@@ -21756,7 +21778,7 @@ msgstr "mykistetty"
#. Status label indicating the surface is currently muted.
#: src/features/app/components/layout/sidebar_nav/UseGuildListItemState.ts:23
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:491
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:74
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/lib/overlay/OverlayContextMenu.tsx:24
msgid "Muted"
msgstr "Mykistetty"
@@ -21779,7 +21801,7 @@ msgstr "Moderaattoreiden mykistämä"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/ChatSettingsIndex.ts:495
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
msgid "Muted channels"
msgstr "Mykistetyt kanavat"
@@ -21992,7 +22014,7 @@ msgid "Narrates only the channel you're viewing. Narration follows you between c
msgstr "Lukee ääneen vain kanavan, jota katselet. Lukeminen seuraa sinua kanavien välillä."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:155
msgid "Narration"
msgstr "Ääneen luku"
@@ -22057,12 +22079,12 @@ msgid "Need an account?"
msgstr "Tarvitsetko tilin?"
#. Settings search synonym. Proper name of the optional cat sprite that chases the cursor.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:70
msgid "Neko"
msgstr "Neko"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:63
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:66
msgid "Neko cat that chases your cursor"
msgstr "Neko-kissa, joka jahtaa osoitintasi"
@@ -22247,12 +22269,12 @@ msgid "New password"
msgstr "Uusi salasana"
#. Plutonium subscription card line shown when a move to a lower price is scheduled but the new amount is unknown. {pendingChangeDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:595
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:611
msgid "New price scheduled for <0>{pendingChangeDate}</0>."
msgstr "Uusi hinta on ajoitettu päivälle <0>{pendingChangeDate}</0>."
#. Plutonium subscription card line shown when a move to a lower price is scheduled. {pendingChangeDate} is a date and {pendingTargetPriceLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:589
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:605
msgid "New price scheduled for <0>{pendingChangeDate}</0>. Renewals will be {pendingTargetPriceLabel} from then on."
msgstr "Uusi hinta on ajoitettu päivälle <0>{pendingChangeDate}</0>. Uusiminen maksaa sen jälkeen {pendingTargetPriceLabel}."
@@ -23560,6 +23582,8 @@ msgid "Open {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName}
msgstr "Avaa {macosSystemSettingsName} → {macosPrivacyAndSecuritySettingsName} → {macosScreenRecordingPermissionName} ja anna sitten lupa sovellukselle {productName}. Jos {productName2} on jo sallittu, sulje {productName3} kokonaan ja käynnistä se uudelleen, jotta macOS ottaa luvan käyttöön."
#. Button label that opens the desktop app. productName is the app name.
#. Button that hands SSO sign-in back to the mobile app. productName is the app name.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:34
#: src/features/auth/flow/DesktopDeepLinkPrompt.tsx:27
msgid "Open {productName}"
msgstr "Avaa {productName}"
@@ -24945,7 +24969,7 @@ msgstr "Kiinnitä tämä viesti kanavalle kaikkien nähtäväksi."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Voice stats field label (mobile lobby). Shows current latency in ms.
#. Voice stats field label (mobile voice lobby). Shows current latency in ms.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:184
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/voice/components/bottomsheets/DirectCallLobbyBottomSheet.tsx:118
#: src/features/voice/components/bottomsheets/VoiceLobbyBottomSheet.tsx:86
msgid "Ping"
@@ -25165,7 +25189,7 @@ msgid "Popped out"
msgstr "Erillisessä ikkunassa"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:196
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:204
msgid "Popup"
msgstr "Ponnahdusikkuna"
@@ -26128,7 +26152,7 @@ msgstr "Reaktiot"
#. Billing button that cancels a scheduled subscription cancellation.
#. Button label on the premium-expired nagbar. Opens billing so the user can reactivate their subscription.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:746
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:762
#: src/features/app/components/layout/app_layout/nagbars/PremiumExpiredNagbar.tsx:25
msgid "Reactivate"
msgstr "Aktivoi uudelleen"
@@ -26139,7 +26163,7 @@ msgid "Reactivate subscription"
msgstr "Aktivoi tilaus uudelleen"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:131
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
msgid "Read aloud"
msgstr "Lue ääneen"
@@ -26156,7 +26180,7 @@ msgstr "Lue viestihistoriaa"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AccessibilityIndex.ts:177
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:127
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
msgid "Read messages"
msgstr "Lue viestejä"
@@ -26351,8 +26375,8 @@ msgstr "Lunasta itsellesi"
#. Billing button for entering a premium gift code.
#. Billing button for entering a premium gift code.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:719
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:307
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:735
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:306
msgid "Redeem gift code"
msgstr "Lunasta lahjakoodi"
@@ -26630,7 +26654,7 @@ msgstr "Muista ikkunan koko ja sijainti"
#: src/features/user/components/modals/tabs/chat_settings_tab/SearchEnginesTab.tsx:26
#: src/features/user/components/modals/tabs/LinkedAccountsTab.tsx:55
#: src/features/user/components/settings_utils/search_index/AccountSecurityIndex.ts:178
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:192
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:200
#: src/features/webhook/components/WebhookListItem.tsx:277
msgid "Remove"
msgstr "Poista"
@@ -27123,7 +27147,7 @@ msgstr "Uusimiskynnys (päiviä)"
msgid "Renew window (days)"
msgstr "Uusimisikkuna (päiviä)"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:701
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:717
msgid "Renews on <0>{renewalDate}.</0>"
msgstr "Uusiutuu <0>{renewalDate}.</0>"
@@ -27321,7 +27345,7 @@ msgid "Require a passkey as your second factor"
msgstr "Vaadi pääsyavain toisena vaiheena"
#. Short label for an advanced voice-channel navigation preference.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:17
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedAppearanceControls.tsx:20
msgid "Require double-click to join voice channels"
msgstr "Vaadi kaksoisnapsautus äänikanaville liittymiseen"
@@ -27872,8 +27896,8 @@ msgstr "Palauta ikkuna"
#. Billing button for restarting a subscription during the grace period.
#. Billing button for starting a new subscription after premium expired.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:738
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:742
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:754
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:758
msgid "Resubscribe"
msgstr "Tilaa uudelleen"
@@ -29578,7 +29602,7 @@ msgid "Sending malware or dangerous links"
msgstr "Haittaohjelmien tai vaarallisten linkkien lähettäminen"
#. Short label under a destination row in the forward modal, shown when the community has messaging disabled.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:54
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:55
msgid "Sending messages is disabled in this community"
msgstr "Viestien lähettäminen on poistettu käytöstä tässä yhteisössä"
@@ -30120,7 +30144,7 @@ msgstr "Pikanäppäin"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:55
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:58
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:370
msgid "Shortcut badges"
msgstr "Pikanäppäinmerkit"
@@ -30280,7 +30304,9 @@ msgid "Show delete button"
msgstr "Näytä poistopainike"
#. Short label for an advanced media button preference.
#. Toggle label and settings search entry for showing the download app button in the sidebar.
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:76
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:66
msgid "Show download button"
msgstr "Näytä latauspainike"
@@ -30322,7 +30348,7 @@ msgid "Show favorite button"
msgstr "Näytä suosikkipainike"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:87
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:90
msgid "Show favorites throughout the app"
msgstr "Näytä suosikit koko sovelluksessa"
@@ -30350,6 +30376,11 @@ msgstr "Näytä GIF-ilmaisin"
msgid "Show GIFs button"
msgstr "Näytä GIF-painike"
#. Toggle label and settings search entry for showing the help center button in the sidebar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:62
msgid "Show help center button"
msgstr "Näytä ohjekeskuspainike"
#. Switch label in the community-folder settings modal. When on, the folder icon is shown in the sidebar while the folder is collapsed.
#: src/features/guild/components/modals/GuildFolderSettingsModal.tsx:77
msgid "Show icon when collapsed"
@@ -30565,7 +30596,7 @@ msgid "Show stickers in expression autocomplete"
msgstr "Näytä tarrat ilmaisujen automaattisessa täydennyksessä"
#. Description for a visual accessibility setting that mutes the color of text formatted with Markdown strikethrough.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:102
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:110
msgid "Show strikethrough Markdown text in a slightly muted color."
msgstr "Näytä yliviivattu Markdown-teksti hieman himmennetyllä värillä."
@@ -31008,7 +31039,7 @@ msgid "Slowmode"
msgstr "Hidas tila"
#. Short label under a destination row in the forward modal while slowmode blocks sending. Preserve {remaining}; it is inserted by code.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:73
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:74
msgid "Slowmode · wait {remaining}"
msgstr "Hidas tila · odota {remaining}"
@@ -31559,7 +31590,7 @@ msgstr "Katsojat - {count}"
#. Native macOS Edit submenu title for text-to-speech actions.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/platform/utils/DesktopLocaleBridge.ts:85
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:151
msgid "Speech"
msgstr "Puhe"
@@ -31670,12 +31701,12 @@ msgstr "Neliönmuotoiset kuvakepainikkeet"
msgid "SSO is required to access this workspace."
msgstr "Tämän työtilan käyttö edellyttää kertakirjautumista."
#: src/features/auth/components/pages/SsoCallbackPage.tsx:105
#: src/features/auth/components/pages/SsoCallbackPage.tsx:139
msgid "SSO sign-in failed"
msgstr "SSO-kirjautuminen epäonnistui"
#. SSO callback page error shown when the SSO sign-in timed out before the callback arrived.
#: src/features/auth/components/pages/SsoCallbackPage.tsx:20
#: src/features/auth/components/pages/SsoCallbackPage.tsx:22
msgid "SSO sign-in timed out. Try again."
msgstr "SSO-kirjautuminen aikakatkaistiin. Yritä uudelleen."
@@ -31714,7 +31745,7 @@ msgid "Star animation"
msgstr "Tähtianimaatio"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:83
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:86
msgid "Starred channels"
msgstr "Tähdellä merkityt kanavat"
@@ -31791,7 +31822,7 @@ msgstr "Aloita alusta"
msgid "Start recording"
msgstr "Aloita nauhoitus"
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:592
#: src/features/search/components/quick_switcher/QuickSwitcherModal.tsx:582
msgid "Start searches with <0>{peoplePrefix}</0> <1>{textChannelPrefix}</1> <2>{voiceChannelPrefix}</2> <3>{communityPrefix}</3> to narrow down results."
msgstr "Aloita haut käyttämällä <0>{peoplePrefix}</0>, <1>{textChannelPrefix}</1>, <2>{voiceChannelPrefix}</2> ja <3>{communityPrefix}</3>, jotta voit rajata hakutuloksia."
@@ -31831,7 +31862,7 @@ msgid "Startup"
msgstr "Käynnistys"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:75
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:78
msgid "Static Neko"
msgstr "Staattinen Neko"
@@ -32038,7 +32069,7 @@ msgid "Still indexing — check back in a moment"
msgstr "Indeksointi käynnissä – tarkista hetken kuluttua"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:71
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:74
msgid "Still Neko"
msgstr "Liikkumaton Neko"
@@ -32067,7 +32098,7 @@ msgid "Stop mic test"
msgstr "Lopeta mikrofonitesti"
#. Settings search entry description. One-line summary of what the setting controls.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:67
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:70
msgid "Stop Neko from chasing your cursor while keeping it draggable and interactive."
msgstr "Estä Nekoa jahtaamasta osoitintasi, mutta pidä se silti vedettävänä ja interaktiivisena."
@@ -32259,14 +32290,14 @@ msgid "Streaming privacy on"
msgstr "Striimauksen yksityisyys käytössä"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:111
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:119
msgid "Strike through"
msgstr "Yliviivaus"
#. Selection formatting toolbar button.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/lexical/composer/SelectionFormattingToolbar.tsx:72
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:107
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:115
msgid "Strikethrough"
msgstr "Yliviivaus"
@@ -32490,7 +32521,7 @@ msgid "Switch price"
msgstr "Vaihda hintaa"
#. Billing button that opens confirmation to move the subscription down to the current price. {listPriceNewLabel} is the localized new price.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:806
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:822
msgid "Switch to {listPriceNewLabel}"
msgstr "Vaihda hintaan {listPriceNewLabel}"
@@ -32515,7 +32546,7 @@ msgstr "Vaihda suoraan syöttöön"
#. Billing button that opens confirmation to switch to monthly billing.
#. Button confirming a change to monthly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:57
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:789
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:805
msgid "Switch to monthly"
msgstr "Vaihda kuukausitilaukseen"
@@ -32584,7 +32615,7 @@ msgstr "Vaihda kaksipalstaiseen näkymään"
#. Billing button that opens confirmation to switch to yearly billing.
#. Button confirming a change to yearly subscription billing.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:53
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:785
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:801
msgid "Switch to yearly"
msgstr "Vaihda vuositilaukseen"
@@ -33074,7 +33105,7 @@ msgstr "Lähetä meille tekstiviesti puhelimestasi"
#. Feature label / section heading for the text-to-speech feature.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/i18n/utils/CommonMessageDescriptors.ts:419
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:139
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:147
msgid "Text-to-speech"
msgstr "Tekstistä puheeksi"
@@ -34133,7 +34164,7 @@ msgid "This member isn't connected to voice anymore."
msgstr "Tämä jäsen ei ole enää äänikanavalla."
#. Forward dialog error shown when the forwarded message contains age-restricted media and the target channel is not age-restricted.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:68
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:69
msgid "This message can only be forwarded to age-restricted channels"
msgstr "Tämä viesti voidaan välittää vain ikärajoitettuihin kanaviin"
@@ -34766,7 +34797,7 @@ msgid "Toolbar"
msgstr "Työkalurivi"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:51
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:54
msgid "Tooltip shortcuts"
msgstr "Pikanäppäinvihjeet"
@@ -35080,7 +35111,7 @@ msgid "Try sending your message again."
msgstr "Yritä lähettää viesti uudelleen."
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:135
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:143
msgid "TTS"
msgstr "TTS"
@@ -35277,7 +35308,7 @@ msgstr "24 tunnin kello"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:39
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:42
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:406
msgid "Two clicks"
msgstr "Kaksi klikkausta"
@@ -35834,7 +35865,7 @@ msgstr "Avaa mukautetut emojit yksityisviesteissä {premiumProductName}-tilaukse
msgid "Unlock HD screen share with {premiumProductName}"
msgstr "Avaa HD-näytönjako käyttöön {premiumProductName}-tilauksella"
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:217
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:216
msgid "Unlock higher limits and exclusive features while supporting an independent communication platform."
msgstr "Saat käyttöösi suuremmat rajat ja vain tilaajille tarkoitetut ominaisuudet sekä tuet samalla riippumatonta viestintäalustaa."
@@ -36044,7 +36075,7 @@ msgstr "lukematon"
#. Tab label in the inbox popout filtering to channels with unread messages.
#: src/features/messaging/components/popouts/InboxPopout.tsx:30
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:10
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:78
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:86
msgid "Unread"
msgstr "Lukemattomat"
@@ -37866,7 +37897,7 @@ msgstr "Visuaaliset ilmaisimet, jotka näyttävät käyttäjän tilan. Ne render
#: src/features/app/components/layout/MobileBottomNav.tsx:123
#: src/features/channel/utils/ChannelUtils.tsx:31
#: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedSettingsCategories.ts:17
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:82
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:90
msgid "Voice"
msgstr "Ääni"
@@ -37961,7 +37992,7 @@ msgstr "Äänikanava"
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#. Settings search synonym. Used to match this term when the user types it in the settings search bar.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:23
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:26
#: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:402
msgid "Voice channel confirmation"
msgstr "Äänikanavan vahvistus"
@@ -37972,7 +38003,7 @@ msgid "Voice channel full"
msgstr "Äänikanava täynnä"
#. Settings search entry label. Names the settings search entry in the settings UI.
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:19
#: src/features/user/components/settings_utils/search_index/AppearanceIndex.ts:22
msgid "Voice channel join behavior"
msgstr "Äänikanavalle liittymisen toiminta"
@@ -38099,7 +38130,7 @@ msgstr "Mitätöity"
#: src/features/i18n/utils/CommonMessageDescriptors.ts:378
#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:181
#: src/features/user/components/settings_utils/search_index/NotificationsIndex.ts:86
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:175
#: src/features/user/components/settings_utils/section_registry/SharedDescriptors.ts:183
msgid "Volume"
msgstr "Äänenvoimakkuus"
@@ -38984,15 +39015,15 @@ msgstr "Vuosittain {yearlyPrice}"
msgid "Yearly gift"
msgstr "Vuosilahja"
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:618
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:634
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>."
msgstr "Päivitys vuositilaukseen on ajoitettu päivälle <0>{pendingChangeDate}</0>."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:603
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:619
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel} after a {pendingCreditPriceLabel} credit. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Päivitys vuositilaukseen on ajoitettu päivälle <0>{pendingChangeDate}</0>. Ensimmäinen vuosimaksu: {pendingInitialPriceLabel} hyvityksen {pendingCreditPriceLabel} jälkeen. Tulevat vuosiuusinnat: {pendingRecurringPriceLabel}/vuosi."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:610
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:626
msgid "Yearly upgrade scheduled for <0>{pendingChangeDate}</0>. First yearly charge: {pendingInitialPriceLabel}. Future yearly renewals: {pendingRecurringPriceLabel}/year."
msgstr "Päivitys vuositilaukseen on ajoitettu päivälle <0>{pendingChangeDate}</0>. Ensimmäinen vuosimaksu: {pendingInitialPriceLabel}. Tulevat vuosiuusinnat: {pendingRecurringPriceLabel}/vuosi."
@@ -39462,10 +39493,10 @@ msgid "You just pressed Tab. Keyboard mode is now on so you can navigate {produc
msgstr "Painoit juuri sarkainta. Näppäimistötila on nyt käytössä, joten voit liikkua {productName}-sovelluksessa ilman hiirtä."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:137
msgid "You keep your perks until your next renewal date, then have a 3-day grace period to resubscribe and keep your subscriber history."
msgstr "Pidät etusi seuraavaan uusimispäivään asti, minkä jälkeen sinulla on kolmen päivän lisäaika tilata uudelleen ja säilyttää tilaushistoriasi."
msgid "You keep your perks until your next renewal date. Reactivate before then to keep your subscriber history."
msgstr "Pidät etusi seuraavaan uusimispäivään asti. Aktivoi tilaus uudelleen ennen sitä, niin säilytät tilaushistoriasi."
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:159
#: src/features/app/components/dialogs/components/PlutoniumContent.tsx:158
msgid "You lose all {PREMIUM_PRODUCT_NAME} perks immediately and your subscriber history resets. This cannot be undone."
msgstr "Menetät kaikki {PREMIUM_PRODUCT_NAME}-edut välittömästi ja tilaushistoriasi nollataan. Tätä ei voi kumota."
@@ -39508,12 +39539,12 @@ msgid "You need access to your current email to change it from here. Use phone v
msgstr "Jotta voit vaihtaa sähköpostiosoitteesi täältä, tarvitset pääsyn nykyiseen sähköpostiisi. Käytä puhelinvarmennusta, jos se on saatavilla, tai ota yhteyttä tukeen."
#. Forward dialog error shown when the forwarded message has attachments and the user lacks Attach Files in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:63
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:64
msgid "You need the \"{attachFilesPermissionLabel}\" permission to attach files in this channel"
msgstr "Tarvitset \"{attachFilesPermissionLabel}\" -käyttöoikeuden liittääksesi tiedostoja tällä kanavalla"
#. Forward dialog error shown when the forwarded message contains embeds and the user lacks Embed Links in the target channel.
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:58
#: src/features/app/components/dialogs/shared/UseForwardDestinations.ts:59
msgid "You need the \"{embedLinksPermissionLabel}\" permission to embed links in this channel"
msgstr "Tarvitset \"{embedLinksPermissionLabel}\" -käyttöoikeuden upottaaksesi linkkejä tällä kanavalla"
@@ -40200,6 +40231,11 @@ msgstr "alueesi"
msgid "Your registration needs an extra anti-spam check before you can continue."
msgstr "Rekisteröitymisesi vaatii ylimääräisen roskapostitarkistuksen, ennen kuin voit jatkaa."
#. Plutonium subscription card text shown while a failed renewal payment is being retried. {graceDate} is a date already formatted and localized by code; never write a date into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
msgid "Your renewal payment failed but <0/> stay active until <1>{graceDate}</1>. Update your payment method before then to keep your subscription."
msgstr "Uusimismaksusi epäonnistui, mutta <0/> pysyvät voimassa <1>{graceDate}</1> asti. Päivitä maksutapasi ennen sitä, niin säilytät tilauksesi."
#. Video settings note shown when the saved screen share quality is above what this account can send. Resolutions are short labels such as 1440p or Source and rates are whole numbers. FPS is a technical token.
#: src/features/user/components/modals/tabs/UserVideoTab.tsx:92
msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS."
@@ -40221,7 +40257,7 @@ msgstr "Striimisi on edelleen käynnissä"
msgid "Your subscription can't move to the new price right now."
msgstr "Tilauksesi ei voi siirtyä uuteen hintaan juuri nyt."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:470
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:486
msgid "Your subscription ended but <0/> stay active until <1>{graceDate}</1>. Resubscribe before then to keep your subscriber history."
msgstr "Tilauksesi päättyi, mutta <0/> pysyvät voimassa <1>{graceDate}</1> asti. Tilaa uudelleen ennen sitä, niin säilytät tilaushistoriasi."
@@ -40250,7 +40286,7 @@ msgstr "Tilauksesi on nyt kuukausilaskutuksella."
msgid "Your subscription has been switched to yearly billing."
msgstr "Tilauksesi on nyt vuosilaskutuksella."
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:512
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:528
msgid "Your subscription is active but perks are temporarily paused."
msgstr "Tilauksesi on aktiivinen, mutta edut ovat väliaikaisesti keskeytettyinä."
@@ -40270,7 +40306,7 @@ msgid "Your subscription moves to the new price on {effectiveDate}."
msgstr "Tilauksesi siirtyy uuteen hintaan {effectiveDate}."
#. Plutonium subscription card line shown to a subscriber on a legacy price whose subscription is already set to cancel. {cancelDate} is a date and {listPriceNewLabel} is a currency amount, both already formatted and localized by code; never write a date or an amount into the translation.
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:666
#: src/features/app/components/dialogs/components/plutonium/SubscriptionCard.tsx:682
msgid "Your subscription still ends on <0>{cancelDate}</0>. The current price is now {listPriceNewLabel}. If you reactivate, you can switch to it from here."
msgstr "Tilauksesi päättyy silti <0>{cancelDate}</0>. Nykyinen hinta on nyt {listPriceNewLabel}. Jos aktivoit sen uudelleen, voit vaihtaa siihen täältä."

Some files were not shown because too many files have changed in this diff Show More