Compare commits
1 Commits
2025-08-01
...
system-loc
| Author | SHA1 | Date | |
|---|---|---|---|
|
c1d3be4c07
|
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -3517,6 +3517,7 @@ dependencies = [
|
|||||||
"sha2",
|
"sha2",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
|
"sys-locale",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"tokenator",
|
"tokenator",
|
||||||
@@ -5721,6 +5722,15 @@ dependencies = [
|
|||||||
"syn 2.0.104",
|
"syn 2.0.104",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sys-locale"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sysinfo"
|
name = "sysinfo"
|
||||||
version = "0.30.13"
|
version = "0.30.13"
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ tracing-appender = "0.2.3"
|
|||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
tempfile = "3.13.0"
|
tempfile = "3.13.0"
|
||||||
unic-langid = { version = "0.9.6", features = ["macros"] }
|
unic-langid = { version = "0.9.6", features = ["macros"] }
|
||||||
|
sys-locale = "0.3"
|
||||||
url = "2.5.2"
|
url = "2.5.2"
|
||||||
urlencoding = "2.1.3"
|
urlencoding = "2.1.3"
|
||||||
uuid = { version = "1.10.0", features = ["v4"] }
|
uuid = { version = "1.10.0", features = ["v4"] }
|
||||||
|
|||||||
@@ -241,9 +241,6 @@ Enter_your_public_key__npub___nostr_address__e_g___address____or_private_key__ns
|
|||||||
# Label for find user button
|
# Label for find user button
|
||||||
Find_User_bd12 = Find User
|
Find_User_bd12 = Find User
|
||||||
|
|
||||||
# Label for font size, Appearance settings section
|
|
||||||
Font_size_dd73 = Font size:
|
|
||||||
|
|
||||||
# Title for hashtags column
|
# Title for hashtags column
|
||||||
Hashtags_f8e0 = Hashtags
|
Hashtags_f8e0 = Hashtags
|
||||||
|
|
||||||
@@ -355,9 +352,6 @@ Notifications_ef56 = Notifications
|
|||||||
# Relative time for very recent events (less than 3 seconds)
|
# Relative time for very recent events (less than 3 seconds)
|
||||||
now_2181 = now
|
now_2181 = now
|
||||||
|
|
||||||
# Setting to turn on sorting replies so that the newest are shown first
|
|
||||||
On_f412 = On
|
|
||||||
|
|
||||||
# Button label to open email client
|
# Button label to open email client
|
||||||
Open_Email_25e9 = Open Email
|
Open_Email_25e9 = Open Email
|
||||||
|
|
||||||
@@ -436,9 +430,6 @@ Repost_this_note_8e56 = Repost this note
|
|||||||
# Label for reposted notes
|
# Label for reposted notes
|
||||||
Reposted_61c8 = Reposted
|
Reposted_61c8 = Reposted
|
||||||
|
|
||||||
# Label for reset note body font size, Appearance settings section
|
|
||||||
Reset_4e60 = Reset
|
|
||||||
|
|
||||||
# Label for reset zoom level, Appearance settings section
|
# Label for reset zoom level, Appearance settings section
|
||||||
Reset_62d4 = Reset
|
Reset_62d4 = Reset
|
||||||
|
|
||||||
@@ -478,6 +469,9 @@ Send_1ea4 = Send
|
|||||||
# Column title for app settings
|
# Column title for app settings
|
||||||
Settings_7a4f = Settings
|
Settings_7a4f = Settings
|
||||||
|
|
||||||
|
# Label for Show source client, others settings section
|
||||||
|
Show_source_client_9e31 = Show source client
|
||||||
|
|
||||||
# Description for last note per user column
|
# Description for last note per user column
|
||||||
Show_the_last_note_for_each_user_from_a_list_50e7 = Show the last note for each user from a list
|
Show_the_last_note_for_each_user_from_a_list_50e7 = Show the last note for each user from a list
|
||||||
|
|
||||||
@@ -490,12 +484,6 @@ Someone_else_s_Notes_7e5f = Someone else's Notes
|
|||||||
# Title for someone else's notifications column
|
# Title for someone else's notifications column
|
||||||
Someone_else_s_Notifications_82e6 = Someone else's Notifications
|
Someone_else_s_Notifications_82e6 = Someone else's Notifications
|
||||||
|
|
||||||
# Label for Sort replies newest first, others settings section
|
|
||||||
Sort_replies_newest_first_b6c3 = Sort replies newest first:
|
|
||||||
|
|
||||||
# Label for Source client, others settings section
|
|
||||||
Source_client_fb2b = Source client:
|
|
||||||
|
|
||||||
# Description for contact list column
|
# Description for contact list column
|
||||||
Source_the_last_note_for_each_user_in_your_contact_list_e157 = Source the last note for each user in your contact list
|
Source_the_last_note_for_each_user_in_your_contact_list_e157 = Source the last note for each user in your contact list
|
||||||
|
|
||||||
@@ -532,9 +520,6 @@ Subscribe_to_someone_else_s_notes_d1e9 = Subscribe to someone else's notes
|
|||||||
# Column title for subscribing to individual user
|
# Column title for subscribing to individual user
|
||||||
Subscribe_to_someone_s_notes_b3c8 = Subscribe to someone's notes
|
Subscribe_to_someone_s_notes_b3c8 = Subscribe to someone's notes
|
||||||
|
|
||||||
# Support email address
|
|
||||||
Support_email_44d9 = Support email:
|
|
||||||
|
|
||||||
# Hover text for dark mode toggle button
|
# Hover text for dark mode toggle button
|
||||||
Switch_to_dark_mode_4dec = Switch to dark mode
|
Switch_to_dark_mode_4dec = Switch to dark mode
|
||||||
|
|
||||||
@@ -575,7 +560,7 @@ username___at___domain___will_be_used_for_identification_a4fd = "{$username}" at
|
|||||||
Username_daa7 = Username
|
Username_daa7 = Username
|
||||||
|
|
||||||
# Label for view folder button, Storage settings section
|
# Label for view folder button, Storage settings section
|
||||||
View_folder_9742 = View folder
|
View_folder_9742 = View folder:
|
||||||
|
|
||||||
# Column title for wallet management
|
# Column title for wallet management
|
||||||
Wallet_5e50 = Wallet
|
Wallet_5e50 = Wallet
|
||||||
|
|||||||
@@ -241,9 +241,6 @@ Enter_your_public_key__npub___nostr_address__e_g___address____or_private_key__ns
|
|||||||
# Label for find user button
|
# Label for find user button
|
||||||
Find_User_bd12 = {"["}Fíñd Úsér{"]"}
|
Find_User_bd12 = {"["}Fíñd Úsér{"]"}
|
||||||
|
|
||||||
# Label for font size, Appearance settings section
|
|
||||||
Font_size_dd73 = {"["}Fóñt sízé:{"]"}
|
|
||||||
|
|
||||||
# Title for hashtags column
|
# Title for hashtags column
|
||||||
Hashtags_f8e0 = {"["}Hàshtàgs{"]"}
|
Hashtags_f8e0 = {"["}Hàshtàgs{"]"}
|
||||||
|
|
||||||
@@ -355,9 +352,6 @@ Notifications_ef56 = {"["}Ñótífíçàtíóñs{"]"}
|
|||||||
# Relative time for very recent events (less than 3 seconds)
|
# Relative time for very recent events (less than 3 seconds)
|
||||||
now_2181 = {"["}ñów{"]"}
|
now_2181 = {"["}ñów{"]"}
|
||||||
|
|
||||||
# Setting to turn on sorting replies so that the newest are shown first
|
|
||||||
On_f412 = {"["}Óñ{"]"}
|
|
||||||
|
|
||||||
# Button label to open email client
|
# Button label to open email client
|
||||||
Open_Email_25e9 = {"["}Ópéñ Émàíl{"]"}
|
Open_Email_25e9 = {"["}Ópéñ Émàíl{"]"}
|
||||||
|
|
||||||
@@ -436,9 +430,6 @@ Repost_this_note_8e56 = {"["}Répóst thís ñóté{"]"}
|
|||||||
# Label for reposted notes
|
# Label for reposted notes
|
||||||
Reposted_61c8 = {"["}Répóstéd{"]"}
|
Reposted_61c8 = {"["}Répóstéd{"]"}
|
||||||
|
|
||||||
# Label for reset note body font size, Appearance settings section
|
|
||||||
Reset_4e60 = {"["}Rését{"]"}
|
|
||||||
|
|
||||||
# Label for reset zoom level, Appearance settings section
|
# Label for reset zoom level, Appearance settings section
|
||||||
Reset_62d4 = {"["}Rését{"]"}
|
Reset_62d4 = {"["}Rését{"]"}
|
||||||
|
|
||||||
@@ -478,6 +469,9 @@ Send_1ea4 = {"["}Séñd{"]"}
|
|||||||
# Column title for app settings
|
# Column title for app settings
|
||||||
Settings_7a4f = {"["}Séttíñgs{"]"}
|
Settings_7a4f = {"["}Séttíñgs{"]"}
|
||||||
|
|
||||||
|
# Label for Show source client, others settings section
|
||||||
|
Show_source_client_9e31 = {"["}Shów sóúrçé çlíéñt{"]"}
|
||||||
|
|
||||||
# Description for last note per user column
|
# Description for last note per user column
|
||||||
Show_the_last_note_for_each_user_from_a_list_50e7 = {"["}Shów thé làst ñóté fór éàçh úsér fróm à líst{"]"}
|
Show_the_last_note_for_each_user_from_a_list_50e7 = {"["}Shów thé làst ñóté fór éàçh úsér fróm à líst{"]"}
|
||||||
|
|
||||||
@@ -490,12 +484,6 @@ Someone_else_s_Notes_7e5f = {"["}Sóméóñé élsé's Ñótés{"]"}
|
|||||||
# Title for someone else's notifications column
|
# Title for someone else's notifications column
|
||||||
Someone_else_s_Notifications_82e6 = {"["}Sóméóñé élsé's Ñótífíçàtíóñs{"]"}
|
Someone_else_s_Notifications_82e6 = {"["}Sóméóñé élsé's Ñótífíçàtíóñs{"]"}
|
||||||
|
|
||||||
# Label for Sort replies newest first, others settings section
|
|
||||||
Sort_replies_newest_first_b6c3 = {"["}Sórt réplíés ñéwést fírst:{"]"}
|
|
||||||
|
|
||||||
# Label for Source client, others settings section
|
|
||||||
Source_client_fb2b = {"["}Sóúrçé çlíéñt:{"]"}
|
|
||||||
|
|
||||||
# Description for contact list column
|
# Description for contact list column
|
||||||
Source_the_last_note_for_each_user_in_your_contact_list_e157 = {"["}Sóúrçé thé làst ñóté fór éàçh úsér íñ yóúr çóñtàçt líst{"]"}
|
Source_the_last_note_for_each_user_in_your_contact_list_e157 = {"["}Sóúrçé thé làst ñóté fór éàçh úsér íñ yóúr çóñtàçt líst{"]"}
|
||||||
|
|
||||||
@@ -532,9 +520,6 @@ Subscribe_to_someone_else_s_notes_d1e9 = {"["}Súbsçríbé tó sóméóñé él
|
|||||||
# Column title for subscribing to individual user
|
# Column title for subscribing to individual user
|
||||||
Subscribe_to_someone_s_notes_b3c8 = {"["}Súbsçríbé tó sóméóñé's ñótés{"]"}
|
Subscribe_to_someone_s_notes_b3c8 = {"["}Súbsçríbé tó sóméóñé's ñótés{"]"}
|
||||||
|
|
||||||
# Support email address
|
|
||||||
Support_email_44d9 = {"["}Súppórt émàíl:{"]"}
|
|
||||||
|
|
||||||
# Hover text for dark mode toggle button
|
# Hover text for dark mode toggle button
|
||||||
Switch_to_dark_mode_4dec = {"["}Swítçh tó dàrk módé{"]"}
|
Switch_to_dark_mode_4dec = {"["}Swítçh tó dàrk módé{"]"}
|
||||||
|
|
||||||
@@ -575,7 +560,7 @@ username___at___domain___will_be_used_for_identification_a4fd = {"["}"{$username
|
|||||||
Username_daa7 = {"["}Úsérñàmé{"]"}
|
Username_daa7 = {"["}Úsérñàmé{"]"}
|
||||||
|
|
||||||
# Label for view folder button, Storage settings section
|
# Label for view folder button, Storage settings section
|
||||||
View_folder_9742 = {"["}Víéw fóldér{"]"}
|
View_folder_9742 = {"["}Víéw fóldér:{"]"}
|
||||||
|
|
||||||
# Column title for wallet management
|
# Column title for wallet management
|
||||||
Wallet_5e50 = {"["}Wàllét{"]"}
|
Wallet_5e50 = {"["}Wàllét{"]"}
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ Algo_2452 = Algo
|
|||||||
Algorithmic_feeds_to_aid_in_note_discovery_d344 = Feeds algorítmicos para ayudar en el descubrimiento de notas
|
Algorithmic_feeds_to_aid_in_note_discovery_d344 = Feeds algorítmicos para ayudar en el descubrimiento de notas
|
||||||
# Label for zap amount input field
|
# Label for zap amount input field
|
||||||
Amount_70f0 = Cantidad
|
Amount_70f0 = Cantidad
|
||||||
# Label for appearance settings section
|
|
||||||
Appearance_4c7f = Aspecto
|
|
||||||
# Button to send message to Dave AI assistant
|
# Button to send message to Dave AI assistant
|
||||||
Ask_b7f4 = Preguntar
|
Ask_b7f4 = Preguntar
|
||||||
# Placeholder text for Dave AI input field
|
# Placeholder text for Dave AI input field
|
||||||
@@ -55,26 +53,16 @@ Ask_dave_anything_33d1 = Pregúntale cualquier cosa a Dave...
|
|||||||
Banner_52ef = Banner
|
Banner_52ef = Banner
|
||||||
# Beta version label
|
# Beta version label
|
||||||
BETA_8e5d = BETA
|
BETA_8e5d = BETA
|
||||||
# Option in settings section to show the source client label at the bottom of the note
|
|
||||||
Bottom_33c8 = Parte inferior
|
|
||||||
# Broadcast the note to all connected relays
|
# Broadcast the note to all connected relays
|
||||||
Broadcast_fe43 = Transmitir
|
Broadcast_fe43 = Transmitir
|
||||||
# Broadcast the note only to local network relays
|
# Broadcast the note only to local network relays
|
||||||
Broadcast_Local_7e50 = Transmitir localmente
|
Broadcast_Local_7e50 = Transmitir localmente
|
||||||
# Button label to cancel an action
|
# Button label to cancel an action
|
||||||
Cancel_ed3b = Cancelar
|
Cancel_ed3b = Cancelar
|
||||||
# Label for cancel clear cache, Storage settings section
|
|
||||||
Cancel_fd8b = Cancelar
|
|
||||||
# Label for clear cache button, Storage settings section
|
|
||||||
Clear_cache_dccb = Limpiar caché
|
|
||||||
# Hover text for editable zap amount
|
# Hover text for editable zap amount
|
||||||
Click_to_edit_0414 = Haz clic para editar
|
Click_to_edit_0414 = Haz clic para editar
|
||||||
# Column title for note composition
|
# Column title for note composition
|
||||||
Compose_Note_c094 = Redactar nota
|
Compose_Note_c094 = Redactar nota
|
||||||
# Label for configure relays, settings section
|
|
||||||
Configure_relays_d156 = Configurar relés
|
|
||||||
# Label for confirm clear cache, Storage settings section
|
|
||||||
Confirm_9d9d = Confirmar
|
|
||||||
# Button label to confirm an action
|
# Button label to confirm an action
|
||||||
Confirm_f8a6 = Confirmar
|
Confirm_f8a6 = Confirmar
|
||||||
# Status label for connected relay
|
# Status label for connected relay
|
||||||
@@ -123,8 +111,6 @@ Custom_a69e = Personalizado
|
|||||||
Customize_Zap_Amount_cfc4 = Personalizar cantidad de zap
|
Customize_Zap_Amount_cfc4 = Personalizar cantidad de zap
|
||||||
# Column title for support page
|
# Column title for support page
|
||||||
Damus_Support_27c0 = Ayuda de Damus
|
Damus_Support_27c0 = Ayuda de Damus
|
||||||
# Label for Theme Dark, Appearance settings section
|
|
||||||
Dark_85fe = Oscuro
|
|
||||||
# Label for deck name input field
|
# Label for deck name input field
|
||||||
Deck_name_cd32 = Nombre del deck
|
Deck_name_cd32 = Nombre del deck
|
||||||
# Label for decks section in side panel
|
# Label for decks section in side panel
|
||||||
@@ -165,14 +151,10 @@ Enter_your_public_key__npub___nostr_address__e_g___address____or_private_key__ns
|
|||||||
Find_User_bd12 = Buscar usuario
|
Find_User_bd12 = Buscar usuario
|
||||||
# Title for hashtags column
|
# Title for hashtags column
|
||||||
Hashtags_f8e0 = Hashtags
|
Hashtags_f8e0 = Hashtags
|
||||||
# Option in settings section to hide the source client label in note display
|
|
||||||
Hide_281d = Ocultar
|
|
||||||
# Title for Home column
|
# Title for Home column
|
||||||
Home_8c19 = Inicio
|
Home_8c19 = Inicio
|
||||||
# Label for deck icon selection
|
# Label for deck icon selection
|
||||||
Icon_b0ab = Ícono
|
Icon_b0ab = Ícono
|
||||||
# Label for Image cache size, Storage settings section
|
|
||||||
Image_cache_size_3004 = Tamaño de caché de imágenes:
|
|
||||||
# Title for individual user column
|
# Title for individual user column
|
||||||
Individual_b776 = Individual
|
Individual_b776 = Individual
|
||||||
# Error message for invalid zap amount
|
# Error message for invalid zap amount
|
||||||
@@ -193,12 +175,8 @@ k_50K_c2dc = 50.000
|
|||||||
k_5K_f7e6 = 5.000
|
k_5K_f7e6 = 5.000
|
||||||
# Description for your notes column
|
# Description for your notes column
|
||||||
Keep_track_of_your_notes___replies_a334 = Haz seguimiento de tus notas y respuestas
|
Keep_track_of_your_notes___replies_a334 = Haz seguimiento de tus notas y respuestas
|
||||||
# Label for language, Appearance settings section
|
|
||||||
Language_e264 = Idioma:
|
|
||||||
# Title for last note per user column
|
# Title for last note per user column
|
||||||
Last_Note_per_User_17ad = Última nota por usuario
|
Last_Note_per_User_17ad = Última nota por usuario
|
||||||
# Label for Theme Light, Appearance settings section
|
|
||||||
Light_7475 = Claro
|
|
||||||
# Bitcoin Lightning network address field label
|
# Bitcoin Lightning network address field label
|
||||||
Lightning_network_address__lud16_ea51 = Dirección de la red Lightning (lud16)
|
Lightning_network_address__lud16_ea51 = Dirección de la red Lightning (lud16)
|
||||||
# Login page title
|
# Login page title
|
||||||
@@ -241,8 +219,6 @@ now_2181 = ahora
|
|||||||
Open_Email_25e9 = Abrir correo electrónico
|
Open_Email_25e9 = Abrir correo electrónico
|
||||||
# Instruction to open email client
|
# Instruction to open email client
|
||||||
Open_your_default_email_client_to_get_help_from_the_Damus_team_68dc = Abre tu cliente de correo predeterminado para recibir ayuda del equipo de Damus
|
Open_your_default_email_client_to_get_help_from_the_Damus_team_68dc = Abre tu cliente de correo predeterminado para recibir ayuda del equipo de Damus
|
||||||
# Label for others settings section
|
|
||||||
Others_7267 = Otros
|
|
||||||
# Placeholder text for NWC URI input
|
# Placeholder text for NWC URI input
|
||||||
Paste_your_NWC_URI_here_b471 = Pega tu NWC URI aquí...
|
Paste_your_NWC_URI_here_b471 = Pega tu NWC URI aquí...
|
||||||
# Error message for missing deck name
|
# Error message for missing deck name
|
||||||
@@ -289,8 +265,6 @@ replying_to_a_note_e0bc = respondiendo a una nota
|
|||||||
Repost_this_note_8e56 = Volver a publicar esta nota
|
Repost_this_note_8e56 = Volver a publicar esta nota
|
||||||
# Label for reposted notes
|
# Label for reposted notes
|
||||||
Reposted_61c8 = Publicadas de nuevo
|
Reposted_61c8 = Publicadas de nuevo
|
||||||
# Label for reset zoom level, Appearance settings section
|
|
||||||
Reset_62d4 = Restablecer
|
|
||||||
# Heading for support section
|
# Heading for support section
|
||||||
Running_into_a_bug_1796 = ¿Encontraste un error?
|
Running_into_a_bug_1796 = ¿Encontraste un error?
|
||||||
# Label for satoshis (Bitcoin unit) for custom zap amount input field
|
# Label for satoshis (Bitcoin unit) for custom zap amount input field
|
||||||
@@ -313,10 +287,6 @@ See_notes_from_your_contacts_ac16 = Ver notas de tus contactos
|
|||||||
See_the_whole_nostr_universe_7694 = Ver todo el universo de nostr
|
See_the_whole_nostr_universe_7694 = Ver todo el universo de nostr
|
||||||
# Button label to send a zap
|
# Button label to send a zap
|
||||||
Send_1ea4 = Enviar
|
Send_1ea4 = Enviar
|
||||||
# Column title for app settings
|
|
||||||
Settings_7a4f = Configuración
|
|
||||||
# Label for Show source client, others settings section
|
|
||||||
Show_source_client_9e31 = Mostrar cliente de origen
|
|
||||||
# Description for last note per user column
|
# Description for last note per user column
|
||||||
Show_the_last_note_for_each_user_from_a_list_50e7 = Mostrar la última nota para cada usuario de una lista
|
Show_the_last_note_for_each_user_from_a_list_50e7 = Mostrar la última nota para cada usuario de una lista
|
||||||
# Button label to sign out of account
|
# Button label to sign out of account
|
||||||
@@ -343,8 +313,6 @@ Stay_up_to_date_with_your_notifications_and_mentions_e73e = Mantente al día con
|
|||||||
Step_1_8656 = Paso 1
|
Step_1_8656 = Paso 1
|
||||||
# Step 2 label in support instructions
|
# Step 2 label in support instructions
|
||||||
Step_2_d08d = Paso 2
|
Step_2_d08d = Paso 2
|
||||||
# Label for storage settings section
|
|
||||||
Storage_ed65 = Almacenamiento
|
|
||||||
# Column title for subscribing to external user
|
# Column title for subscribing to external user
|
||||||
Subscribe_to_someone_else_s_notes_d1e9 = Suscribirse a las notas de otra persona
|
Subscribe_to_someone_else_s_notes_d1e9 = Suscribirse a las notas de otra persona
|
||||||
# Column title for subscribing to individual user
|
# Column title for subscribing to individual user
|
||||||
@@ -357,14 +325,10 @@ Switch_to_light_mode_72ce = Cambiar a modo claro
|
|||||||
Tap_to_Load_4b05 = Toca para cargar
|
Tap_to_Load_4b05 = Toca para cargar
|
||||||
# Message shown when Dave trial period has ended
|
# Message shown when Dave trial period has ended
|
||||||
The_Dave_Nostr_AI_assistant_trial_has_ended_____Thanks_for_testing__Zap-enabled_Dave_coming_soon_c6c7 = La prueba del asistente de IA Dave de Nostr finalizó :(. ¡Gracias por probarlo! ¡Dave con zaps estará disponible muy pronto!
|
The_Dave_Nostr_AI_assistant_trial_has_ended_____Thanks_for_testing__Zap-enabled_Dave_coming_soon_c6c7 = La prueba del asistente de IA Dave de Nostr finalizó :(. ¡Gracias por probarlo! ¡Dave con zaps estará disponible muy pronto!
|
||||||
# Label for theme, Appearance settings section
|
|
||||||
Theme_4aac = Tema:
|
|
||||||
# Column title for note thread view
|
# Column title for note thread view
|
||||||
Thread_0f20 = Conversación
|
Thread_0f20 = Conversación
|
||||||
# Link text for thread references
|
# Link text for thread references
|
||||||
thread_ad1f = conversación
|
thread_ad1f = conversación
|
||||||
# Option in settings section to show the source client label at the top of the note
|
|
||||||
Top_6aeb = Parte superior
|
|
||||||
# Title for universe column
|
# Title for universe column
|
||||||
Universe_e01e = Universo
|
Universe_e01e = Universo
|
||||||
# Column title for universe feed
|
# Column title for universe feed
|
||||||
@@ -375,8 +339,6 @@ Use_this_wallet_for_the_current_account_only_61dc = Usar esta billetera solo par
|
|||||||
username___at___domain___will_be_used_for_identification_a4fd = Se utilizará "{ $username }" en "{ $domain }" para la identificación
|
username___at___domain___will_be_used_for_identification_a4fd = Se utilizará "{ $username }" en "{ $domain }" para la identificación
|
||||||
# Profile username field label
|
# Profile username field label
|
||||||
Username_daa7 = Nombre de usuario
|
Username_daa7 = Nombre de usuario
|
||||||
# Label for view folder button, Storage settings section
|
|
||||||
View_folder_9742 = Ver carpeta
|
|
||||||
# Column title for wallet management
|
# Column title for wallet management
|
||||||
Wallet_5e50 = Billetera
|
Wallet_5e50 = Billetera
|
||||||
# Hint for deck name input field
|
# Hint for deck name input field
|
||||||
@@ -395,8 +357,6 @@ Your_Notifications_080d = Tus notificaciones
|
|||||||
Zap_16b4 = Zap
|
Zap_16b4 = Zap
|
||||||
# Hover text for zap button
|
# Hover text for zap button
|
||||||
Zap_this_note_42b2 = Enviar un zap a esta nota
|
Zap_this_note_42b2 = Enviar un zap a esta nota
|
||||||
# Label for zoom level, Appearance settings section
|
|
||||||
Zoom_Level_29a8 = Nivel de zoom:
|
|
||||||
|
|
||||||
# Pluralized strings
|
# Pluralized strings
|
||||||
|
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ Algo_2452 = Algo
|
|||||||
Algorithmic_feeds_to_aid_in_note_discovery_d344 = Feeds algorítmicos para ayudar en el descubrimiento de notas
|
Algorithmic_feeds_to_aid_in_note_discovery_d344 = Feeds algorítmicos para ayudar en el descubrimiento de notas
|
||||||
# Label for zap amount input field
|
# Label for zap amount input field
|
||||||
Amount_70f0 = Cantidad
|
Amount_70f0 = Cantidad
|
||||||
# Label for appearance settings section
|
|
||||||
Appearance_4c7f = Aspecto
|
|
||||||
# Button to send message to Dave AI assistant
|
# Button to send message to Dave AI assistant
|
||||||
Ask_b7f4 = Preguntar
|
Ask_b7f4 = Preguntar
|
||||||
# Placeholder text for Dave AI input field
|
# Placeholder text for Dave AI input field
|
||||||
@@ -55,26 +53,16 @@ Ask_dave_anything_33d1 = Pregúntale cualquier cosa a Dave...
|
|||||||
Banner_52ef = Banner
|
Banner_52ef = Banner
|
||||||
# Beta version label
|
# Beta version label
|
||||||
BETA_8e5d = BETA
|
BETA_8e5d = BETA
|
||||||
# Option in settings section to show the source client label at the bottom of the note
|
|
||||||
Bottom_33c8 = Parte inferior
|
|
||||||
# Broadcast the note to all connected relays
|
# Broadcast the note to all connected relays
|
||||||
Broadcast_fe43 = Transmitir
|
Broadcast_fe43 = Transmitir
|
||||||
# Broadcast the note only to local network relays
|
# Broadcast the note only to local network relays
|
||||||
Broadcast_Local_7e50 = Transmitir localmente
|
Broadcast_Local_7e50 = Transmitir localmente
|
||||||
# Button label to cancel an action
|
# Button label to cancel an action
|
||||||
Cancel_ed3b = Cancelar
|
Cancel_ed3b = Cancelar
|
||||||
# Label for cancel clear cache, Storage settings section
|
|
||||||
Cancel_fd8b = Cancelar
|
|
||||||
# Label for clear cache button, Storage settings section
|
|
||||||
Clear_cache_dccb = Limpiar caché
|
|
||||||
# Hover text for editable zap amount
|
# Hover text for editable zap amount
|
||||||
Click_to_edit_0414 = Haz clic para editar
|
Click_to_edit_0414 = Haz clic para editar
|
||||||
# Column title for note composition
|
# Column title for note composition
|
||||||
Compose_Note_c094 = Redactar nota
|
Compose_Note_c094 = Redactar nota
|
||||||
# Label for configure relays, settings section
|
|
||||||
Configure_relays_d156 = Configurar relés
|
|
||||||
# Label for confirm clear cache, Storage settings section
|
|
||||||
Confirm_9d9d = Confirmar
|
|
||||||
# Button label to confirm an action
|
# Button label to confirm an action
|
||||||
Confirm_f8a6 = Confirmar
|
Confirm_f8a6 = Confirmar
|
||||||
# Status label for connected relay
|
# Status label for connected relay
|
||||||
@@ -123,8 +111,6 @@ Custom_a69e = Personalizado
|
|||||||
Customize_Zap_Amount_cfc4 = Personalizar cantidad de zap
|
Customize_Zap_Amount_cfc4 = Personalizar cantidad de zap
|
||||||
# Column title for support page
|
# Column title for support page
|
||||||
Damus_Support_27c0 = Ayuda de Damus
|
Damus_Support_27c0 = Ayuda de Damus
|
||||||
# Label for Theme Dark, Appearance settings section
|
|
||||||
Dark_85fe = Oscuro
|
|
||||||
# Label for deck name input field
|
# Label for deck name input field
|
||||||
Deck_name_cd32 = Nombre del deck
|
Deck_name_cd32 = Nombre del deck
|
||||||
# Label for decks section in side panel
|
# Label for decks section in side panel
|
||||||
@@ -165,14 +151,10 @@ Enter_your_public_key__npub___nostr_address__e_g___address____or_private_key__ns
|
|||||||
Find_User_bd12 = Buscar usuario
|
Find_User_bd12 = Buscar usuario
|
||||||
# Title for hashtags column
|
# Title for hashtags column
|
||||||
Hashtags_f8e0 = Hashtags
|
Hashtags_f8e0 = Hashtags
|
||||||
# Option in settings section to hide the source client label in note display
|
|
||||||
Hide_281d = Ocultar
|
|
||||||
# Title for Home column
|
# Title for Home column
|
||||||
Home_8c19 = Inicio
|
Home_8c19 = Inicio
|
||||||
# Label for deck icon selection
|
# Label for deck icon selection
|
||||||
Icon_b0ab = Icono
|
Icon_b0ab = Icono
|
||||||
# Label for Image cache size, Storage settings section
|
|
||||||
Image_cache_size_3004 = Tamaño de caché de imágenes:
|
|
||||||
# Title for individual user column
|
# Title for individual user column
|
||||||
Individual_b776 = Individual
|
Individual_b776 = Individual
|
||||||
# Error message for invalid zap amount
|
# Error message for invalid zap amount
|
||||||
@@ -193,12 +175,8 @@ k_50K_c2dc = 50.000
|
|||||||
k_5K_f7e6 = 5.000
|
k_5K_f7e6 = 5.000
|
||||||
# Description for your notes column
|
# Description for your notes column
|
||||||
Keep_track_of_your_notes___replies_a334 = Haz seguimiento de tus notas y respuestas
|
Keep_track_of_your_notes___replies_a334 = Haz seguimiento de tus notas y respuestas
|
||||||
# Label for language, Appearance settings section
|
|
||||||
Language_e264 = Idioma:
|
|
||||||
# Title for last note per user column
|
# Title for last note per user column
|
||||||
Last_Note_per_User_17ad = Última nota por usuario
|
Last_Note_per_User_17ad = Última nota por usuario
|
||||||
# Label for Theme Light, Appearance settings section
|
|
||||||
Light_7475 = Claro
|
|
||||||
# Bitcoin Lightning network address field label
|
# Bitcoin Lightning network address field label
|
||||||
Lightning_network_address__lud16_ea51 = Dirección de la red Lightning (lud16)
|
Lightning_network_address__lud16_ea51 = Dirección de la red Lightning (lud16)
|
||||||
# Login page title
|
# Login page title
|
||||||
@@ -241,8 +219,6 @@ now_2181 = ahora
|
|||||||
Open_Email_25e9 = Abrir correo electrónico
|
Open_Email_25e9 = Abrir correo electrónico
|
||||||
# Instruction to open email client
|
# Instruction to open email client
|
||||||
Open_your_default_email_client_to_get_help_from_the_Damus_team_68dc = Abre tu cliente de correo predeterminado para recibir ayuda del equipo de Damus
|
Open_your_default_email_client_to_get_help_from_the_Damus_team_68dc = Abre tu cliente de correo predeterminado para recibir ayuda del equipo de Damus
|
||||||
# Label for others settings section
|
|
||||||
Others_7267 = Otros
|
|
||||||
# Placeholder text for NWC URI input
|
# Placeholder text for NWC URI input
|
||||||
Paste_your_NWC_URI_here_b471 = Pega tu NWC URI aquí...
|
Paste_your_NWC_URI_here_b471 = Pega tu NWC URI aquí...
|
||||||
# Error message for missing deck name
|
# Error message for missing deck name
|
||||||
@@ -289,8 +265,6 @@ replying_to_a_note_e0bc = respondiendo a una nota
|
|||||||
Repost_this_note_8e56 = Volver a publicar esta nota
|
Repost_this_note_8e56 = Volver a publicar esta nota
|
||||||
# Label for reposted notes
|
# Label for reposted notes
|
||||||
Reposted_61c8 = Publicadas de nuevo
|
Reposted_61c8 = Publicadas de nuevo
|
||||||
# Label for reset zoom level, Appearance settings section
|
|
||||||
Reset_62d4 = Restablecer
|
|
||||||
# Heading for support section
|
# Heading for support section
|
||||||
Running_into_a_bug_1796 = ¿Has encontrado un error?
|
Running_into_a_bug_1796 = ¿Has encontrado un error?
|
||||||
# Label for satoshis (Bitcoin unit) for custom zap amount input field
|
# Label for satoshis (Bitcoin unit) for custom zap amount input field
|
||||||
@@ -313,10 +287,6 @@ See_notes_from_your_contacts_ac16 = Ver notas de tus contactos
|
|||||||
See_the_whole_nostr_universe_7694 = Ver todo el universo de nostr
|
See_the_whole_nostr_universe_7694 = Ver todo el universo de nostr
|
||||||
# Button label to send a zap
|
# Button label to send a zap
|
||||||
Send_1ea4 = Enviar
|
Send_1ea4 = Enviar
|
||||||
# Column title for app settings
|
|
||||||
Settings_7a4f = Configuración
|
|
||||||
# Label for Show source client, others settings section
|
|
||||||
Show_source_client_9e31 = Mostrar cliente de origen
|
|
||||||
# Description for last note per user column
|
# Description for last note per user column
|
||||||
Show_the_last_note_for_each_user_from_a_list_50e7 = Mostrar la última nota para cada usuario de una lista
|
Show_the_last_note_for_each_user_from_a_list_50e7 = Mostrar la última nota para cada usuario de una lista
|
||||||
# Button label to sign out of account
|
# Button label to sign out of account
|
||||||
@@ -343,8 +313,6 @@ Stay_up_to_date_with_your_notifications_and_mentions_e73e = Mantente al día con
|
|||||||
Step_1_8656 = Paso 1
|
Step_1_8656 = Paso 1
|
||||||
# Step 2 label in support instructions
|
# Step 2 label in support instructions
|
||||||
Step_2_d08d = Paso 2
|
Step_2_d08d = Paso 2
|
||||||
# Label for storage settings section
|
|
||||||
Storage_ed65 = Almacenamiento
|
|
||||||
# Column title for subscribing to external user
|
# Column title for subscribing to external user
|
||||||
Subscribe_to_someone_else_s_notes_d1e9 = Suscribirse a las notas de otra persona
|
Subscribe_to_someone_else_s_notes_d1e9 = Suscribirse a las notas de otra persona
|
||||||
# Column title for subscribing to individual user
|
# Column title for subscribing to individual user
|
||||||
@@ -357,14 +325,10 @@ Switch_to_light_mode_72ce = Cambiar a modo claro
|
|||||||
Tap_to_Load_4b05 = Toca para cargar
|
Tap_to_Load_4b05 = Toca para cargar
|
||||||
# Message shown when Dave trial period has ended
|
# Message shown when Dave trial period has ended
|
||||||
The_Dave_Nostr_AI_assistant_trial_has_ended_____Thanks_for_testing__Zap-enabled_Dave_coming_soon_c6c7 = La prueba del asistente de IA Dave de Nostr ha finalizado :(. ¡Gracias por probarlo! ¡Dave con zaps estará disponible muy pronto!
|
The_Dave_Nostr_AI_assistant_trial_has_ended_____Thanks_for_testing__Zap-enabled_Dave_coming_soon_c6c7 = La prueba del asistente de IA Dave de Nostr ha finalizado :(. ¡Gracias por probarlo! ¡Dave con zaps estará disponible muy pronto!
|
||||||
# Label for theme, Appearance settings section
|
|
||||||
Theme_4aac = Tema:
|
|
||||||
# Column title for note thread view
|
# Column title for note thread view
|
||||||
Thread_0f20 = Conversación
|
Thread_0f20 = Conversación
|
||||||
# Link text for thread references
|
# Link text for thread references
|
||||||
thread_ad1f = conversación
|
thread_ad1f = conversación
|
||||||
# Option in settings section to show the source client label at the top of the note
|
|
||||||
Top_6aeb = Parte superior
|
|
||||||
# Title for universe column
|
# Title for universe column
|
||||||
Universe_e01e = Universo
|
Universe_e01e = Universo
|
||||||
# Column title for universe feed
|
# Column title for universe feed
|
||||||
@@ -375,8 +339,6 @@ Use_this_wallet_for_the_current_account_only_61dc = Usar este monedero solo para
|
|||||||
username___at___domain___will_be_used_for_identification_a4fd = Se utilizará "{ $username }" en "{ $domain }" para la identificación
|
username___at___domain___will_be_used_for_identification_a4fd = Se utilizará "{ $username }" en "{ $domain }" para la identificación
|
||||||
# Profile username field label
|
# Profile username field label
|
||||||
Username_daa7 = Nombre de usuario
|
Username_daa7 = Nombre de usuario
|
||||||
# Label for view folder button, Storage settings section
|
|
||||||
View_folder_9742 = Ver carpeta
|
|
||||||
# Column title for wallet management
|
# Column title for wallet management
|
||||||
Wallet_5e50 = Monedero
|
Wallet_5e50 = Monedero
|
||||||
# Hint for deck name input field
|
# Hint for deck name input field
|
||||||
@@ -395,8 +357,6 @@ Your_Notifications_080d = Tus notificaciones
|
|||||||
Zap_16b4 = Zap
|
Zap_16b4 = Zap
|
||||||
# Hover text for zap button
|
# Hover text for zap button
|
||||||
Zap_this_note_42b2 = Enviar un zap a esta nota
|
Zap_this_note_42b2 = Enviar un zap a esta nota
|
||||||
# Label for zoom level, Appearance settings section
|
|
||||||
Zoom_Level_29a8 = Nivel de zoom:
|
|
||||||
|
|
||||||
# Pluralized strings
|
# Pluralized strings
|
||||||
|
|
||||||
|
|||||||
@@ -376,7 +376,7 @@ username___at___domain___will_be_used_for_identification_a4fd = "{ $username }"
|
|||||||
# Profile username field label
|
# Profile username field label
|
||||||
Username_daa7 = Nom d'utilisateur
|
Username_daa7 = Nom d'utilisateur
|
||||||
# Label for view folder button, Storage settings section
|
# Label for view folder button, Storage settings section
|
||||||
View_folder_9742 = Voir le dossier
|
View_folder_9742 = Voir le dossier :
|
||||||
# Column title for wallet management
|
# Column title for wallet management
|
||||||
Wallet_5e50 = Portefeuille
|
Wallet_5e50 = Portefeuille
|
||||||
# Hint for deck name input field
|
# Hint for deck name input field
|
||||||
|
|||||||
@@ -376,7 +376,7 @@ username___at___domain___will_be_used_for_identification_a4fd = d = "{ $username
|
|||||||
# Profile username field label
|
# Profile username field label
|
||||||
Username_daa7 = Usuário
|
Username_daa7 = Usuário
|
||||||
# Label for view folder button, Storage settings section
|
# Label for view folder button, Storage settings section
|
||||||
View_folder_9742 = Visualizar pasta
|
View_folder_9742 = Visualizar pasta:
|
||||||
# Column title for wallet management
|
# Column title for wallet management
|
||||||
Wallet_5e50 = Carteira
|
Wallet_5e50 = Carteira
|
||||||
# Hint for deck name input field
|
# Hint for deck name input field
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ username___at___domain___will_be_used_for_identification_a4fd = "{ $username }"
|
|||||||
# Profile username field label
|
# Profile username field label
|
||||||
Username_daa7 = ชื่อผู้ใช้
|
Username_daa7 = ชื่อผู้ใช้
|
||||||
# Label for view folder button, Storage settings section
|
# Label for view folder button, Storage settings section
|
||||||
View_folder_9742 = ดูโฟลเดอร์
|
View_folder_9742 = ดูโฟลเดอร์:
|
||||||
# Column title for wallet management
|
# Column title for wallet management
|
||||||
Wallet_5e50 = วอลเล็ต
|
Wallet_5e50 = วอลเล็ต
|
||||||
# Hint for deck name input field
|
# Hint for deck name input field
|
||||||
|
|||||||
@@ -376,7 +376,7 @@ username___at___domain___will_be_used_for_identification_a4fd = "{ $username }"
|
|||||||
# Profile username field label
|
# Profile username field label
|
||||||
Username_daa7 = 用户名
|
Username_daa7 = 用户名
|
||||||
# Label for view folder button, Storage settings section
|
# Label for view folder button, Storage settings section
|
||||||
View_folder_9742 = 查看文件夹
|
View_folder_9742 = 查看文件夹:
|
||||||
# Column title for wallet management
|
# Column title for wallet management
|
||||||
Wallet_5e50 = 钱包
|
Wallet_5e50 = 钱包
|
||||||
# Hint for deck name input field
|
# Hint for deck name input field
|
||||||
|
|||||||
@@ -376,7 +376,7 @@ username___at___domain___will_be_used_for_identification_a4fd = "{ $username }"
|
|||||||
# Profile username field label
|
# Profile username field label
|
||||||
Username_daa7 = 用戶名
|
Username_daa7 = 用戶名
|
||||||
# Label for view folder button, Storage settings section
|
# Label for view folder button, Storage settings section
|
||||||
View_folder_9742 = 查看文件夾
|
View_folder_9742 = 查看文件夾:
|
||||||
# Column title for wallet management
|
# Column title for wallet management
|
||||||
Wallet_5e50 = 錢包
|
Wallet_5e50 = 錢包
|
||||||
# Hint for deck name input field
|
# Hint for deck name input field
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ fluent = { workspace = true }
|
|||||||
fluent-resmgr = { workspace = true }
|
fluent-resmgr = { workspace = true }
|
||||||
fluent-langneg = { workspace = true }
|
fluent-langneg = { workspace = true }
|
||||||
unic-langid = { workspace = true }
|
unic-langid = { workspace = true }
|
||||||
|
sys-locale = { workspace = true }
|
||||||
once_cell = { workspace = true }
|
once_cell = { workspace = true }
|
||||||
md5 = { workspace = true }
|
md5 = { workspace = true }
|
||||||
bitflags = { workspace = true }
|
bitflags = { workspace = true }
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use fluent::{FluentArgs, FluentBundle, FluentResource};
|
|||||||
use fluent_langneg::negotiate_languages;
|
use fluent_langneg::negotiate_languages;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use sys_locale;
|
||||||
use unic_langid::{langid, LanguageIdentifier};
|
use unic_langid::{langid, LanguageIdentifier};
|
||||||
|
|
||||||
const EN_US: LanguageIdentifier = langid!("en-US");
|
const EN_US: LanguageIdentifier = langid!("en-US");
|
||||||
@@ -101,10 +102,6 @@ pub struct Localization {
|
|||||||
|
|
||||||
impl Default for Localization {
|
impl Default for Localization {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
// Default to English (US)
|
|
||||||
let default_locale = &EN_US;
|
|
||||||
let fallback_locale = default_locale.to_owned();
|
|
||||||
|
|
||||||
// Build available locales list
|
// Build available locales list
|
||||||
let available_locales = vec![
|
let available_locales = vec![
|
||||||
EN_US.clone(),
|
EN_US.clone(),
|
||||||
@@ -132,8 +129,20 @@ impl Default for Localization {
|
|||||||
(ZH_TW, ZH_TW_NATIVE_NAME.to_owned()),
|
(ZH_TW, ZH_TW_NATIVE_NAME.to_owned()),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Detect system locale and find best match
|
||||||
|
let current_locale = Self::negotiate_system_locale_with_preferences(&available_locales);
|
||||||
|
|
||||||
|
// Fallback locale is always EN_US
|
||||||
|
let fallback_locale = EN_US.clone();
|
||||||
|
|
||||||
|
tracing::info!(
|
||||||
|
"Localization initialized - Selected locale: {}, Fallback: {}",
|
||||||
|
current_locale,
|
||||||
|
fallback_locale
|
||||||
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
current_locale: default_locale.to_owned(),
|
current_locale,
|
||||||
available_locales,
|
available_locales,
|
||||||
fallback_locale,
|
fallback_locale,
|
||||||
locale_native_names,
|
locale_native_names,
|
||||||
@@ -159,6 +168,150 @@ impl Localization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extract just the language and region from locale string (e.g., "fr-FR-u-mu-celsius" -> "fr-FR")
|
||||||
|
fn extract_language_region(locale_str: &str) -> String {
|
||||||
|
// Split by '-' and analyze the parts
|
||||||
|
let parts: Vec<&str> = locale_str.split('-').collect();
|
||||||
|
|
||||||
|
if parts.len() >= 2 {
|
||||||
|
// Check if the second part looks like a region
|
||||||
|
let second_part = parts[1];
|
||||||
|
if (second_part.len() >= 2) {
|
||||||
|
format!("{}-{}", parts[0], parts[1])
|
||||||
|
} else {
|
||||||
|
// Second part is not a region, probably an extension (e.g., "u", "t", "x")
|
||||||
|
// Just return the language part
|
||||||
|
parts[0].to_string()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Only one part, return as is
|
||||||
|
locale_str.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Negotiate the best locale from all system preferences against available locales
|
||||||
|
fn negotiate_system_locale_with_preferences(
|
||||||
|
available_locales: &[LanguageIdentifier],
|
||||||
|
) -> LanguageIdentifier {
|
||||||
|
// Get all system preferred locales in descending order
|
||||||
|
let mut system_locales: Vec<String> = sys_locale::get_locales().collect();
|
||||||
|
if system_locales.is_empty() {
|
||||||
|
tracing::info!("No system locales detected, using fallback: en-US");
|
||||||
|
return EN_US.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracing::info!("System preferred locales: {:?}", system_locales);
|
||||||
|
|
||||||
|
// If we only got one locale, it might be that the system only returns the primary locale
|
||||||
|
// In this case, we can try to add common fallbacks based on the detected locale
|
||||||
|
if system_locales.len() == 1 {
|
||||||
|
let primary = &system_locales[0];
|
||||||
|
|
||||||
|
// Try to parse the primary locale, handling extensions
|
||||||
|
let primary_lang = if let Ok(locale) = primary.parse::<LanguageIdentifier>() {
|
||||||
|
locale.language.as_str().to_string()
|
||||||
|
} else {
|
||||||
|
// If parsing fails, try extracting language-region
|
||||||
|
// let stripped = Self::extract_language_region(primary);
|
||||||
|
// if let Ok(locale) = stripped.parse::<LanguageIdentifier>() {
|
||||||
|
// locale.language.as_str().to_string()
|
||||||
|
// } else {
|
||||||
|
tracing::info!("Could not parse primary locale: {}", primary);
|
||||||
|
"unknown".to_string()
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
tracing::info!(
|
||||||
|
"Only one system locale detected: {} (language: {})",
|
||||||
|
primary,
|
||||||
|
primary_lang
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add common fallbacks for the detected language
|
||||||
|
match primary_lang.as_str() {
|
||||||
|
"uk" => {
|
||||||
|
// For Ukrainian, add common fallbacks
|
||||||
|
system_locales.push("es-ES".to_string());
|
||||||
|
system_locales.push("en-US".to_string());
|
||||||
|
tracing::info!("Added fallbacks for Ukrainian: {:?}", system_locales);
|
||||||
|
}
|
||||||
|
"es" => {
|
||||||
|
// For Spanish, add English fallback
|
||||||
|
system_locales.push("en-US".to_string());
|
||||||
|
tracing::info!("Added fallback for Spanish: {:?}", system_locales);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// For other languages, add English fallback
|
||||||
|
system_locales.push("en-US".to_string());
|
||||||
|
tracing::info!("Added fallback for {}: {:?}", primary_lang, system_locales);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert system locale strings to LanguageIdentifiers, handling extensions
|
||||||
|
let mut parsed_system_locales = Vec::new();
|
||||||
|
for locale_str in system_locales {
|
||||||
|
// Try to parse the locale string directly first
|
||||||
|
if let Ok(locale) = locale_str.parse::<LanguageIdentifier>() {
|
||||||
|
parsed_system_locales.push(locale);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If parsing fails, try extracting just language-region
|
||||||
|
// let stripped_locale = Self::extract_language_region(&locale_str);
|
||||||
|
// if let Ok(locale) = stripped_locale.parse::<LanguageIdentifier>() {
|
||||||
|
// parsed_system_locales.push(locale);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
tracing::info!("Failed to parse locale string: {}", locale_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
if parsed_system_locales.is_empty() {
|
||||||
|
tracing::info!("No valid system locales parsed, using fallback: en-US");
|
||||||
|
return EN_US.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
// First try exact matches with fluent_langneg
|
||||||
|
let fallback = &EN_US;
|
||||||
|
let negotiated = negotiate_languages(
|
||||||
|
&parsed_system_locales,
|
||||||
|
available_locales,
|
||||||
|
Some(fallback),
|
||||||
|
fluent_langneg::NegotiationStrategy::Filtering,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(result) = negotiated.first() {
|
||||||
|
tracing::info!(
|
||||||
|
"Exact match found: {} from preferences: {:?}",
|
||||||
|
result,
|
||||||
|
parsed_system_locales
|
||||||
|
);
|
||||||
|
return (*result).clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no exact match, try language-only fallbacks
|
||||||
|
tracing::info!("No exact matches found, trying language-only fallbacks");
|
||||||
|
for system_locale in &parsed_system_locales {
|
||||||
|
let system_lang = system_locale.language.as_str();
|
||||||
|
|
||||||
|
// Look for any available locale with the same language
|
||||||
|
for available_locale in available_locales {
|
||||||
|
if available_locale.language.as_str() == system_lang {
|
||||||
|
tracing::debug!(
|
||||||
|
"Language match found: {} (system: {})",
|
||||||
|
available_locale,
|
||||||
|
system_locale
|
||||||
|
);
|
||||||
|
return available_locale.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracing::info!("No language matches found, using fallback: en-US");
|
||||||
|
EN_US.clone()
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets a localized string by its ID
|
/// Gets a localized string by its ID
|
||||||
pub fn get_string(&mut self, id: IntlKey<'_>) -> Result<String, IntlError> {
|
pub fn get_string(&mut self, id: IntlKey<'_>) -> Result<String, IntlError> {
|
||||||
self.get_cached_string(id, None)
|
self.get_cached_string(id, None)
|
||||||
@@ -458,20 +611,6 @@ impl Localization {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Negotiates the best locale from a list of preferred locales
|
|
||||||
pub fn negotiate_locale(&self, preferred: &[LanguageIdentifier]) -> LanguageIdentifier {
|
|
||||||
let available = self.available_locales.clone();
|
|
||||||
let negotiated = negotiate_languages(
|
|
||||||
preferred,
|
|
||||||
&available,
|
|
||||||
Some(&self.fallback_locale),
|
|
||||||
fluent_langneg::NegotiationStrategy::Filtering,
|
|
||||||
);
|
|
||||||
negotiated
|
|
||||||
.first()
|
|
||||||
.map_or(self.fallback_locale.clone(), |v| (*v).clone())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Statistics about cache usage
|
/// Statistics about cache usage
|
||||||
@@ -484,6 +623,80 @@ pub struct CacheStats {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_extract_language_region() {
|
||||||
|
// Test that we extract just language and region from various locale formats
|
||||||
|
|
||||||
|
// Test locales with extensions
|
||||||
|
let unicode_locale = "fr-FR-u-mu-celsius";
|
||||||
|
let extracted = Localization::extract_language_region(unicode_locale);
|
||||||
|
assert_eq!(extracted, "fr-FR");
|
||||||
|
|
||||||
|
let transformed_locale = "en-US-t-0-abc123";
|
||||||
|
let extracted = Localization::extract_language_region(transformed_locale);
|
||||||
|
assert_eq!(extracted, "en-US");
|
||||||
|
|
||||||
|
let private_locale = "de-DE-x-phonebk";
|
||||||
|
let extracted = Localization::extract_language_region(private_locale);
|
||||||
|
assert_eq!(extracted, "de-DE");
|
||||||
|
|
||||||
|
// Test simple locale (no extensions)
|
||||||
|
let simple_locale = "en-US";
|
||||||
|
let extracted = Localization::extract_language_region(simple_locale);
|
||||||
|
assert_eq!(extracted, "en-US");
|
||||||
|
|
||||||
|
// Test language-only locale
|
||||||
|
let lang_only = "en";
|
||||||
|
let extracted = Localization::extract_language_region(lang_only);
|
||||||
|
assert_eq!(extracted, "en");
|
||||||
|
|
||||||
|
// Test language with extensions (no region)
|
||||||
|
let lang_with_extensions = "fr-u-mu-celsius";
|
||||||
|
let extracted = Localization::extract_language_region(lang_with_extensions);
|
||||||
|
assert_eq!(extracted, "fr");
|
||||||
|
|
||||||
|
// Test language with other extension types (no region)
|
||||||
|
let lang_with_t_ext = "en-t-0-abc123";
|
||||||
|
let extracted = Localization::extract_language_region(lang_with_t_ext);
|
||||||
|
assert_eq!(extracted, "en");
|
||||||
|
|
||||||
|
let lang_with_x_ext = "de-x-phonebk";
|
||||||
|
let extracted = Localization::extract_language_region(lang_with_x_ext);
|
||||||
|
assert_eq!(extracted, "de");
|
||||||
|
|
||||||
|
// Test locale with numeric region code
|
||||||
|
let numeric_region = "es-419-u-mu-celsius";
|
||||||
|
let extracted = Localization::extract_language_region(numeric_region);
|
||||||
|
assert_eq!(extracted, "es-419");
|
||||||
|
|
||||||
|
// Test locale with 3-letter region code
|
||||||
|
let three_letter_region = "en-USA-t-0-abc123";
|
||||||
|
let extracted = Localization::extract_language_region(three_letter_region);
|
||||||
|
assert_eq!(extracted, "en-USA");
|
||||||
|
|
||||||
|
// Test locale with 2-letter region code
|
||||||
|
let two_letter_region = "fr-FR-u-mu-celsius";
|
||||||
|
let extracted = Localization::extract_language_region(two_letter_region);
|
||||||
|
assert_eq!(extracted, "fr-FR");
|
||||||
|
|
||||||
|
// Test complex locale with multiple parts
|
||||||
|
let complex_locale = "zh-CN-u-ca-chinese-x-private";
|
||||||
|
let extracted = Localization::extract_language_region(complex_locale);
|
||||||
|
assert_eq!(extracted, "zh-CN");
|
||||||
|
|
||||||
|
// Verify that extracted locales can be parsed
|
||||||
|
let test_cases = ["fr-FR", "en-US", "de-DE", "en", "zh-CN"];
|
||||||
|
for extracted in test_cases {
|
||||||
|
if let Ok(locale) = extracted.parse::<LanguageIdentifier>() {
|
||||||
|
tracing::info!("Successfully parsed extracted locale: {}", locale);
|
||||||
|
} else {
|
||||||
|
tracing::error!("Failed to parse extracted locale: {}", extracted);
|
||||||
|
panic!("Should parse locale after extraction");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// TODO(jb55): write tests that work, i broke all these during the refacto
|
// TODO(jb55): write tests that work, i broke all these during the refacto
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ use crate::{nav::RouterAction, Damus, Route};
|
|||||||
|
|
||||||
const PREVIEW_NOTE_ID: &str = "note1edjc8ggj07hwv77g2405uh6j2jkk5aud22gktxrvc2wnre4vdwgqzlv2gw";
|
const PREVIEW_NOTE_ID: &str = "note1edjc8ggj07hwv77g2405uh6j2jkk5aud22gktxrvc2wnre4vdwgqzlv2gw";
|
||||||
|
|
||||||
|
const THEME_LIGHT: &str = "Light";
|
||||||
|
const THEME_DARK: &str = "Dark";
|
||||||
|
|
||||||
const MIN_ZOOM: f32 = 0.5;
|
const MIN_ZOOM: f32 = 0.5;
|
||||||
const MAX_ZOOM: f32 = 3.0;
|
const MAX_ZOOM: f32 = 3.0;
|
||||||
const ZOOM_STEP: f32 = 0.1;
|
const ZOOM_STEP: f32 = 0.1;
|
||||||
@@ -386,7 +389,7 @@ impl<'a> SettingsView<'a> {
|
|||||||
ThemePreference::Light,
|
ThemePreference::Light,
|
||||||
richtext_small(tr!(
|
richtext_small(tr!(
|
||||||
self.note_context.i18n,
|
self.note_context.i18n,
|
||||||
"Light",
|
THEME_LIGHT,
|
||||||
"Label for Theme Light, Appearance settings section",
|
"Label for Theme Light, Appearance settings section",
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
@@ -401,7 +404,7 @@ impl<'a> SettingsView<'a> {
|
|||||||
ThemePreference::Dark,
|
ThemePreference::Dark,
|
||||||
richtext_small(tr!(
|
richtext_small(tr!(
|
||||||
self.note_context.i18n,
|
self.note_context.i18n,
|
||||||
"Dark",
|
THEME_DARK,
|
||||||
"Label for Theme Dark, Appearance settings section",
|
"Label for Theme Dark, Appearance settings section",
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
@@ -529,18 +532,14 @@ impl<'a> SettingsView<'a> {
|
|||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.label(richtext_small(tr!(
|
ui.label(richtext_small(tr!(
|
||||||
self.note_context.i18n,
|
self.note_context.i18n,
|
||||||
"Sort replies newest first:",
|
"Sort replies newest first",
|
||||||
"Label for Sort replies newest first, others settings section",
|
"Label for Sort replies newest first, others settings section",
|
||||||
)));
|
)));
|
||||||
|
|
||||||
if ui
|
if ui
|
||||||
.toggle_value(
|
.toggle_value(
|
||||||
&mut self.settings.show_replies_newest_first,
|
&mut self.settings.show_replies_newest_first,
|
||||||
RichText::new(tr!(
|
RichText::new(tr!(self.note_context.i18n, "ON", "ON"))
|
||||||
self.note_context.i18n,
|
|
||||||
"On",
|
|
||||||
"Setting to turn on sorting replies so that the newest are shown first"
|
|
||||||
))
|
|
||||||
.text_style(NotedeckTextStyle::Small.text_style()),
|
.text_style(NotedeckTextStyle::Small.text_style()),
|
||||||
)
|
)
|
||||||
.changed()
|
.changed()
|
||||||
@@ -554,7 +553,7 @@ impl<'a> SettingsView<'a> {
|
|||||||
ui.horizontal_wrapped(|ui| {
|
ui.horizontal_wrapped(|ui| {
|
||||||
ui.label(richtext_small(tr!(
|
ui.label(richtext_small(tr!(
|
||||||
self.note_context.i18n,
|
self.note_context.i18n,
|
||||||
"Source client:",
|
"Source client",
|
||||||
"Label for Source client, others settings section",
|
"Label for Source client, others settings section",
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user