i18n: make localization context non-global
- Simplify Localization{Context,Manager} to just Localization
- Fixed a bunch of lifetime issueo
- Removed all Arcs and Locks
- Removed globals
* widgets now need access to &mut Localization for i18n
Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
@@ -323,6 +323,7 @@ pub fn render_note_contents(
|
||||
&supported_medias,
|
||||
carousel_id,
|
||||
trusted_media,
|
||||
note_context.i18n,
|
||||
);
|
||||
ui.add_space(2.0);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use egui::{Rect, Vec2};
|
||||
use nostrdb::NoteKey;
|
||||
use notedeck::{tr, BroadcastContext, NoteContextSelection};
|
||||
use notedeck::{tr, BroadcastContext, Localization, NoteContextSelection};
|
||||
|
||||
pub struct NoteContextButton {
|
||||
put_at: Option<Rect>,
|
||||
@@ -105,24 +105,17 @@ impl NoteContextButton {
|
||||
#[profiling::function]
|
||||
pub fn menu(
|
||||
ui: &mut egui::Ui,
|
||||
i18n: &mut Localization,
|
||||
button_response: egui::Response,
|
||||
) -> Option<NoteContextSelection> {
|
||||
let mut context_selection: Option<NoteContextSelection> = None;
|
||||
|
||||
// Debug: Check if global i18n is available
|
||||
if let Some(i18n) = notedeck::i18n::get_global_i18n() {
|
||||
if let Ok(locale) = i18n.get_current_locale() {
|
||||
tracing::debug!("Current locale in context menu: {}", locale);
|
||||
}
|
||||
} else {
|
||||
tracing::warn!("Global i18n context not available in context menu");
|
||||
}
|
||||
|
||||
stationary_arbitrary_menu_button(ui, button_response, |ui| {
|
||||
ui.set_max_width(200.0);
|
||||
|
||||
// Debug: Check what the tr! macro returns
|
||||
let copy_text = tr!(
|
||||
i18n,
|
||||
"Copy Text",
|
||||
"Copy the text content of the note to clipboard"
|
||||
);
|
||||
@@ -134,6 +127,7 @@ impl NoteContextButton {
|
||||
}
|
||||
if ui
|
||||
.button(tr!(
|
||||
i18n,
|
||||
"Copy Pubkey",
|
||||
"Copy the author's public key to clipboard"
|
||||
))
|
||||
@@ -144,6 +138,7 @@ impl NoteContextButton {
|
||||
}
|
||||
if ui
|
||||
.button(tr!(
|
||||
i18n,
|
||||
"Copy Note ID",
|
||||
"Copy the unique note identifier to clipboard"
|
||||
))
|
||||
@@ -154,6 +149,7 @@ impl NoteContextButton {
|
||||
}
|
||||
if ui
|
||||
.button(tr!(
|
||||
i18n,
|
||||
"Copy Note JSON",
|
||||
"Copy the raw note data in JSON format to clipboard"
|
||||
))
|
||||
@@ -164,6 +160,7 @@ impl NoteContextButton {
|
||||
}
|
||||
if ui
|
||||
.button(tr!(
|
||||
i18n,
|
||||
"Broadcast",
|
||||
"Broadcast the note to all connected relays"
|
||||
))
|
||||
@@ -176,6 +173,7 @@ impl NoteContextButton {
|
||||
}
|
||||
if ui
|
||||
.button(tr!(
|
||||
i18n,
|
||||
"Broadcast Local",
|
||||
"Broadcast the note only to local network relays"
|
||||
))
|
||||
|
||||
@@ -6,8 +6,8 @@ use egui::{
|
||||
};
|
||||
use notedeck::{
|
||||
fonts::get_font_size, note::MediaAction, show_one_error_message, supported_mime_hosted_at_url,
|
||||
tr, GifState, GifStateMap, Images, JobPool, MediaCache, MediaCacheType, NotedeckTextStyle,
|
||||
TexturedImage, TexturesCache, UrlMimes,
|
||||
tr, GifState, GifStateMap, Images, JobPool, Localization, MediaCache, MediaCacheType,
|
||||
NotedeckTextStyle, TexturedImage, TexturesCache, UrlMimes,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -20,6 +20,7 @@ use crate::{
|
||||
AnimationHelper, PulseAlpha,
|
||||
};
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn image_carousel(
|
||||
ui: &mut egui::Ui,
|
||||
img_cache: &mut Images,
|
||||
@@ -28,6 +29,7 @@ pub(crate) fn image_carousel(
|
||||
medias: &[RenderableMedia],
|
||||
carousel_id: egui::Id,
|
||||
trusted_media: bool,
|
||||
i18n: &mut Localization,
|
||||
) -> Option<MediaAction> {
|
||||
// let's make sure everything is within our area
|
||||
|
||||
@@ -69,9 +71,14 @@ pub(crate) fn image_carousel(
|
||||
blur_type.clone(),
|
||||
);
|
||||
|
||||
if let Some(cur_action) =
|
||||
render_media(ui, &mut img_cache.gif_states, media_state, url, height)
|
||||
{
|
||||
if let Some(cur_action) = render_media(
|
||||
ui,
|
||||
&mut img_cache.gif_states,
|
||||
media_state,
|
||||
url,
|
||||
height,
|
||||
i18n,
|
||||
) {
|
||||
// clicked the media, lets set the active index
|
||||
if let MediaUIAction::Clicked = cur_action {
|
||||
set_show_popup(ui, popup_id(carousel_id), true);
|
||||
@@ -100,7 +107,14 @@ pub(crate) fn image_carousel(
|
||||
|
||||
let current_image_index = update_selected_image_index(ui, carousel_id, medias.len() as i32);
|
||||
|
||||
show_full_screen_media(ui, medias, current_image_index, img_cache, carousel_id);
|
||||
show_full_screen_media(
|
||||
ui,
|
||||
medias,
|
||||
current_image_index,
|
||||
img_cache,
|
||||
carousel_id,
|
||||
i18n,
|
||||
);
|
||||
}
|
||||
action
|
||||
}
|
||||
@@ -163,6 +177,7 @@ fn show_full_screen_media(
|
||||
index: usize,
|
||||
img_cache: &mut Images,
|
||||
carousel_id: egui::Id,
|
||||
i18n: &mut Localization,
|
||||
) {
|
||||
Window::new("image_popup")
|
||||
.title_bar(false)
|
||||
@@ -201,6 +216,7 @@ fn show_full_screen_media(
|
||||
cur_state.gifs,
|
||||
image_url,
|
||||
carousel_id,
|
||||
i18n,
|
||||
);
|
||||
})
|
||||
});
|
||||
@@ -363,6 +379,7 @@ fn select_next_media(
|
||||
next as usize
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn render_full_screen_media(
|
||||
ui: &mut egui::Ui,
|
||||
num_urls: usize,
|
||||
@@ -371,6 +388,7 @@ fn render_full_screen_media(
|
||||
gifs: &mut HashMap<String, GifState>,
|
||||
image_url: &str,
|
||||
carousel_id: egui::Id,
|
||||
i18n: &mut Localization,
|
||||
) {
|
||||
const TOP_BAR_HEIGHT: f32 = 30.0;
|
||||
const BOTTOM_BAR_HEIGHT: f32 = 60.0;
|
||||
@@ -631,13 +649,17 @@ fn render_full_screen_media(
|
||||
});
|
||||
}
|
||||
|
||||
copy_link(image_url, &response);
|
||||
copy_link(i18n, image_url, &response);
|
||||
}
|
||||
|
||||
fn copy_link(url: &str, img_resp: &Response) {
|
||||
fn copy_link(i18n: &mut Localization, url: &str, img_resp: &Response) {
|
||||
img_resp.context_menu(|ui| {
|
||||
if ui
|
||||
.button(tr!("Copy Link", "Button to copy media link to clipboard"))
|
||||
.button(tr!(
|
||||
i18n,
|
||||
"Copy Link",
|
||||
"Button to copy media link to clipboard"
|
||||
))
|
||||
.clicked()
|
||||
{
|
||||
ui.ctx().copy_text(url.to_owned());
|
||||
@@ -653,10 +675,11 @@ fn render_media(
|
||||
render_state: MediaRenderState,
|
||||
url: &str,
|
||||
height: f32,
|
||||
i18n: &mut Localization,
|
||||
) -> Option<MediaUIAction> {
|
||||
match render_state {
|
||||
MediaRenderState::ActualImage(image) => {
|
||||
if render_success_media(ui, url, image, gifs, height).clicked() {
|
||||
if render_success_media(ui, url, image, gifs, height, i18n).clicked() {
|
||||
Some(MediaUIAction::Clicked)
|
||||
} else {
|
||||
None
|
||||
@@ -695,9 +718,9 @@ fn render_media(
|
||||
let resp = match obfuscated_texture {
|
||||
ObfuscatedTexture::Blur(texture_handle) => {
|
||||
let resp = ui.add(texture_to_image(texture_handle, height));
|
||||
render_blur_text(ui, url, resp.rect)
|
||||
render_blur_text(ui, i18n, url, resp.rect)
|
||||
}
|
||||
ObfuscatedTexture::Default => render_default_blur(ui, height, url),
|
||||
ObfuscatedTexture::Default => render_default_blur(ui, i18n, height, url),
|
||||
};
|
||||
|
||||
if resp
|
||||
@@ -712,7 +735,12 @@ fn render_media(
|
||||
}
|
||||
}
|
||||
|
||||
fn render_blur_text(ui: &mut egui::Ui, url: &str, render_rect: egui::Rect) -> egui::Response {
|
||||
fn render_blur_text(
|
||||
ui: &mut egui::Ui,
|
||||
i18n: &mut Localization,
|
||||
url: &str,
|
||||
render_rect: egui::Rect,
|
||||
) -> egui::Response {
|
||||
let helper = AnimationHelper::new_from_rect(ui, ("show_media", url), render_rect);
|
||||
|
||||
let painter = ui.painter_at(helper.get_animation_rect());
|
||||
@@ -726,6 +754,7 @@ fn render_blur_text(ui: &mut egui::Ui, url: &str, render_rect: egui::Rect) -> eg
|
||||
);
|
||||
let info_galley = painter.layout(
|
||||
tr!(
|
||||
i18n,
|
||||
"Media from someone you don't follow",
|
||||
"Text shown on blurred media from unfollowed users"
|
||||
)
|
||||
@@ -736,7 +765,7 @@ fn render_blur_text(ui: &mut egui::Ui, url: &str, render_rect: egui::Rect) -> eg
|
||||
);
|
||||
|
||||
let load_galley = painter.layout_no_wrap(
|
||||
tr!("Tap to Load", "Button text to load blurred media").to_owned(),
|
||||
tr!(i18n, "Tap to Load", "Button text to load blurred media"),
|
||||
animation_fontid,
|
||||
egui::Color32::BLACK,
|
||||
// ui.visuals().widgets.inactive.bg_fill,
|
||||
@@ -792,9 +821,14 @@ fn render_blur_text(ui: &mut egui::Ui, url: &str, render_rect: egui::Rect) -> eg
|
||||
helper.take_animation_response()
|
||||
}
|
||||
|
||||
fn render_default_blur(ui: &mut egui::Ui, height: f32, url: &str) -> egui::Response {
|
||||
fn render_default_blur(
|
||||
ui: &mut egui::Ui,
|
||||
i18n: &mut Localization,
|
||||
height: f32,
|
||||
url: &str,
|
||||
) -> egui::Response {
|
||||
let rect = render_default_blur_bg(ui, height, url, false);
|
||||
render_blur_text(ui, url, rect)
|
||||
render_blur_text(ui, i18n, url, rect)
|
||||
}
|
||||
|
||||
fn render_default_blur_bg(ui: &mut egui::Ui, height: f32, url: &str, shimmer: bool) -> egui::Rect {
|
||||
@@ -883,12 +917,13 @@ fn render_success_media(
|
||||
tex: &mut TexturedImage,
|
||||
gifs: &mut GifStateMap,
|
||||
height: f32,
|
||||
i18n: &mut Localization,
|
||||
) -> Response {
|
||||
let texture = handle_repaint(ui, retrieve_latest_texture(url, gifs, tex));
|
||||
let img = texture_to_image(texture, height);
|
||||
let img_resp = ui.add(Button::image(img).frame(false));
|
||||
|
||||
copy_link(url, &img_resp);
|
||||
copy_link(i18n, url, &img_resp);
|
||||
|
||||
img_resp
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ use notedeck::note::MediaAction;
|
||||
use notedeck::note::ZapTargetAmount;
|
||||
use notedeck::ui::is_narrow;
|
||||
use notedeck::Images;
|
||||
use notedeck::Localization;
|
||||
pub use options::NoteOptions;
|
||||
pub use reply_description::reply_desc;
|
||||
|
||||
@@ -27,8 +28,8 @@ use nostrdb::{Ndb, Note, NoteKey, ProfileRecord, Transaction};
|
||||
use notedeck::{
|
||||
name::get_display_name,
|
||||
note::{NoteAction, NoteContext, ZapAction},
|
||||
tr, AnyZapState, CachedNote, ContextSelection, NoteCache, NoteZapTarget, NoteZapTargetOwned,
|
||||
NotedeckTextStyle, ZapTarget, Zaps,
|
||||
tr, AnyZapState, ContextSelection, NoteZapTarget, NoteZapTargetOwned, NotedeckTextStyle,
|
||||
ZapTarget, Zaps,
|
||||
};
|
||||
|
||||
pub struct NoteView<'a, 'd> {
|
||||
@@ -194,7 +195,6 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
||||
}
|
||||
|
||||
fn textmode_ui(&mut self, ui: &mut egui::Ui) -> egui::Response {
|
||||
let note_key = self.note.key().expect("todo: implement non-db notes");
|
||||
let txn = self.note.txn().expect("todo: implement non-db notes");
|
||||
|
||||
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
||||
@@ -206,23 +206,22 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
||||
//ui.horizontal(|ui| {
|
||||
ui.spacing_mut().item_spacing.x = 2.0;
|
||||
|
||||
let cached_note = self
|
||||
.note_context
|
||||
.note_cache
|
||||
.cached_note_or_insert_mut(note_key, self.note);
|
||||
|
||||
let (_id, rect) = ui.allocate_space(egui::vec2(50.0, 20.0));
|
||||
ui.allocate_rect(rect, Sense::hover());
|
||||
ui.put(rect, |ui: &mut egui::Ui| {
|
||||
render_reltime(ui, cached_note, false).response
|
||||
render_reltime(ui, self.note_context.i18n, self.note.created_at(), false).response
|
||||
});
|
||||
let (_id, rect) = ui.allocate_space(egui::vec2(150.0, 20.0));
|
||||
ui.allocate_rect(rect, Sense::hover());
|
||||
ui.put(rect, |ui: &mut egui::Ui| {
|
||||
ui.add(
|
||||
Username::new(profile.as_ref().ok(), self.note.pubkey())
|
||||
.abbreviated(6)
|
||||
.pk_colored(true),
|
||||
Username::new(
|
||||
self.note_context.i18n,
|
||||
profile.as_ref().ok(),
|
||||
self.note.pubkey(),
|
||||
)
|
||||
.abbreviated(6)
|
||||
.pk_colored(true),
|
||||
)
|
||||
});
|
||||
|
||||
@@ -308,9 +307,13 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
||||
let color = ui.style().visuals.noninteractive().fg_stroke.color;
|
||||
ui.add_space(4.0);
|
||||
ui.label(
|
||||
RichText::new(tr!("Reposted", "Label for reposted notes"))
|
||||
.color(color)
|
||||
.text_style(style.text_style()),
|
||||
RichText::new(tr!(
|
||||
self.note_context.i18n,
|
||||
"Reposted",
|
||||
"Label for reposted notes"
|
||||
))
|
||||
.color(color)
|
||||
.text_style(style.text_style()),
|
||||
);
|
||||
});
|
||||
NoteView::new(self.note_context, ¬e_to_repost, self.flags, self.jobs).show(ui)
|
||||
@@ -348,20 +351,17 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
||||
#[profiling::function]
|
||||
fn note_header(
|
||||
ui: &mut egui::Ui,
|
||||
note_cache: &mut NoteCache,
|
||||
i18n: &mut Localization,
|
||||
note: &Note,
|
||||
profile: &Result<nostrdb::ProfileRecord<'_>, nostrdb::Error>,
|
||||
show_unread_indicator: bool,
|
||||
) {
|
||||
let note_key = note.key().unwrap();
|
||||
|
||||
let horiz_resp = ui
|
||||
.horizontal(|ui| {
|
||||
ui.spacing_mut().item_spacing.x = if is_narrow(ui.ctx()) { 1.0 } else { 2.0 };
|
||||
ui.add(Username::new(profile.as_ref().ok(), note.pubkey()).abbreviated(20));
|
||||
ui.add(Username::new(i18n, profile.as_ref().ok(), note.pubkey()).abbreviated(20));
|
||||
|
||||
let cached_note = note_cache.cached_note_or_insert_mut(note_key, note);
|
||||
render_reltime(ui, cached_note, true);
|
||||
render_reltime(ui, i18n, note.created_at(), true);
|
||||
})
|
||||
.response;
|
||||
|
||||
@@ -405,7 +405,7 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
||||
ui.horizontal_centered(|ui| {
|
||||
NoteView::note_header(
|
||||
ui,
|
||||
self.note_context.note_cache,
|
||||
self.note_context.i18n,
|
||||
self.note,
|
||||
profile,
|
||||
self.show_unread_indicator,
|
||||
@@ -460,10 +460,16 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
||||
cur_acc: cur_acc.keypair(),
|
||||
})
|
||||
};
|
||||
note_action =
|
||||
render_note_actionbar(ui, zapper, self.note.id(), self.note.pubkey(), note_key)
|
||||
.inner
|
||||
.or(note_action);
|
||||
note_action = render_note_actionbar(
|
||||
ui,
|
||||
zapper,
|
||||
self.note.id(),
|
||||
self.note.pubkey(),
|
||||
note_key,
|
||||
self.note_context.i18n,
|
||||
)
|
||||
.inner
|
||||
.or(note_action);
|
||||
}
|
||||
|
||||
NoteUiResponse {
|
||||
@@ -489,7 +495,7 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
||||
ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| {
|
||||
NoteView::note_header(
|
||||
ui,
|
||||
self.note_context.note_cache,
|
||||
self.note_context.i18n,
|
||||
self.note,
|
||||
profile,
|
||||
self.show_unread_indicator,
|
||||
@@ -542,6 +548,7 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
||||
self.note.id(),
|
||||
self.note.pubkey(),
|
||||
note_key,
|
||||
self.note_context.i18n,
|
||||
)
|
||||
.inner
|
||||
.or(note_action);
|
||||
@@ -588,7 +595,8 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
||||
};
|
||||
|
||||
let resp = ui.add(NoteContextButton::new(note_key).place_at(context_pos));
|
||||
if let Some(action) = NoteContextButton::menu(ui, resp.clone()) {
|
||||
if let Some(action) = NoteContextButton::menu(ui, self.note_context.i18n, resp.clone())
|
||||
{
|
||||
note_action = Some(NoteAction::Context(ContextSelection { note_key, action }));
|
||||
}
|
||||
}
|
||||
@@ -765,11 +773,13 @@ fn render_note_actionbar(
|
||||
note_id: &[u8; 32],
|
||||
note_pubkey: &[u8; 32],
|
||||
note_key: NoteKey,
|
||||
i18n: &mut Localization,
|
||||
) -> egui::InnerResponse<Option<NoteAction>> {
|
||||
ui.horizontal(|ui| 's: {
|
||||
let reply_resp = reply_button(ui, note_key).on_hover_cursor(egui::CursorIcon::PointingHand);
|
||||
let reply_resp =
|
||||
reply_button(ui, i18n, note_key).on_hover_cursor(egui::CursorIcon::PointingHand);
|
||||
let quote_resp =
|
||||
quote_repost_button(ui, note_key).on_hover_cursor(egui::CursorIcon::PointingHand);
|
||||
quote_repost_button(ui, i18n, note_key).on_hover_cursor(egui::CursorIcon::PointingHand);
|
||||
|
||||
let to_noteid = |id: &[u8; 32]| NoteId::new(*id);
|
||||
if reply_resp.clicked() {
|
||||
@@ -804,7 +814,7 @@ fn render_note_actionbar(
|
||||
cur_acc.secret_key.as_ref()?;
|
||||
|
||||
match zap_state {
|
||||
Ok(any_zap_state) => ui.add(zap_button(any_zap_state, note_id)),
|
||||
Ok(any_zap_state) => ui.add(zap_button(i18n, any_zap_state, note_id)),
|
||||
Err(err) => {
|
||||
let (rect, _) =
|
||||
ui.allocate_at_least(egui::vec2(10.0, 10.0), egui::Sense::click());
|
||||
@@ -832,7 +842,8 @@ fn render_note_actionbar(
|
||||
#[profiling::function]
|
||||
fn render_reltime(
|
||||
ui: &mut egui::Ui,
|
||||
note_cache: &mut CachedNote,
|
||||
i18n: &mut Localization,
|
||||
created_at: u64,
|
||||
before: bool,
|
||||
) -> egui::InnerResponse<()> {
|
||||
ui.horizontal(|ui| {
|
||||
@@ -840,7 +851,7 @@ fn render_reltime(
|
||||
secondary_label(ui, "⋅");
|
||||
}
|
||||
|
||||
secondary_label(ui, note_cache.reltime_str_mut());
|
||||
secondary_label(ui, notedeck::time_ago_since(i18n, created_at));
|
||||
|
||||
if !before {
|
||||
secondary_label(ui, "⋅");
|
||||
@@ -848,7 +859,7 @@ fn render_reltime(
|
||||
})
|
||||
}
|
||||
|
||||
fn reply_button(ui: &mut egui::Ui, note_key: NoteKey) -> egui::Response {
|
||||
fn reply_button(ui: &mut egui::Ui, i18n: &mut Localization, note_key: NoteKey) -> egui::Response {
|
||||
let img = if ui.style().visuals.dark_mode {
|
||||
app_images::reply_dark_image()
|
||||
} else {
|
||||
@@ -862,9 +873,11 @@ fn reply_button(ui: &mut egui::Ui, note_key: NoteKey) -> egui::Response {
|
||||
let expand_size = 5.0; // from hover_expand_small
|
||||
let rect = rect.translate(egui::vec2(-(expand_size / 2.0), 0.0));
|
||||
|
||||
let put_resp = ui
|
||||
.put(rect, img.max_width(size))
|
||||
.on_hover_text(tr!("Reply to this note", "Hover text for reply button"));
|
||||
let put_resp = ui.put(rect, img.max_width(size)).on_hover_text(tr!(
|
||||
i18n,
|
||||
"Reply to this note",
|
||||
"Hover text for reply button"
|
||||
));
|
||||
|
||||
resp.union(put_resp)
|
||||
}
|
||||
@@ -877,7 +890,11 @@ fn repost_icon(dark_mode: bool) -> egui::Image<'static> {
|
||||
}
|
||||
}
|
||||
|
||||
fn quote_repost_button(ui: &mut egui::Ui, note_key: NoteKey) -> egui::Response {
|
||||
fn quote_repost_button(
|
||||
ui: &mut egui::Ui,
|
||||
i18n: &mut Localization,
|
||||
note_key: NoteKey,
|
||||
) -> egui::Response {
|
||||
let size = 14.0;
|
||||
let expand_size = 5.0;
|
||||
let anim_speed = 0.05;
|
||||
@@ -889,12 +906,20 @@ fn quote_repost_button(ui: &mut egui::Ui, note_key: NoteKey) -> egui::Response {
|
||||
|
||||
let put_resp = ui
|
||||
.put(rect, repost_icon(ui.visuals().dark_mode).max_width(size))
|
||||
.on_hover_text(tr!("Repost this note", "Hover text for repost button"));
|
||||
.on_hover_text(tr!(
|
||||
i18n,
|
||||
"Repost this note",
|
||||
"Hover text for repost button"
|
||||
));
|
||||
|
||||
resp.union(put_resp)
|
||||
}
|
||||
|
||||
fn zap_button(state: AnyZapState, noteid: &[u8; 32]) -> impl egui::Widget + use<'_> {
|
||||
fn zap_button<'a>(
|
||||
i18n: &'a mut Localization,
|
||||
state: AnyZapState,
|
||||
noteid: &'a [u8; 32],
|
||||
) -> impl egui::Widget + use<'a> {
|
||||
move |ui: &mut egui::Ui| -> egui::Response {
|
||||
let (rect, size, resp) = crate::anim::hover_expand_small(ui, ui.id().with("zap"));
|
||||
|
||||
@@ -927,9 +952,11 @@ fn zap_button(state: AnyZapState, noteid: &[u8; 32]) -> impl egui::Widget + use<
|
||||
let expand_size = 5.0; // from hover_expand_small
|
||||
let rect = rect.translate(egui::vec2(-(expand_size / 2.0), 0.0));
|
||||
|
||||
let put_resp = ui
|
||||
.put(rect, img)
|
||||
.on_hover_text(tr!("Zap this note", "Hover text for zap button"));
|
||||
let put_resp = ui.put(rect, img).on_hover_text(tr!(
|
||||
i18n,
|
||||
"Zap this note",
|
||||
"Hover text for zap button"
|
||||
));
|
||||
|
||||
resp.union(put_resp)
|
||||
}
|
||||
|
||||
@@ -130,9 +130,13 @@ fn render_text_segments(
|
||||
if let Ok(note) = note_context.ndb.get_note_by_id(txn, note_id) {
|
||||
let r = ui.add(
|
||||
Label::new(
|
||||
RichText::new(tr!("note", "Link text for note references"))
|
||||
.size(size)
|
||||
.color(link_color),
|
||||
RichText::new(tr!(
|
||||
note_context.i18n,
|
||||
"note",
|
||||
"Link text for note references"
|
||||
))
|
||||
.size(size)
|
||||
.color(link_color),
|
||||
)
|
||||
.sense(Sense::click())
|
||||
.selectable(selectable),
|
||||
@@ -157,9 +161,13 @@ fn render_text_segments(
|
||||
if let Ok(note) = note_context.ndb.get_note_by_id(txn, note_id) {
|
||||
let r = ui.add(
|
||||
Label::new(
|
||||
RichText::new(tr!("thread", "Link text for thread references"))
|
||||
.size(size)
|
||||
.color(link_color),
|
||||
RichText::new(tr!(
|
||||
note_context.i18n,
|
||||
"thread",
|
||||
"Link text for thread references"
|
||||
))
|
||||
.size(size)
|
||||
.color(link_color),
|
||||
)
|
||||
.sense(Sense::click())
|
||||
.selectable(selectable),
|
||||
@@ -206,6 +214,7 @@ pub fn reply_desc(
|
||||
} else {
|
||||
// Handle case where reply note is not found
|
||||
let template = tr!(
|
||||
note_context.i18n,
|
||||
"replying to a note",
|
||||
"Fallback text when reply note is not found"
|
||||
);
|
||||
@@ -225,6 +234,7 @@ pub fn reply_desc(
|
||||
let segments = if note_reply.is_reply_to_root() {
|
||||
// Template: "replying to {user}'s {thread}"
|
||||
let template = tr!(
|
||||
note_context.i18n,
|
||||
"replying to {user}'s {thread}",
|
||||
"Template for replying to root thread",
|
||||
user = "{user}",
|
||||
@@ -243,6 +253,7 @@ pub fn reply_desc(
|
||||
if root_note.pubkey() == reply_note.pubkey() {
|
||||
// Template: "replying to {user}'s {note}"
|
||||
let template = tr!(
|
||||
note_context.i18n,
|
||||
"replying to {user}'s {note}",
|
||||
"Template for replying to user's note",
|
||||
user = "{user}",
|
||||
@@ -254,6 +265,7 @@ pub fn reply_desc(
|
||||
// Template: "replying to {reply_user}'s {note} in {thread_user}'s {thread}"
|
||||
// This would need more sophisticated placeholder handling
|
||||
let template = tr!(
|
||||
note_context.i18n,
|
||||
"replying to {user}'s {note} in {thread_user}'s {thread}",
|
||||
"Template for replying to note in different user's thread",
|
||||
user = "{user}",
|
||||
@@ -273,6 +285,7 @@ pub fn reply_desc(
|
||||
} else {
|
||||
// Template: "replying to {user} in someone's thread"
|
||||
let template = tr!(
|
||||
note_context.i18n,
|
||||
"replying to {user} in someone's thread",
|
||||
"Template for replying to user in unknown thread",
|
||||
user = "{user}"
|
||||
@@ -283,6 +296,7 @@ pub fn reply_desc(
|
||||
} else {
|
||||
// Fallback
|
||||
let template = tr!(
|
||||
note_context.i18n,
|
||||
"replying to {user}",
|
||||
"Fallback template for replying to user",
|
||||
user = "{user}"
|
||||
|
||||
Reference in New Issue
Block a user