remove i18n crate (#213)

This commit is contained in:
reya
2025-12-31 09:23:59 +07:00
committed by GitHub
parent 0507fa7ac5
commit bb455871e5
20 changed files with 138 additions and 748 deletions

155
Cargo.lock generated
View File

@@ -125,15 +125,6 @@ version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
[[package]]
name = "arc-swap"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d03449bb8ca2cc2ef70869af31463d1ae5ccc8fa3e334b307203fbf815207e"
dependencies = [
"rustversion",
]
[[package]] [[package]]
name = "arg_enum_proc_macro" name = "arg_enum_proc_macro"
version = "0.3.4" version = "0.3.4"
@@ -625,12 +616,6 @@ dependencies = [
"fs_extra", "fs_extra",
] ]
[[package]]
name = "base62"
version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1adf9755786e27479693dedd3271691a92b5e242ab139cacb9fb8e7fb5381111"
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.22.1" version = "0.22.1"
@@ -1335,7 +1320,6 @@ dependencies = [
"futures", "futures",
"gpui", "gpui",
"gpui_tokio", "gpui_tokio",
"i18n",
"indexset", "indexset",
"itertools 0.13.0", "itertools 0.13.0",
"key_store", "key_store",
@@ -1346,7 +1330,6 @@ dependencies = [
"person", "person",
"relay_auth", "relay_auth",
"reqwest_client", "reqwest_client",
"rust-i18n",
"serde", "serde",
"serde_json", "serde_json",
"settings", "settings",
@@ -2518,17 +2501,6 @@ dependencies = [
"regex-syntax", "regex-syntax",
] ]
[[package]]
name = "globwalk"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc"
dependencies = [
"bitflags 1.3.2",
"ignore",
"walkdir",
]
[[package]] [[package]]
name = "gloo-timers" name = "gloo-timers"
version = "0.3.0" version = "0.3.0"
@@ -3037,13 +3009,6 @@ dependencies = [
"windows-registry 0.6.1", "windows-registry 0.6.1",
] ]
[[package]]
name = "i18n"
version = "0.3.0"
dependencies = [
"rust-i18n",
]
[[package]] [[package]]
name = "iana-time-zone" name = "iana-time-zone"
version = "0.1.64" version = "0.1.64"
@@ -3170,22 +3135,6 @@ dependencies = [
"icu_properties", "icu_properties",
] ]
[[package]]
name = "ignore"
version = "0.4.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a"
dependencies = [
"crossbeam-deque",
"globset",
"log",
"memchr",
"regex-automata",
"same-file",
"walkdir",
"winapi-util",
]
[[package]] [[package]]
name = "image" name = "image"
version = "0.25.9" version = "0.25.9"
@@ -3339,15 +3288,6 @@ dependencies = [
"once_cell", "once_cell",
] ]
[[package]]
name = "itertools"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
dependencies = [
"either",
]
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.13.0" version = "0.13.0"
@@ -3975,15 +3915,6 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
[[package]]
name = "normpath"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf23ab2b905654b4cb177e30b629937b3868311d4e1cba859f899c041046e69b"
dependencies = [
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "nostr" name = "nostr"
version = "0.44.1" version = "0.44.1"
@@ -5432,60 +5363,6 @@ dependencies = [
"walkdir", "walkdir",
] ]
[[package]]
name = "rust-i18n"
version = "3.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fda2551fdfaf6cc5ee283adc15e157047b92ae6535cf80f6d4962d05717dc332"
dependencies = [
"globwalk",
"once_cell",
"regex",
"rust-i18n-macro",
"rust-i18n-support",
"smallvec",
]
[[package]]
name = "rust-i18n-macro"
version = "3.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22baf7d7f56656d23ebe24f6bb57a5d40d2bce2a5f1c503e692b5b2fa450f965"
dependencies = [
"glob",
"once_cell",
"proc-macro2",
"quote",
"rust-i18n-support",
"serde",
"serde_json",
"serde_yaml",
"syn 2.0.111",
]
[[package]]
name = "rust-i18n-support"
version = "3.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "940ed4f52bba4c0152056d771e563b7133ad9607d4384af016a134b58d758f19"
dependencies = [
"arc-swap",
"base62",
"globwalk",
"itertools 0.11.0",
"lazy_static",
"normpath",
"once_cell",
"proc-macro2",
"regex",
"serde",
"serde_json",
"serde_yaml",
"siphasher",
"toml 0.8.23",
"triomphe",
]
[[package]] [[package]]
name = "rust-ini" name = "rust-ini"
version = "0.17.0" version = "0.17.0"
@@ -5971,19 +5848,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serde_yaml"
version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap",
"itoa",
"ryu",
"serde",
"unsafe-libyaml",
]
[[package]] [[package]]
name = "settings" name = "settings"
version = "0.3.0" version = "0.3.0"
@@ -6713,11 +6577,9 @@ dependencies = [
"anyhow", "anyhow",
"common", "common",
"gpui", "gpui",
"i18n",
"linicon", "linicon",
"log", "log",
"nostr-sdk", "nostr-sdk",
"rust-i18n",
"smallvec", "smallvec",
"smol", "smol",
"theme", "theme",
@@ -7007,17 +6869,6 @@ dependencies = [
"tracing-log", "tracing-log",
] ]
[[package]]
name = "triomphe"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd69c5aa8f924c7519d6372789a74eac5b94fb0f8fcf0d4a97eb0bfc3e785f39"
dependencies = [
"arc-swap",
"serde",
"stable_deref_trait",
]
[[package]] [[package]]
name = "try-lock" name = "try-lock"
version = "0.2.5" version = "0.2.5"
@@ -7207,12 +7058,6 @@ dependencies = [
"subtle", "subtle",
] ]
[[package]]
name = "unsafe-libyaml"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]] [[package]]
name = "untrusted" name = "untrusted"
version = "0.9.0" version = "0.9.0"

View File

@@ -8,13 +8,7 @@ version = "0.3.0"
edition = "2021" edition = "2021"
publish = false publish = false
[workspace.metadata.i18n]
available-locales = ["en"]
default-locale = "en"
load-path = "locales"
[workspace.dependencies] [workspace.dependencies]
i18n = { path = "crates/i18n" }
# GPUI # GPUI
gpui = { git = "https://github.com/zed-industries/zed" } gpui = { git = "https://github.com/zed-industries/zed" }
@@ -36,7 +30,6 @@ oneshot = "0.1.10"
reqwest = { version = "0.12", features = ["multipart", "stream", "json"] } reqwest = { version = "0.12", features = ["multipart", "stream", "json"] }
flume = { version = "0.11.1", default-features = false, features = ["async", "select"] } flume = { version = "0.11.1", default-features = false, features = ["async", "select"] }
rust-embed = "8.5.0" rust-embed = "8.5.0"
rust-i18n = "3"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
schemars = "1" schemars = "1"

View File

@@ -44,8 +44,6 @@ encryption_ui = { path = "../encryption_ui" }
person = { path = "../person" } person = { path = "../person" }
relay_auth = { path = "../relay_auth" } relay_auth = { path = "../relay_auth" }
rust-i18n.workspace = true
i18n.workspace = true
gpui.workspace = true gpui.workspace = true
gpui_tokio.workspace = true gpui_tokio.workspace = true
reqwest_client.workspace = true reqwest_client.workspace = true

