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"
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]]
name = "arg_enum_proc_macro"
version = "0.3.4"
@@ -625,12 +616,6 @@ dependencies = [
"fs_extra",
]
[[package]]
name = "base62"
version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1adf9755786e27479693dedd3271691a92b5e242ab139cacb9fb8e7fb5381111"
[[package]]
name = "base64"
version = "0.22.1"
@@ -1335,7 +1320,6 @@ dependencies = [
"futures",
"gpui",
"gpui_tokio",
"i18n",
"indexset",
"itertools 0.13.0",
"key_store",
@@ -1346,7 +1330,6 @@ dependencies = [
"person",
"relay_auth",
"reqwest_client",
"rust-i18n",
"serde",
"serde_json",
"settings",
@@ -2518,17 +2501,6 @@ dependencies = [
"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]]
name = "gloo-timers"
version = "0.3.0"
@@ -3037,13 +3009,6 @@ dependencies = [
"windows-registry 0.6.1",
]
[[package]]
name = "i18n"
version = "0.3.0"
dependencies = [
"rust-i18n",
]
[[package]]
name = "iana-time-zone"
version = "0.1.64"
@@ -3170,22 +3135,6 @@ dependencies = [
"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]]
name = "image"
version = "0.25.9"
@@ -3339,15 +3288,6 @@ dependencies = [
"once_cell",
]
[[package]]
name = "itertools"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.13.0"
@@ -3975,15 +3915,6 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "nostr"
version = "0.44.1"
@@ -5432,60 +5363,6 @@ dependencies = [
"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]]
name = "rust-ini"
version = "0.17.0"
@@ -5971,19 +5848,6 @@ dependencies = [
"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]]
name = "settings"
version = "0.3.0"
@@ -6713,11 +6577,9 @@ dependencies = [
"anyhow",
"common",
"gpui",
"i18n",
"linicon",
"log",
"nostr-sdk",
"rust-i18n",
"smallvec",
"smol",
"theme",
@@ -7007,17 +6869,6 @@ dependencies = [
"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]]
name = "try-lock"
version = "0.2.5"
@@ -7207,12 +7058,6 @@ dependencies = [
"subtle",
]
[[package]]
name = "unsafe-libyaml"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]]
name = "untrusted"
version = "0.9.0"

View File

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

View File

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

View File

@@ -13,7 +13,6 @@ use gpui::{
InteractiveElement, IntoElement, ParentElement, Render, SharedString,
StatefulInteractiveElement, Styled, Subscription, Window,
};
use i18n::{shared_t, t};
use key_store::{Credential, KeyItem, KeyStore};
use nostr_connect::prelude::*;
use person::PersonRegistry;
@@ -230,7 +229,7 @@ impl ChatSpace {
window.open_modal(cx, move |modal, _window, _cx| {
modal
.title(shared_t!("common.preferences"))
.title(SharedString::from("Preferences"))
.width(px(520.))
.child(view.clone())
});
@@ -291,9 +290,9 @@ impl ChatSpace {
let entity = entity.clone();
this.confirm()
.title(shared_t!("relays.modal"))
.title(SharedString::from("Set Up Messaging Relays"))
.child(view.clone())
.button_props(ModalButtonProps::default().ok_text(t!("common.update")))
.button_props(ModalButtonProps::default().ok_text("Update"))
.on_ok(move |_, window, cx| {
entity
.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>) {
let Ok(bech32) = ev.0.to_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>) {
window.open_modal(cx, move |this, _window, _cx| {
this.show_close(true)
.title(shared_t!("keyring_disable.label"))
.title(SharedString::from("Keyring is disabled"))
.child(
v_flex()
.gap_2()
.pb_4()
.text_sm()
.child(shared_t!("keyring_disable.body_1"))
.child(shared_t!("keyring_disable.body_2"))
.child(shared_t!("keyring_disable.body_3")),
.child(SharedString::from("Coop cannot access the Keyring Service on your system. By design, Coop uses Keyring to store your credentials."))
.child(SharedString::from("Without access to Keyring, Coop will store your credentials as plain text."))
.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()
.rounded_full()
.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)
.hover(|this| this.bg(cx.theme().warning_hover))
.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| {
relay_auth.update(cx, |this, cx| {
this.re_ask(window, cx);

View File

@@ -7,7 +7,6 @@ use gpui::{
div, relative, AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle,
Focusable, IntoElement, ParentElement, Render, SharedString, Styled, Subscription, Window,
};
use i18n::{shared_t, t};
use key_store::{KeyItem, KeyStore};
use nostr_connect::prelude::*;
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>) {
let Ok(uri) = NostrConnectUri::parse(content) else {
self.set_error(t!("login.bunker_invalid"), cx);
self.set_error("Bunker is not valid", cx);
return;
};
@@ -396,7 +395,7 @@ impl Render for Login {
})
.child(
Button::new("login")
.label(t!("common.continue"))
.label("Continue")
.primary()
.loading(self.logging_in)
.disabled(self.logging_in)
@@ -410,7 +409,10 @@ impl Render for Login {
.text_xs()
.text_center()
.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| {

View File

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

View File

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

View File

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

View File

@@ -12,7 +12,6 @@ use gpui::{
RetainAllImageCache, SharedString, Styled, Subscription, Task, Window,
};
use gpui_tokio::Tokio;
use i18n::{shared_t, t};
use list_item::RoomListItem;
use nostr_sdk::prelude::*;
use settings::AppSettings;
@@ -69,7 +68,7 @@ impl Sidebar {
let search_results = cx.new(|_| None);
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 mut subscriptions = smallvec![];
@@ -432,12 +431,12 @@ impl Sidebar {
room
} 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;
};
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;
};
@@ -456,7 +455,7 @@ impl Sidebar {
ChatRegistry::global(cx).update(cx, |this, 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>) {
@@ -492,7 +491,7 @@ impl Sidebar {
this.show_close(true)
.overlay_closable(true)
.keyboard(true)
.title(shared_t!("manage_relays.modal"))
.title(SharedString::from("Messaging Relay Status"))
.child(v_flex().pb_4().gap_2().children({
let mut items = Vec::with_capacity(relays.len());
@@ -524,10 +523,9 @@ impl Sidebar {
.child(url),
)
.child(
div()
.text_right()
.text_color(cx.theme().text_muted)
.child(shared_t!("manage_relays.time", t = time)),
div().text_right().text_color(cx.theme().text_muted).child(
SharedString::from(format!("Last activity: {}", time)),
),
),
);
}
@@ -649,7 +647,7 @@ impl Render for Sidebar {
this.suffix(
Button::new("find")
.icon(IconName::Search)
.tooltip(t!("sidebar.search_tooltip"))
.tooltip("Press Enter to search")
.transparent()
.small(),
)
@@ -675,8 +673,8 @@ impl Render for Sidebar {
.flex_none()
.child(
Button::new("all")
.label(t!("sidebar.all_button"))
.tooltip(t!("sidebar.all_conversations_tooltip"))
.label("All")
.tooltip("All ongoing conversations")
.when_some(self.indicator.read(cx).as_ref(), |this, kind| {
this.when(kind == &RoomKind::Ongoing, |this| {
this.child(
@@ -696,8 +694,8 @@ impl Render for Sidebar {
)
.child(
Button::new("requests")
.label(t!("sidebar.requests_button"))
.tooltip(t!("sidebar.requests_tooltip"))
.label("Requests")
.tooltip("Incoming new conversations")
.when_some(self.indicator.read(cx).as_ref(), |this, kind| {
this.when(kind != &RoomKind::Ongoing, |this| {
this.child(
@@ -730,11 +728,11 @@ impl Render for Sidebar {
.rounded()
.popup_menu(move |this, _window, _cx| {
this.menu(
t!("sidebar.reload_menu"),
"Reload",
Box::new(Reload),
)
.menu(
t!("sidebar.status_menu"),
"Relay Status",
Box::new(RelayStatus),
)
}),
@@ -757,14 +755,14 @@ impl Render for Sidebar {
.text_sm()
.font_semibold()
.line_height(relative(1.25))
.child(shared_t!("sidebar.no_conversations")),
.child(SharedString::from("No conversations")),
)
.child(
div()
.text_xs()
.text_color(cx.theme().text_muted)
.line_height(relative(1.25))
.child(shared_t!("sidebar.no_conversations_label")),
.child(SharedString::from("Start a conversation with someone to get started.")),
),
))
} else {
@@ -781,14 +779,14 @@ impl Render for Sidebar {
.text_sm()
.font_semibold()
.line_height(relative(1.25))
.child(shared_t!("sidebar.no_requests")),
.child(SharedString::from("No message requests")),
)
.child(
div()
.text_xs()
.text_color(cx.theme().text_muted)
.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,
};
use gpui_tokio::Tokio;
use i18n::{shared_t, t};
use nostr_sdk::prelude::*;
use person::PersonRegistry;
use settings::AppSettings;
@@ -41,9 +40,9 @@ pub fn compose_button() -> impl IntoElement {
window.open_modal(cx, move |modal, _window, cx| {
let weak_view = weak_view.clone();
let label = if compose.read(cx).selected(cx).len() > 1 {
shared_t!("compose.create_group_dm_button")
SharedString::from("Create Group DM")
} else {
shared_t!("compose.create_dm_button")
SharedString::from("Create DM")
};
modal
@@ -52,7 +51,7 @@ pub fn compose_button() -> impl IntoElement {
.keyboard(true)
.show_close(true)
.button_props(ModalButtonProps::default().ok_text(label))
.title(shared_t!("sidebar.direct_messages"))
.title(SharedString::from("Direct Messages"))
.child(compose.clone())
.on_ok(move |_, window, cx| {
weak_view
@@ -238,7 +237,7 @@ impl Compose {
});
});
} 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()
.text_sm()
.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| {
this.child(
@@ -440,7 +439,7 @@ impl Render for Compose {
div()
.text_sm()
.font_semibold()
.child(shared_t!("compose.subject_label")),
.child(SharedString::from("Subject:")),
)
.child(TextInput::new(&self.title_input).small().appearance(false)),
)
@@ -455,7 +454,7 @@ impl Render for Compose {
div()
.text_sm()
.font_semibold()
.child(shared_t!("compose.to_label")),
.child(SharedString::from("To:")),
)
.child(
TextInput::new(&self.user_input)
@@ -487,12 +486,12 @@ impl Render for Compose {
div()
.font_semibold()
.line_height(relative(1.2))
.child(shared_t!("compose.no_contacts_message")),
.child(SharedString::from("No contacts")),
)
.child(
div()
.text_color(cx.theme().text_muted)
.child(shared_t!("compose.no_contacts_description")),
.child(SharedString::from("Your recently contacts will appear here.")),
),
)
} else {

View File

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

View File

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

View File

@@ -7,7 +7,6 @@ use gpui::{
InteractiveElement, IntoElement, ParentElement, Render, SharedString, Styled, Task, Window,
};
use gpui_tokio::Tokio;
use i18n::{shared_t, t};
use nostr_sdk::prelude::*;
use person::PersonRegistry;
use settings::AppSettings;
@@ -176,7 +175,7 @@ impl Screening {
if task.await.is_ok() {
cx.update(|window, cx| {
window.close_modal(cx);
window.push_notification(t!("screening.report_msg"), cx);
window.push_notification("Report submitted successfully", cx);
})
.ok();
}
@@ -191,7 +190,7 @@ impl Screening {
let contacts = contacts.clone();
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(
uniform_list("contacts", total, move |range, _window, cx| {
let mut items = Vec::with_capacity(total);
@@ -270,7 +269,7 @@ impl Render for Screening {
.gap_1()
.child(
Button::new("njump")
.label(t!("profile.njump"))
.label("View on njump.me")
.secondary()
.small()
.rounded()
@@ -280,7 +279,7 @@ impl Render for Screening {
)
.child(
Button::new("report")
.tooltip(t!("screening.report"))
.tooltip("Report as a scam or impostor")
.icon(IconName::Report)
.danger()
.rounded()
@@ -302,16 +301,16 @@ impl Render for Screening {
.child(
v_flex()
.text_sm()
.child(shared_t!("screening.contact_label"))
.child(SharedString::from("Contact"))
.child(
div()
.line_clamp(1)
.text_color(cx.theme().text_muted)
.child({
if self.followed {
shared_t!("screening.contact")
SharedString::from("This person is one of your contacts.")
} 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(
h_flex()
.gap_0p5()
.child(shared_t!("screening.active_label"))
.child(SharedString::from("Activity on Public Relays"))
.child(
Button::new("active")
.icon(IconName::Info)
.xsmall()
.ghost()
.rounded()
.tooltip(t!("screening.active_tooltip")),
.tooltip("This may be inaccurate if the user only publishes to their private relays."),
),
)
.child(
@@ -346,12 +345,12 @@ impl Render for Screening {
.text_color(cx.theme().text_muted)
.map(|this| {
if let Some(date) = self.last_active {
this.child(shared_t!(
"screening.active_at",
d = date.to_human_time()
))
this.child(SharedString::from(format!(
"Last active: {}.",
date.to_human_time()
)))
} 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()
.child({
if let Some(addr) = self.address(cx) {
shared_t!("screening.nip05_addr", addr = addr)
SharedString::from(format!("{} validation", addr))
} else {
shared_t!("screening.nip05_label")
SharedString::from("Friendly Address (NIP-05) validation")
}
})
.child(
@@ -379,12 +378,12 @@ impl Render for Screening {
.child({
if self.address(cx).is_some() {
if self.verified {
shared_t!("screening.nip05_ok")
SharedString::from("The address matches the user's public key.")
} else {
shared_t!("screening.nip05_failed")
SharedString::from("The address does not match the user's public key.")
}
} 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(
h_flex()
.gap_0p5()
.child(shared_t!("screening.mutual_label"))
.child(SharedString::from("Mutual contacts"))
.child(
Button::new("mutuals")
.icon(IconName::Info)
@@ -421,9 +420,12 @@ impl Render for Screening {
.text_color(cx.theme().text_muted)
.child({
if total_mutuals > 0 {
shared_t!("screening.mutual", u = total_mutuals)
SharedString::from(format!(
"You have {} mutual contacts with this person.",
total_mutuals
))
} 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,
Window,
};
use i18n::{shared_t, t};
use nostr_sdk::prelude::*;
use smallvec::{smallvec, SmallVec};
use state::NostrRegistry;
@@ -149,7 +148,11 @@ impl SetupRelay {
pub fn set_relays(&mut self, window: &mut Window, cx: &mut Context<Self>) {
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;
};
@@ -272,7 +275,7 @@ impl SetupRelay {
.justify_center()
.text_sm()
.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(
div()
.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(
v_flex()
@@ -297,7 +300,7 @@ impl Render for SetupRelay {
.child(
Button::new("add")
.icon(IconName::PlusFill)
.label(t!("common.add"))
.label("Add")
.ghost()
.on_click(cx.listener(move |this, _, window, cx| {
this.add(window, cx);

View File

@@ -8,7 +8,6 @@ use gpui::{
RetainAllImageCache, SharedString, StatefulInteractiveElement, Styled, Subscription, Task,
Window,
};
use i18n::{shared_t, t};
use key_store::{Credential, KeyItem, KeyStore};
use nostr_connect::prelude::*;
use person::PersonRegistry;
@@ -147,7 +146,10 @@ impl Startup {
)
}
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);
}
Err(e) => {
@@ -231,12 +233,14 @@ impl Render for Startup {
.text_xl()
.font_semibold()
.line_height(relative(1.3))
.child(shared_t!("welcome.title")),
.child(SharedString::from("Welcome to Coop")),
)
.child(
div()
.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);
})),
)
.child(
Button::new("logout")
.label(t!("user.sign_out"))
.ghost()
.on_click(|_, _window, cx| {
.child(Button::new("logout").label("Sign out").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" }
ui = { path = "../ui" }
rust-i18n.workspace = true
i18n.workspace = true
nostr-sdk.workspace = true
gpui.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."