View File

@@ -13,7 +13,6 @@ use gpui::{
InteractiveElement, IntoElement, ParentElement, Render, SharedString, InteractiveElement, IntoElement, ParentElement, Render, SharedString,
StatefulInteractiveElement, Styled, Subscription, Window, StatefulInteractiveElement, Styled, Subscription, Window,
}; };
use i18n::{shared_t, t};
use key_store::{Credential, KeyItem, KeyStore}; use key_store::{Credential, KeyItem, KeyStore};
use nostr_connect::prelude::*; use nostr_connect::prelude::*;
use person::PersonRegistry; use person::PersonRegistry;
@@ -230,7 +229,7 @@ impl ChatSpace {
window.open_modal(cx, move |modal, _window, _cx| { window.open_modal(cx, move |modal, _window, _cx| {
modal modal
.title(shared_t!("common.preferences")) .title(SharedString::from("Preferences"))
.width(px(520.)) .width(px(520.))
.child(view.clone()) .child(view.clone())
}); });
@@ -291,9 +290,9 @@ impl ChatSpace {
let entity = entity.clone(); let entity = entity.clone();
this.confirm() this.confirm()
.title(shared_t!("relays.modal")) .title(SharedString::from("Set Up Messaging Relays"))
.child(view.clone()) .child(view.clone())
.button_props(ModalButtonProps::default().ok_text(t!("common.update"))) .button_props(ModalButtonProps::default().ok_text("Update"))
.on_ok(move |_, window, cx| { .on_ok(move |_, window, cx| {
entity entity
.update(cx, |this, cx| { .update(cx, |this, cx| {
@@ -397,21 +396,21 @@ impl ChatSpace {
fn on_copy_pubkey(&mut self, ev: &CopyPublicKey, window: &mut Window, cx: &mut Context<Self>) { fn on_copy_pubkey(&mut self, ev: &CopyPublicKey, window: &mut Window, cx: &mut Context<Self>) {
let Ok(bech32) = ev.0.to_bech32(); let Ok(bech32) = ev.0.to_bech32();
cx.write_to_clipboard(ClipboardItem::new_string(bech32)); cx.write_to_clipboard(ClipboardItem::new_string(bech32));
window.push_notification(t!("common.copied"), cx); window.push_notification("Copied", cx);
} }
fn on_keyring(&mut self, _ev: &KeyringPopup, window: &mut Window, cx: &mut Context<Self>) { fn on_keyring(&mut self, _ev: &KeyringPopup, window: &mut Window, cx: &mut Context<Self>) {
window.open_modal(cx, move |this, _window, _cx| { window.open_modal(cx, move |this, _window, _cx| {
this.show_close(true) this.show_close(true)
.title(shared_t!("keyring_disable.label")) .title(SharedString::from("Keyring is disabled"))
.child( .child(
v_flex() v_flex()
.gap_2() .gap_2()
.pb_4() .pb_4()
.text_sm() .text_sm()
.child(shared_t!("keyring_disable.body_1")) .child(SharedString::from("Coop cannot access the Keyring Service on your system. By design, Coop uses Keyring to store your credentials."))
.child(shared_t!("keyring_disable.body_2")) .child(SharedString::from("Without access to Keyring, Coop will store your credentials as plain text."))
.child(shared_t!("keyring_disable.body_3")), .child(SharedString::from("If you want to store your credentials in the Keyring, please enable Keyring and allow Coop to access it.")),
) )
}); });
} }
@@ -470,7 +469,9 @@ impl ChatSpace {
.text_xs() .text_xs()
.rounded_full() .rounded_full()
.bg(cx.theme().surface_background) .bg(cx.theme().surface_background)
.child(shared_t!("loading.label")), .child(SharedString::from(
"Getting messages. This may take a while...",
)),
)) ))
}) })
} }
@@ -530,7 +531,10 @@ impl ChatSpace {
.text_color(cx.theme().warning_foreground) .text_color(cx.theme().warning_foreground)
.hover(|this| this.bg(cx.theme().warning_hover)) .hover(|this| this.bg(cx.theme().warning_hover))
.active(|this| this.bg(cx.theme().warning_active)) .active(|this| this.bg(cx.theme().warning_active))
.child(shared_t!("auth.requests", u = pending_requests)) .child(SharedString::from(format!(
"You have {} pending authentication requests",
pending_requests
)))
.on_click(move |_ev, window, cx| { .on_click(move |_ev, window, cx| {
relay_auth.update(cx, |this, cx| { relay_auth.update(cx, |this, cx| {
this.re_ask(window, cx); this.re_ask(window, cx);

View File

@@ -7,7 +7,6 @@ use gpui::{
div, relative, AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle, div, relative, AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle,
Focusable, IntoElement, ParentElement, Render, SharedString, Styled, Subscription, Window, Focusable, IntoElement, ParentElement, Render, SharedString, Styled, Subscription, Window,
}; };
use i18n::{shared_t, t};
use key_store::{KeyItem, KeyStore}; use key_store::{KeyItem, KeyStore};
use nostr_connect::prelude::*; use nostr_connect::prelude::*;
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
@@ -112,7 +111,7 @@ impl Login {
fn login_with_bunker(&mut self, content: &str, window: &mut Window, cx: &mut Context<Self>) { fn login_with_bunker(&mut self, content: &str, window: &mut Window, cx: &mut Context<Self>) {
let Ok(uri) = NostrConnectUri::parse(content) else { let Ok(uri) = NostrConnectUri::parse(content) else {
self.set_error(t!("login.bunker_invalid"), cx); self.set_error("Bunker is not valid", cx);
return; return;
}; };
@@ -396,7 +395,7 @@ impl Render for Login {
}) })
.child( .child(
Button::new("login") Button::new("login")
.label(t!("common.continue")) .label("Continue")
.primary() .primary()
.loading(self.logging_in) .loading(self.logging_in)
.disabled(self.logging_in) .disabled(self.logging_in)
@@ -410,7 +409,10 @@ impl Render for Login {
.text_xs() .text_xs()
.text_center() .text_center()
.text_color(cx.theme().text_muted) .text_color(cx.theme().text_muted)
.child(shared_t!("login.approve_message", i = i)), .child(SharedString::from(format!(
"Approve connection request from your signer in {} seconds",
i
))),
) )
}) })
.when_some(self.error.read(cx).as_ref(), |this, error| { .when_some(self.error.read(cx).as_ref(), |this, error| {

View File

@@ -19,8 +19,6 @@ mod sidebar;
mod user; mod user;
mod views; mod views;
i18n::init!();
fn main() { fn main() {
// Initialize logging // Initialize logging
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();

View File

@@ -6,7 +6,6 @@ use gpui::{
Window, Window,
}; };
use gpui_tokio::Tokio; use gpui_tokio::Tokio;
use i18n::{shared_t, t};
use key_store::{KeyItem, KeyStore}; use key_store::{KeyItem, KeyStore};
use nostr_sdk::prelude::*; use nostr_sdk::prelude::*;
use settings::AppSettings; use settings::AppSettings;
@@ -68,11 +67,11 @@ impl NewAccount {
modal modal
.alert() .alert()
.title(shared_t!("new_account.backup_label")) .title(SharedString::from(
"Backup to avoid losing access to your account",
))
.child(view.clone()) .child(view.clone())
.button_props( .button_props(ModalButtonProps::default().ok_text("Download"))
ModalButtonProps::default().ok_text(t!("new_account.backup_download")),
)
.on_ok(move |_, window, cx| { .on_ok(move |_, window, cx| {
weak_view weak_view
.update(cx, |this, cx| { .update(cx, |this, cx| {
@@ -330,7 +329,7 @@ impl Render for NewAccount {
v_flex() v_flex()
.gap_1() .gap_1()
.text_sm() .text_sm()
.child(shared_t!("new_account.name")) .child(SharedString::from("What should people call you?"))
.child( .child(
TextInput::new(&self.name_input) TextInput::new(&self.name_input)
.disabled(self.submitting) .disabled(self.submitting)
@@ -340,7 +339,7 @@ impl Render for NewAccount {
.child(divider(cx)) .child(divider(cx))
.child( .child(
Button::new("submit") Button::new("submit")
.label(t!("common.continue")) .label("Continue")
.primary() .primary()
.loading(self.submitting) .loading(self.submitting)
.disabled(self.submitting || self.uploading) .disabled(self.submitting || self.uploading)

View File

@@ -7,7 +7,6 @@ use gpui::{
div, rems, App, ClickEvent, InteractiveElement, IntoElement, ParentElement as _, RenderOnce, div, rems, App, ClickEvent, InteractiveElement, IntoElement, ParentElement as _, RenderOnce,
SharedString, StatefulInteractiveElement, Styled, Window, SharedString, StatefulInteractiveElement, Styled, Window,
}; };
use i18n::t;
use nostr_sdk::prelude::*; use nostr_sdk::prelude::*;
use settings::AppSettings; use settings::AppSettings;
use theme::ActiveTheme; use theme::ActiveTheme;
@@ -168,8 +167,8 @@ impl RenderOnce for RoomListItem {
) )
.hover(|this| this.bg(cx.theme().elevated_surface_background)) .hover(|this| this.bg(cx.theme().elevated_surface_background))
.context_menu(move |this, _window, _cx| { .context_menu(move |this, _window, _cx| {
this.menu(t!("profile.view"), Box::new(OpenPublicKey(public_key))) this.menu("View Profile", Box::new(OpenPublicKey(public_key)))
.menu(t!("profile.copy"), Box::new(CopyPublicKey(public_key))) .menu("Copy Public Key", Box::new(CopyPublicKey(public_key)))
}) })
.on_click(move |event, window, cx| { .on_click(move |event, window, cx| {
handler(event, window, cx); handler(event, window, cx);
@@ -182,8 +181,8 @@ impl RenderOnce for RoomListItem {
.child(screening.clone()) .child(screening.clone())
.button_props( .button_props(
ModalButtonProps::default() ModalButtonProps::default()
.cancel_text(t!("screening.ignore")) .cancel_text("Ignore")
.ok_text(t!("screening.response")), .ok_text("Response"),
) )
.on_cancel(move |_event, _window, cx| { .on_cancel(move |_event, _window, cx| {
ChatRegistry::global(cx).update(cx, |this, cx| { ChatRegistry::global(cx).update(cx, |this, cx| {

View File

@@ -12,7 +12,6 @@ use gpui::{
RetainAllImageCache, SharedString, Styled, Subscription, Task, Window, RetainAllImageCache, SharedString, Styled, Subscription, Task, Window,
}; };
use gpui_tokio::Tokio; use gpui_tokio::Tokio;
use i18n::{shared_t, t};
use list_item::RoomListItem; use list_item::RoomListItem;
use nostr_sdk::prelude::*; use nostr_sdk::prelude::*;
use settings::AppSettings; use settings::AppSettings;
@@ -69,7 +68,7 @@ impl Sidebar {
let search_results = cx.new(|_| None); let search_results = cx.new(|_| None);
let find_input = let find_input =
cx.new(|cx| InputState::new(window, cx).placeholder(t!("sidebar.search_label"))); cx.new(|cx| InputState::new(window, cx).placeholder("Find or start a conversation"));
let chat = ChatRegistry::global(cx); let chat = ChatRegistry::global(cx);
let mut subscriptions = smallvec![]; let mut subscriptions = smallvec![];
@@ -432,12 +431,12 @@ impl Sidebar {
room room
} else { } else {
let Some(result) = self.search_results.read(cx).as_ref() else { let Some(result) = self.search_results.read(cx).as_ref() else {
window.push_notification(t!("common.room_error"), cx); window.push_notification("Failed to open room. Please try again later.", cx);
return; return;
}; };
let Some(room) = result.iter().find(|this| this.read(cx).id == id).cloned() else { let Some(room) = result.iter().find(|this| this.read(cx).id == id).cloned() else {
window.push_notification(t!("common.room_error"), cx); window.push_notification("Failed to open room. Please try again later.", cx);
return; return;
}; };
@@ -456,7 +455,7 @@ impl Sidebar {
ChatRegistry::global(cx).update(cx, |this, cx| { ChatRegistry::global(cx).update(cx, |this, cx| {
this.get_rooms(cx); this.get_rooms(cx);
}); });
window.push_notification(t!("common.refreshed"), cx); window.push_notification("Refreshed", cx);
} }
fn on_manage(&mut self, _ev: &RelayStatus, window: &mut Window, cx: &mut Context<Self>) { fn on_manage(&mut self, _ev: &RelayStatus, window: &mut Window, cx: &mut Context<Self>) {
@@ -492,7 +491,7 @@ impl Sidebar {
this.show_close(true) this.show_close(true)
.overlay_closable(true) .overlay_closable(true)
.keyboard(true) .keyboard(true)
.title(shared_t!("manage_relays.modal")) .title(SharedString::from("Messaging Relay Status"))
.child(v_flex().pb_4().gap_2().children({ .child(v_flex().pb_4().gap_2().children({
let mut items = Vec::with_capacity(relays.len()); let mut items = Vec::with_capacity(relays.len());
@@ -524,10 +523,9 @@ impl Sidebar {
.child(url), .child(url),
) )
.child( .child(
div() div().text_right().text_color(cx.theme().text_muted).child(
.text_right() SharedString::from(format!("Last activity: {}", time)),
.text_color(cx.theme().text_muted) ),
.child(shared_t!("manage_relays.time", t = time)),
), ),
); );
} }
@@ -649,7 +647,7 @@ impl Render for Sidebar {
this.suffix( this.suffix(
Button::new("find") Button::new("find")
.icon(IconName::Search) .icon(IconName::Search)
.tooltip(t!("sidebar.search_tooltip")) .tooltip("Press Enter to search")
.transparent() .transparent()
.small(), .small(),
) )
@@ -675,8 +673,8 @@ impl Render for Sidebar {
.flex_none() .flex_none()
.child( .child(
Button::new("all") Button::new("all")
.label(t!("sidebar.all_button")) .label("All")
.tooltip(t!("sidebar.all_conversations_tooltip")) .tooltip("All ongoing conversations")
.when_some(self.indicator.read(cx).as_ref(), |this, kind| { .when_some(self.indicator.read(cx).as_ref(), |this, kind| {
this.when(kind == &RoomKind::Ongoing, |this| { this.when(kind == &RoomKind::Ongoing, |this| {
this.child( this.child(
@@ -696,8 +694,8 @@ impl Render for Sidebar {
) )
.child( .child(
Button::new("requests") Button::new("requests")
.label(t!("sidebar.requests_button")) .label("Requests")
.tooltip(t!("sidebar.requests_tooltip")) .tooltip("Incoming new conversations")
.when_some(self.indicator.read(cx).as_ref(), |this, kind| { .when_some(self.indicator.read(cx).as_ref(), |this, kind| {
this.when(kind != &RoomKind::Ongoing, |this| { this.when(kind != &RoomKind::Ongoing, |this| {
this.child( this.child(
@@ -730,11 +728,11 @@ impl Render for Sidebar {
.rounded() .rounded()
.popup_menu(move |this, _window, _cx| { .popup_menu(move |this, _window, _cx| {
this.menu( this.menu(
t!("sidebar.reload_menu"), "Reload",
Box::new(Reload), Box::new(Reload),
) )
.menu( .menu(
t!("sidebar.status_menu"), "Relay Status",
Box::new(RelayStatus), Box::new(RelayStatus),
) )
}), }),
@@ -757,14 +755,14 @@ impl Render for Sidebar {
.text_sm() .text_sm()
.font_semibold() .font_semibold()
.line_height(relative(1.25)) .line_height(relative(1.25))
.child(shared_t!("sidebar.no_conversations")), .child(SharedString::from("No conversations")),
) )
.child( .child(
div() div()
.text_xs() .text_xs()
.text_color(cx.theme().text_muted) .text_color(cx.theme().text_muted)
.line_height(relative(1.25)) .line_height(relative(1.25))
.child(shared_t!("sidebar.no_conversations_label")), .child(SharedString::from("Start a conversation with someone to get started.")),
), ),
)) ))
} else { } else {
@@ -781,14 +779,14 @@ impl Render for Sidebar {
.text_sm() .text_sm()
.font_semibold() .font_semibold()
.line_height(relative(1.25)) .line_height(relative(1.25))
.child(shared_t!("sidebar.no_requests")), .child(SharedString::from("No message requests")),
) )
.child( .child(
div() div()
.text_xs() .text_xs()
.text_color(cx.theme().text_muted) .text_color(cx.theme().text_muted)
.line_height(relative(1.25)) .line_height(relative(1.25))
.child(shared_t!("sidebar.no_requests_label")), .child(SharedString::from("New message requests from people you don't know will appear here.")),
), ),
)) ))
} }

View File

@@ -12,7 +12,6 @@ use gpui::{
StatefulInteractiveElement, Styled, Subscription, Task, Window, StatefulInteractiveElement, Styled, Subscription, Task, Window,
}; };
use gpui_tokio::Tokio; use gpui_tokio::Tokio;
use i18n::{shared_t, t};
use nostr_sdk::prelude::*; use nostr_sdk::prelude::*;
use person::PersonRegistry; use person::PersonRegistry;
use settings::AppSettings; use settings::AppSettings;
@@ -41,9 +40,9 @@ pub fn compose_button() -> impl IntoElement {
window.open_modal(cx, move |modal, _window, cx| { window.open_modal(cx, move |modal, _window, cx| {
let weak_view = weak_view.clone(); let weak_view = weak_view.clone();
let label = if compose.read(cx).selected(cx).len() > 1 { let label = if compose.read(cx).selected(cx).len() > 1 {
shared_t!("compose.create_group_dm_button") SharedString::from("Create Group DM")
} else { } else {
shared_t!("compose.create_dm_button") SharedString::from("Create DM")
}; };
modal modal
@@ -52,7 +51,7 @@ pub fn compose_button() -> impl IntoElement {
.keyboard(true) .keyboard(true)
.show_close(true) .show_close(true)
.button_props(ModalButtonProps::default().ok_text(label)) .button_props(ModalButtonProps::default().ok_text(label))
.title(shared_t!("sidebar.direct_messages")) .title(SharedString::from("Direct Messages"))
.child(compose.clone()) .child(compose.clone())
.on_ok(move |_, window, cx| { .on_ok(move |_, window, cx| {
weak_view weak_view
@@ -238,7 +237,7 @@ impl Compose {
}); });
}); });
} else { } else {
self.set_error(t!("compose.contact_existed"), cx); self.set_error("Contact already added", cx);
} }
} }
@@ -419,7 +418,7 @@ impl Render for Compose {
div() div()
.text_sm() .text_sm()
.text_color(cx.theme().text_muted) .text_color(cx.theme().text_muted)
.child(shared_t!("compose.description")), .child(SharedString::from("Start a conversation with someone using their npub or NIP-05 (like foo@bar.com).")),
) )
.when_some(error, |this, msg| { .when_some(error, |this, msg| {
this.child( this.child(
@@ -440,7 +439,7 @@ impl Render for Compose {
div() div()
.text_sm() .text_sm()
.font_semibold() .font_semibold()
.child(shared_t!("compose.subject_label")), .child(SharedString::from("Subject:")),
) )
.child(TextInput::new(&self.title_input).small().appearance(false)), .child(TextInput::new(&self.title_input).small().appearance(false)),
) )
@@ -455,7 +454,7 @@ impl Render for Compose {
div() div()
.text_sm() .text_sm()
.font_semibold() .font_semibold()
.child(shared_t!("compose.to_label")), .child(SharedString::from("To:")),
) )
.child( .child(
TextInput::new(&self.user_input) TextInput::new(&self.user_input)
@@ -487,12 +486,12 @@ impl Render for Compose {
div() div()
.font_semibold() .font_semibold()
.line_height(relative(1.2)) .line_height(relative(1.2))
.child(shared_t!("compose.no_contacts_message")), .child(SharedString::from("No contacts")),
) )
.child( .child(
div() div()
.text_color(cx.theme().text_muted) .text_color(cx.theme().text_muted)
.child(shared_t!("compose.no_contacts_description")), .child(SharedString::from("Your recently contacts will appear here.")),
), ),
) )
} else { } else {

View File

@@ -8,7 +8,6 @@ use gpui::{
FocusHandle, Focusable, Image, InteractiveElement, IntoElement, ParentElement, Render, FocusHandle, Focusable, Image, InteractiveElement, IntoElement, ParentElement, Render,
SharedString, StatefulInteractiveElement, Styled, Task, Window, SharedString, StatefulInteractiveElement, Styled, Task, Window,
}; };
use i18n::{shared_t, t};
use key_store::{KeyItem, KeyStore}; use key_store::{KeyItem, KeyStore};
use nostr_connect::prelude::*; use nostr_connect::prelude::*;
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
@@ -253,13 +252,11 @@ impl Render for Onboarding {
.text_xl() .text_xl()
.font_semibold() .font_semibold()
.line_height(relative(1.3)) .line_height(relative(1.3))
.child(shared_t!("welcome.title")), .child(SharedString::from("Welcome to Coop")),
) )
.child( .child(div().text_color(cx.theme().text_muted).child(
div() SharedString::from("Chat Freely, Stay Private on Nostr."),
.text_color(cx.theme().text_muted) )),
.child(shared_t!("welcome.subtitle")),
),
), ),
) )
.child( .child(
@@ -269,7 +266,7 @@ impl Render for Onboarding {
.child( .child(
Button::new("continue_btn") Button::new("continue_btn")
.icon(Icon::new(IconName::ArrowRight)) .icon(Icon::new(IconName::ArrowRight))
.label(shared_t!("onboarding.start_messaging")) .label(SharedString::from("Start Messaging on Nostr"))
.primary() .primary()
.large() .large()
.bold() .bold()
@@ -283,17 +280,16 @@ impl Render for Onboarding {
.my_1() .my_1()
.gap_1() .gap_1()
.child(divider(cx)) .child(divider(cx))
.child( .child(div().text_sm().text_color(cx.theme().text_muted).child(
div() SharedString::from(
.text_sm() "Already have an account? Continue with",
.text_color(cx.theme().text_muted) ),
.child(shared_t!("onboarding.divider")), ))
)
.child(divider(cx)), .child(divider(cx)),
) )
.child( .child(
Button::new("key") Button::new("key")
.label(t!("onboarding.key_login")) .label("Secret Key or Bunker")
.large() .large()
.ghost_alt() .ghost_alt()
.on_click(cx.listener(move |_, _, window, cx| { .on_click(cx.listener(move |_, _, window, cx| {
@@ -339,13 +335,17 @@ impl Render for Onboarding {
div() div()
.font_semibold() .font_semibold()
.line_height(relative(1.3)) .line_height(relative(1.3))
.child(shared_t!("onboarding.nostr_connect")), .child(SharedString::from(
"Continue with Nostr Connect",
)),
) )
.child( .child(
div() div()
.text_sm() .text_sm()
.text_color(cx.theme().text_muted) .text_color(cx.theme().text_muted)
.child(shared_t!("onboarding.scan_qr")), .child(SharedString::from(
"Use Nostr Connect apps to scan the code",
)),
) )
.child( .child(
h_flex() h_flex()

View File

@@ -3,7 +3,6 @@ use gpui::{
div, px, App, AppContext, Context, Entity, IntoElement, ParentElement, Render, SharedString, div, px, App, AppContext, Context, Entity, IntoElement, ParentElement, Render, SharedString,
Styled, Window, Styled, Window,
}; };
use i18n::{shared_t, t};
use settings::AppSettings; use settings::AppSettings;
use theme::ActiveTheme; use theme::ActiveTheme;
use ui::button::{Button, ButtonVariants}; use ui::button::{Button, ButtonVariants};
@@ -54,7 +53,7 @@ impl Render for Preferences {
.text_sm() .text_sm()
.text_color(cx.theme().text_placeholder) .text_color(cx.theme().text_placeholder)
.font_semibold() .font_semibold()
.child(shared_t!("preferences.relay_and_media")), .child(SharedString::from("Relay and Media")),
) )
.child( .child(
v_flex() v_flex()
@@ -85,13 +84,13 @@ impl Render for Preferences {
div() div()
.text_xs() .text_xs()
.text_color(cx.theme().text_muted) .text_color(cx.theme().text_muted)
.child(shared_t!("preferences.media_description")), .child(SharedString::from("Coop currently only supports NIP-96 media servers.")),
), ),
) )
.child( .child(
Switch::new("auth") Switch::new("auth")
.label(t!("preferences.auto_auth")) .label("Automatically authenticate for known relays")
.description(t!("preferences.auto_auth_description")) .description("After you approve the authentication request, Coop will automatically complete this step next time.")
.checked(auto_auth) .checked(auto_auth)
.on_click(move |_, _window, cx| { .on_click(move |_, _window, cx| {
AppSettings::update_auto_auth(!auto_auth, cx); AppSettings::update_auto_auth(!auto_auth, cx);
@@ -109,15 +108,15 @@ impl Render for Preferences {
.text_sm() .text_sm()
.text_color(cx.theme().text_placeholder) .text_color(cx.theme().text_placeholder)
.font_semibold() .font_semibold()
.child(shared_t!("preferences.messages_header")), .child(SharedString::from("Messages")),
) )
.child( .child(
v_flex() v_flex()
.gap_2() .gap_2()
.child( .child(
Switch::new("screening") Switch::new("screening")
.label(t!("preferences.screening_label")) .label("Screening")
.description(t!("preferences.screening_description")) .description("When opening a chat request, Coop will show a popup to help you verify the sender.")
.checked(screening) .checked(screening)
.on_click(move |_, _window, cx| { .on_click(move |_, _window, cx| {
AppSettings::update_screening(!screening, cx); AppSettings::update_screening(!screening, cx);
@@ -125,8 +124,8 @@ impl Render for Preferences {
) )
.child( .child(
Switch::new("bypass") Switch::new("bypass")
.label(t!("preferences.bypass_label")) .label("Skip screening for contacts")
.description(t!("preferences.bypass_description")) .description("Requests from your contacts will automatically go to inbox.")
.checked(bypass) .checked(bypass)
.on_click(move |_, _window, cx| { .on_click(move |_, _window, cx| {
AppSettings::update_contact_bypass(!bypass, cx); AppSettings::update_contact_bypass(!bypass, cx);
@@ -134,8 +133,8 @@ impl Render for Preferences {
) )
.child( .child(
Switch::new("backup") Switch::new("backup")
.label(t!("preferences.backup_label")) .label("Backup messages")
.description(t!("preferences.backup_description")) .description("When you send a message, Coop will also forward it to your configured Messaging Relays. Disabling this will cause all messages sent during the current session to disappear when the app is closed.")
.checked(backup) .checked(backup)
.on_click(move |_, _window, cx| { .on_click(move |_, _window, cx| {
AppSettings::update_backup_messages(!backup, cx); AppSettings::update_backup_messages(!backup, cx);
@@ -154,15 +153,15 @@ impl Render for Preferences {
.text_sm() .text_sm()
.text_color(cx.theme().text_placeholder) .text_color(cx.theme().text_placeholder)
.font_semibold() .font_semibold()
.child(shared_t!("preferences.display_header")), .child(SharedString::from("Display")),
) )
.child( .child(
v_flex() v_flex()
.gap_2() .gap_2()
.child( .child(
Switch::new("hide_avatar") Switch::new("hide_avatar")
.label(t!("preferences.hide_avatars_label")) .label("Hide user avatars")
.description(t!("preferences.hide_avatar_description")) .description("Unload all avatar pictures to improve performance and reduce memory usage.")
.checked(hide) .checked(hide)
.on_click(move |_, _window, cx| { .on_click(move |_, _window, cx| {
AppSettings::update_hide_user_avatars(!hide, cx); AppSettings::update_hide_user_avatars(!hide, cx);
@@ -170,8 +169,8 @@ impl Render for Preferences {
) )
.child( .child(
Switch::new("proxy_avatar") Switch::new("proxy_avatar")
.label(t!("preferences.proxy_avatars_label")) .label("Proxy user avatars")
.description(t!("preferences.proxy_description")) .description("Use wsrv.nl to resize and downscale avatar pictures (saves ~50MB of data).")
.checked(proxy) .checked(proxy)
.on_click(move |_, _window, cx| { .on_click(move |_, _window, cx| {
AppSettings::update_proxy_user_avatars(!proxy, cx); AppSettings::update_proxy_user_avatars(!proxy, cx);

View File

@@ -7,7 +7,6 @@ use gpui::{
InteractiveElement, IntoElement, ParentElement, Render, SharedString, Styled, Task, Window, InteractiveElement, IntoElement, ParentElement, Render, SharedString, Styled, Task, Window,
}; };
use gpui_tokio::Tokio; use gpui_tokio::Tokio;
use i18n::{shared_t, t};
use nostr_sdk::prelude::*; use nostr_sdk::prelude::*;
use person::PersonRegistry; use person::PersonRegistry;
use settings::AppSettings; use settings::AppSettings;
@@ -176,7 +175,7 @@ impl Screening {
if task.await.is_ok() { if task.await.is_ok() {
cx.update(|window, cx| { cx.update(|window, cx| {
window.close_modal(cx); window.close_modal(cx);
window.push_notification(t!("screening.report_msg"), cx); window.push_notification("Report submitted successfully", cx);
}) })
.ok(); .ok();
} }
@@ -191,7 +190,7 @@ impl Screening {
let contacts = contacts.clone(); let contacts = contacts.clone();
let total = contacts.len(); let total = contacts.len();
this.title(shared_t!("screening.mutual_label")).child( this.title(SharedString::from("Mutual contacts")).child(
v_flex().gap_1().pb_4().child( v_flex().gap_1().pb_4().child(
uniform_list("contacts", total, move |range, _window, cx| { uniform_list("contacts", total, move |range, _window, cx| {
let mut items = Vec::with_capacity(total); let mut items = Vec::with_capacity(total);
@@ -270,7 +269,7 @@ impl Render for Screening {
.gap_1() .gap_1()
.child( .child(
Button::new("njump") Button::new("njump")
.label(t!("profile.njump")) .label("View on njump.me")
.secondary() .secondary()
.small() .small()
.rounded() .rounded()
@@ -280,7 +279,7 @@ impl Render for Screening {
) )
.child( .child(
Button::new("report") Button::new("report")
.tooltip(t!("screening.report")) .tooltip("Report as a scam or impostor")
.icon(IconName::Report) .icon(IconName::Report)
.danger() .danger()
.rounded() .rounded()
@@ -302,16 +301,16 @@ impl Render for Screening {
.child( .child(
v_flex() v_flex()
.text_sm() .text_sm()
.child(shared_t!("screening.contact_label")) .child(SharedString::from("Contact"))
.child( .child(
div() div()
.line_clamp(1) .line_clamp(1)
.text_color(cx.theme().text_muted) .text_color(cx.theme().text_muted)
.child({ .child({
if self.followed { if self.followed {
shared_t!("screening.contact") SharedString::from("This person is one of your contacts.")
} else { } else {
shared_t!("screening.not_contact") SharedString::from("This person is not one of your contacts.")
} }
}), }),
), ),
@@ -329,14 +328,14 @@ impl Render for Screening {
.child( .child(
h_flex() h_flex()
.gap_0p5() .gap_0p5()
.child(shared_t!("screening.active_label")) .child(SharedString::from("Activity on Public Relays"))
.child( .child(
Button::new("active") Button::new("active")
.icon(IconName::Info) .icon(IconName::Info)
.xsmall() .xsmall()
.ghost() .ghost()
.rounded() .rounded()
.tooltip(t!("screening.active_tooltip")), .tooltip("This may be inaccurate if the user only publishes to their private relays."),
), ),
) )
.child( .child(
@@ -346,12 +345,12 @@ impl Render for Screening {
.text_color(cx.theme().text_muted) .text_color(cx.theme().text_muted)
.map(|this| { .map(|this| {
if let Some(date) = self.last_active { if let Some(date) = self.last_active {
this.child(shared_t!( this.child(SharedString::from(format!(
"screening.active_at", "Last active: {}.",
d = date.to_human_time() date.to_human_time()
)) )))
} else { } else {
this.child(shared_t!("screening.no_active")) this.child(SharedString::from("This person hasn't had any activity."))
} }
}), }),
), ),
@@ -367,9 +366,9 @@ impl Render for Screening {
.text_sm() .text_sm()
.child({ .child({
if let Some(addr) = self.address(cx) { if let Some(addr) = self.address(cx) {
shared_t!("screening.nip05_addr", addr = addr) SharedString::from(format!("{} validation", addr))
} else { } else {
shared_t!("screening.nip05_label") SharedString::from("Friendly Address (NIP-05) validation")
} }
}) })
.child( .child(
@@ -379,12 +378,12 @@ impl Render for Screening {
.child({ .child({
if self.address(cx).is_some() { if self.address(cx).is_some() {
if self.verified { if self.verified {
shared_t!("screening.nip05_ok") SharedString::from("The address matches the user's public key.")
} else { } else {
shared_t!("screening.nip05_failed") SharedString::from("The address does not match the user's public key.")
} }
} else { } else {
shared_t!("screening.nip05_empty") SharedString::from("This person has not set up their friendly address")
} }
}), }),
), ),
@@ -401,7 +400,7 @@ impl Render for Screening {
.child( .child(
h_flex() h_flex()
.gap_0p5() .gap_0p5()
.child(shared_t!("screening.mutual_label")) .child(SharedString::from("Mutual contacts"))
.child( .child(
Button::new("mutuals") Button::new("mutuals")
.icon(IconName::Info) .icon(IconName::Info)
@@ -421,9 +420,12 @@ impl Render for Screening {
.text_color(cx.theme().text_muted) .text_color(cx.theme().text_muted)
.child({ .child({
if total_mutuals > 0 { if total_mutuals > 0 {
shared_t!("screening.mutual", u = total_mutuals) SharedString::from(format!(
"You have {} mutual contacts with this person.",
total_mutuals
))
} else { } else {
shared_t!("screening.no_mutual") SharedString::from("You don't have any mutual contacts with this person.")
} }
}), }),
), ),

View File

@@ -8,7 +8,6 @@ use gpui::{
ParentElement, Render, SharedString, Styled, Subscription, Task, TextAlign, UniformList, ParentElement, Render, SharedString, Styled, Subscription, Task, TextAlign, UniformList,
Window, Window,
}; };
use i18n::{shared_t, t};
use nostr_sdk::prelude::*; use nostr_sdk::prelude::*;
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
use state::NostrRegistry; use state::NostrRegistry;
@@ -149,7 +148,11 @@ impl SetupRelay {
pub fn set_relays(&mut self, window: &mut Window, cx: &mut Context<Self>) { pub fn set_relays(&mut self, window: &mut Window, cx: &mut Context<Self>) {
if self.relays.is_empty() { if self.relays.is_empty() {
self.set_error(t!("relays.empty"), window, cx); self.set_error(
"You need to add at least 1 relay to receive messages from others.",
window,
cx,
);
return; return;
}; };
@@ -272,7 +275,7 @@ impl SetupRelay {
.justify_center() .justify_center()
.text_sm() .text_sm()
.text_align(TextAlign::Center) .text_align(TextAlign::Center)
.child(shared_t!("relays.help_text")) .child(SharedString::from("Please add some relays."))
} }
} }
@@ -284,7 +287,7 @@ impl Render for SetupRelay {
.child( .child(
div() div()
.text_color(cx.theme().text_muted) .text_color(cx.theme().text_muted)
.child(shared_t!("relays.description")), .child(SharedString::from("In order to receive messages from others, you need to set up at least one Messaging Relay.")),
) )
.child( .child(
v_flex() v_flex()
@@ -297,7 +300,7 @@ impl Render for SetupRelay {
.child( .child(
Button::new("add") Button::new("add")
.icon(IconName::PlusFill) .icon(IconName::PlusFill)
.label(t!("common.add")) .label("Add")
.ghost() .ghost()
.on_click(cx.listener(move |this, _, window, cx| { .on_click(cx.listener(move |this, _, window, cx| {
this.add(window, cx); this.add(window, cx);

View File

@@ -8,7 +8,6 @@ use gpui::{
RetainAllImageCache, SharedString, StatefulInteractiveElement, Styled, Subscription, Task, RetainAllImageCache, SharedString, StatefulInteractiveElement, Styled, Subscription, Task,
Window, Window,
}; };
use i18n::{shared_t, t};
use key_store::{Credential, KeyItem, KeyStore}; use key_store::{Credential, KeyItem, KeyStore};
use nostr_connect::prelude::*; use nostr_connect::prelude::*;
use person::PersonRegistry; use person::PersonRegistry;
@@ -147,7 +146,10 @@ impl Startup {
) )
} }
Ok(None) => { Ok(None) => {
window.push_notification(t!("login.keyring_required"), cx); window.push_notification(
"You must allow Coop access to the keyring to continue.",
cx,
);
this.set_loading(false, cx); this.set_loading(false, cx);
} }
Err(e) => { Err(e) => {
@@ -231,12 +233,14 @@ impl Render for Startup {
.text_xl() .text_xl()
.font_semibold() .font_semibold()
.line_height(relative(1.3)) .line_height(relative(1.3))
.child(shared_t!("welcome.title")), .child(SharedString::from("Welcome to Coop")),
) )
.child( .child(
div() div()
.text_color(cx.theme().text_muted) .text_color(cx.theme().text_muted)
.child(shared_t!("welcome.subtitle")), .child(SharedString::from(
"Chat Freely, Stay Private on Nostr.",
)),
), ),
), ),
) )
@@ -305,14 +309,11 @@ impl Render for Startup {
this.login(window, cx); this.login(window, cx);
})), })),
) )
.child( .child(Button::new("logout").label("Sign out").ghost().on_click(
Button::new("logout") |_, _window, cx| {
.label(t!("user.sign_out")) reset(cx);
.ghost() },
.on_click(|_, _window, cx| { )),
reset(cx);
}),
),
) )
} }
} }

View File

@@ -1,8 +0,0 @@
[package]
name = "i18n"
version.workspace = true
edition.workspace = true
publish.workspace = true
[dependencies]
rust-i18n.workspace = true

View File

@@ -1,39 +0,0 @@
use rust_i18n::Backend;
rust_i18n::i18n!("../../locales");
pub struct I18nBackend;
impl Backend for I18nBackend {
fn available_locales(&self) -> Vec<&str> {
_RUST_I18N_BACKEND.available_locales()
}
fn translate(&self, locale: &str, key: &str) -> Option<&str> {
let val = _RUST_I18N_BACKEND.translate(locale, key);
if val.is_none() {
_RUST_I18N_BACKEND.translate("en", key)
} else {
val
}
}
}
#[macro_export]
macro_rules! init {
() => {
rust_i18n::i18n!(backend = i18n::I18nBackend);
};
}
#[macro_export]
macro_rules! shared_t {
($key:expr) => {
SharedString::from(t!($key))
};
($key:expr, $($param:ident = $value:expr),+) => {
SharedString::from(t!($key, $($param = $value),+))
};
}
pub use rust_i18n::{set_locale, t};

View File

@@ -9,8 +9,6 @@ common = { path = "../common" }
theme = { path = "../theme" } theme = { path = "../theme" }
ui = { path = "../ui" } ui = { path = "../ui" }
rust-i18n.workspace = true
i18n.workspace = true
nostr-sdk.workspace = true nostr-sdk.workspace = true
gpui.workspace = true gpui.workspace = true
smol.workspace = true smol.workspace = true

View File

View File

@@ -1,401 +0,0 @@
_version: 2
common:
add:
en: "Add"
update:
en: "Update"
upload:
en: "Upload"
change:
en: "Change"
continue:
en: "Continue"
pubkey:
en: "Public Key"
pubkey_invalid:
en: "Public Key is not valid"
secret:
en: "Secret Key"
not_found:
en: "Not Found"
room_error:
en: "Failed to open room. Please try again later."
preferences:
en: "Preferences"
allow:
en: "Allow"
copied:
en: "Copied"
saved:
en: "Your Secret Key has been saved"
clear:
en: "Clear"
open_browser:
en: "Open Browser"
refreshed:
en: "Refreshed"
quit:
en: "Quit"
restart:
en: "Restart"
approve:
en: "Approve"
ignore:
en: "Ignore"
relay:
en: "Relay"
relay_invalid:
en: "Relay URL is not valid."
recommended:
en: "Recommended:"
resend:
en: "Resend"
seen_on:
en: "Seen on"
default:
en: "Default"
use_default:
en: "Use default"
configure:
en: "Configure"
hide:
en: "Hide"
reset:
en: "Reset"
keyring_disable:
label:
en: "Keyring is disabled"
body_1:
en: "Coop cannot access the Keyring Service on your system. By design, Coop uses Keyring to store your credentials."
body_2:
en: "Without access to Keyring, Coop will store your credentials as plain text."
body_3:
en: "If you want to store your credentials in the Keyring, please enable Keyring and allow Coop to access it."
pending_encryption:
label:
en: "Wait for Approval"
body_1:
en: "Please open %{c} and approve the request for sharing Encryption Key. Without access to them, Coop cannot decrypt your messages that are encrypted with Encryption Key."
body_2:
en: "Or you can click the 'Reset' button to reset the Encryption Key."
body_3:
en: "By resetting the Encryption Key, you will not be able to view your messages that were encrypted with the old Encryption Key."
request_encryption:
label:
en: "Encryption Key Request"
body:
en: "You've requested for the encryption Key from:"
auto_update:
updating:
en: "Installing the new update..."
updated:
en: "Restart to apply the new update"
user:
dark_mode:
en: "Dark mode"
settings:
en: "Settings"
reload_metadata:
en: "Reload metadata"
sign_out:
en: "Sign out"
welcome:
title:
en: "Welcome to Coop"
subtitle:
en: "Chat Freely, Stay Private on Nostr."
onboarding:
choose_account:
en: "Continue as"
auto_login:
en: "Automatically login in the next time"
start_messaging:
en: "Start Messaging on Nostr"
nostr_connect:
en: "Continue with Nostr Connect"
scan_qr:
en: "Use Nostr Connect apps to scan the code"
divider:
en: "Already have an account? Continue with"
key_login:
en: "Secret Key or Bunker"
ext_login:
en: "Browser Extension"
ext_login_note:
en: "You will need to keep your default browser open."
auth:
label:
en: "Authentication Required"
message:
en: "Approve the authentication request to allow Coop to continue sending or receiving events."
requests:
en: "You have %{u} pending authentication requests"
new_account:
title:
en: "Create a new identity"
name:
en: "What should people call you?"
avatar:
en: "Choose an avatar to help people recognize you"
backup_label:
en: "Backup to avoid losing access to your account"
backup_description:
en: "In the Nostr Network, your account is defined by a Secret Key. This key is used to sign your messages and identify you."
backup_pubkey_note:
en: "Your Public Key is the address that others will use to find you on the Nostr Network."
backup_secret_note:
en: "Your Secret Key is required to access your account. If you lose it, you will lose access to your account."
backup_skip:
en: "Do it later"
backup_download:
en: "Download"
login:
title:
en: "Welcome Back!"
key_description:
en: "Continue with Private Key or Bunker"
approve_message:
en: "Approve connection request from your signer in %{i} seconds"
invalid_key:
en: "Please enter a valid secret key or bunker to login."
set_password:
en: "Set password to encrypt your key *"
password_to_decrypt:
en: "Password to decrypt your key *"
password_description:
en: "Coop will only store the encrypted version of your keys"
password_description_full:
en: "Coop will use the password to encrypt your keys. You will need this password to decrypt your keys for future use."
password_is_required:
en: "Password is required"
confirm_password:
en: "Confirm your password *"
must_confirm_password:
en: "You must confirm your password"
password_not_match:
en: "Passwords do not match"
key_invalid:
en: "Secret key is invalid"
bunker_invalid:
en: "Bunker is not valid"
logging_in:
en: "Logging in..."
keyring_required:
en: "You must allow Coop access to the keyring to continue."
mailbox:
modal:
en: "Set Up Mailbox Relays to Continue"
description:
en: "By configuring Mailbox Relays, Coop can find where to get or send your events. If you are unsure, use the default option and modify it later."
write_label:
en: "Outbox Relays are used to publish your events. Other users will also look for your events there."
read_label:
en: "Inbox Relays are used to find events about you. Other users will publish the events they want you to see there."
messaging:
button:
en: "Configure the Messaging Relays to receive messages"
modal:
en: "Set Up Messaging Relays"
description:
en: "In order to receive messages from others, you need to set up at least one Messaging Relay."
relays:
help_text:
en: "Please add some relays."
empty:
en: "You need to add at least 1 relay to receive messages from others."
manage_relays:
modal:
en: "Messaging Relay Status"
time:
en: "Last activity: %{t}"
screening:
ignore:
en: "Ignore"
response:
en: "Response"
nip05_label:
en: "Friendly Address (NIP-05) validation"
nip05_addr:
en: "%{addr} validation"
nip05_empty:
en: "This person has not set up their friendly address"
nip05_ok:
en: "The address matches the user's public key."
nip05_failed:
en: "The address does not match the user's public key."
contact_label:
en: "Contact"
contact:
en: "This person is one of your contacts."
not_contact:
en: "This person is not one of your contacts."
active_label:
en: "Activity on Public Relays"
active_tooltip:
en: "This may be inaccurate if the user only publishes to their private relays."
no_active:
en: "This person hasn't had any activity."
active_at:
en: "Last active: %{d}."
mutual_label:
en: "Mutual contacts"
mutual:
en: "You have %{u} mutual contacts with this person."
no_mutual:
en: "You don't have any mutual contacts with this person."
relay_found:
en: "Messaging Relays found"
relay_found_desc:
en: "You can send a message to this person."
relay_empty:
en: "Messaging Relays not found"
relay_empty_desc:
en: "You cannot send a message to this person."
report:
en: "Report as a scam or impostor"
report_msg:
en: "Report submitted successfully"
profile:
title:
en: "Profile"
view:
en: "View Profile"
set_profile_picture:
en: "Set Profile Picture"
placeholder_bio:
en: "A short introduce about you."
updated_successfully:
en: "Your profile has been updated successfully"
label_name:
en: "Name:"
label_website:
en: "Website:"
label_bio:
en: "Bio:"
unknown:
en: "Unknown contact"
njump:
en: "View on njump.me"
no_bio:
en: "No bio."
copy:
en: "Copy Public Key"
preferences:
account_header:
en: "Account"
account_btn:
en: "See your profile"
relay_and_media:
en: "Relay and Media"
media_description:
en: "Coop currently only supports NIP-96 media servers."
auto_auth:
en: "Automatically authenticate for known relays"
auto_auth_description:
en: "After you approve the authentication request, Coop will automatically complete this step next time."
backup_label:
en: "Backup messages"
backup_description:
en: "When you send a message, Coop will also forward it to your configured Messaging Relays. Disabling this will cause all messages sent during the current session to disappear when the app is closed."
screening_label:
en: "Screening"
screening_description:
en: "When opening a chat request, Coop will show a popup to help you verify the sender."
bypass_label:
en: "Skip screening for contacts"
bypass_description:
en: "Requests from your contacts will automatically go to inbox."
hide_avatars_label:
en: "Hide user avatars"
hide_avatar_description:
en: "Unload all avatar pictures to improve performance and reduce memory usage."
proxy_avatars_label:
en: "Proxy user avatars"
proxy_description:
en: "Use wsrv.nl to resize and downscale avatar pictures (saves ~50MB of data)."
messages_header:
en: "Messages"
display_header:
en: "Display"
compose:
create_dm_button:
en: "Create DM"
creating_dm_button:
en: "Creating DM..."
create_group_dm_button:
en: "Create Group DM"
to_label:
en: "To:"
no_contacts_message:
en: "No contacts"
no_contacts_description:
en: "Your recently contacts will appear here."
contact_existed:
en: "Contact already added"
description:
en: "Start a conversation with someone using their npub or NIP-05 (like foo@bar.com)."
subject_label:
en: "Subject:"
sidebar:
reload_menu:
en: "Reload"
status_menu:
en: "Relay Status"
search_label:
en: "Find or start a conversation"
search_tooltip:
en: "Press Enter to search"
empty:
en: "There are no users matching query %{query}"
search_in_progress:
en: "There is another search in progress"
addr_error:
en: "Failed to get profile via address"
direct_messages:
en: "Direct Messages"
dm_tooltip:
en: "Create DM or Group DM"
all_button:
en: "All"
all_conversations_tooltip:
en: "All ongoing conversations"
requests_button:
en: "Requests"
requests_tooltip:
en: "Incoming new conversations"
trusted_contacts_tooltip:
en: "Only show rooms from trusted contacts"
no_requests:
en: "No message requests"
no_requests_label:
en: "New message requests from people you don't know will appear here."
no_conversations:
en: "No conversations"
no_conversations_label:
en: "Start a conversation with someone to get started."
loading:
label:
en: "Getting messages. This may take a while..."
tooltip:
en: "The progress runs in the background. It doesn't affect your experience."