ui/replydesc: quick TextSegment cleanup/optimize
most a micro-optimize + cleanup Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
@@ -7,16 +7,16 @@ use notedeck::{tr, NoteAction, NoteContext};
|
|||||||
|
|
||||||
// Rich text segment types for internationalized rendering
|
// Rich text segment types for internationalized rendering
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum TextSegment {
|
pub enum TextSegment<'a> {
|
||||||
Plain(String),
|
Plain(String),
|
||||||
UserMention([u8; 32]), // pubkey
|
UserMention(Option<&'a [u8; 32]>), // pubkey
|
||||||
ThreadUserMention([u8; 32]), // pubkey
|
ThreadUserMention(Option<&'a [u8; 32]>), // pubkey
|
||||||
NoteLink([u8; 32]),
|
NoteLink(Option<&'a [u8; 32]>),
|
||||||
ThreadLink([u8; 32]),
|
ThreadLink(Option<&'a [u8; 32]>),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to parse i18n template strings with placeholders
|
// Helper function to parse i18n template strings with placeholders
|
||||||
fn parse_i18n_template(template: &str) -> Vec<TextSegment> {
|
fn parse_i18n_template(template: &str) -> Vec<TextSegment<'_>> {
|
||||||
let mut segments = Vec::new();
|
let mut segments = Vec::new();
|
||||||
let mut current_text = String::new();
|
let mut current_text = String::new();
|
||||||
let mut chars = template.chars().peekable();
|
let mut chars = template.chars().peekable();
|
||||||
@@ -41,10 +41,10 @@ fn parse_i18n_template(template: &str) -> Vec<TextSegment> {
|
|||||||
// Handle different placeholder types
|
// Handle different placeholder types
|
||||||
match placeholder.as_str() {
|
match placeholder.as_str() {
|
||||||
// Placeholder values will be filled later.
|
// Placeholder values will be filled later.
|
||||||
"user" => segments.push(TextSegment::UserMention([0; 32])),
|
"user" => segments.push(TextSegment::UserMention(None)),
|
||||||
"thread_user" => segments.push(TextSegment::ThreadUserMention([0; 32])),
|
"thread_user" => segments.push(TextSegment::ThreadUserMention(None)),
|
||||||
"note" => segments.push(TextSegment::NoteLink([0; 32])),
|
"note" => segments.push(TextSegment::NoteLink(None)),
|
||||||
"thread" => segments.push(TextSegment::ThreadLink([0; 32])),
|
"thread" => segments.push(TextSegment::ThreadLink(None)),
|
||||||
_ => {
|
_ => {
|
||||||
// Unknown placeholder, treat as plain text
|
// Unknown placeholder, treat as plain text
|
||||||
current_text.push_str(&format!("{{{placeholder}}}"));
|
current_text.push_str(&format!("{{{placeholder}}}"));
|
||||||
@@ -64,39 +64,45 @@ fn parse_i18n_template(template: &str) -> Vec<TextSegment> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to fill in the actual data for placeholders
|
// Helper function to fill in the actual data for placeholders
|
||||||
fn fill_template_data(
|
fn fill_template_data<'a>(
|
||||||
mut segments: Vec<TextSegment>,
|
segments: &mut [TextSegment<'a>],
|
||||||
reply_pubkey: &[u8; 32],
|
reply_pubkey: &'a [u8; 32],
|
||||||
reply_note_id: &[u8; 32],
|
reply_note_id: &'a [u8; 32],
|
||||||
root_pubkey: Option<&[u8; 32]>,
|
root_pubkey: Option<&'a [u8; 32]>,
|
||||||
root_note_id: Option<&[u8; 32]>,
|
root_note_id: Option<&'a [u8; 32]>,
|
||||||
) -> Vec<TextSegment> {
|
) {
|
||||||
for segment in &mut segments {
|
for segment in segments {
|
||||||
match segment {
|
match segment {
|
||||||
TextSegment::UserMention(pubkey) if *pubkey == [0; 32] => {
|
TextSegment::UserMention(pubkey) => {
|
||||||
*pubkey = *reply_pubkey;
|
if pubkey.is_none() {
|
||||||
|
*pubkey = Some(reply_pubkey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TextSegment::ThreadUserMention(pubkey) if *pubkey == [0; 32] => {
|
TextSegment::ThreadUserMention(pubkey) => {
|
||||||
*pubkey = *root_pubkey.unwrap_or(reply_pubkey);
|
if pubkey.is_none() {
|
||||||
|
*pubkey = Some(root_pubkey.unwrap_or(reply_pubkey));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TextSegment::NoteLink(note_id) if *note_id == [0; 32] => {
|
TextSegment::NoteLink(note_id) => {
|
||||||
*note_id = *reply_note_id;
|
if note_id.is_none() {
|
||||||
|
*note_id = Some(reply_note_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TextSegment::ThreadLink(note_id) if *note_id == [0; 32] => {
|
TextSegment::ThreadLink(note_id) => {
|
||||||
*note_id = *root_note_id.unwrap_or(reply_note_id);
|
if note_id.is_none() {
|
||||||
|
*note_id = Some(root_note_id.unwrap_or(reply_note_id));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
TextSegment::Plain(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
segments
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main rendering function for text segments
|
// Main rendering function for text segments
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn render_text_segments(
|
fn render_text_segments(
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
segments: &[TextSegment],
|
segments: &[TextSegment<'_>],
|
||||||
txn: &Transaction,
|
txn: &Transaction,
|
||||||
note_context: &mut NoteContext,
|
note_context: &mut NoteContext,
|
||||||
note_options: NoteOptions,
|
note_options: NoteOptions,
|
||||||
@@ -117,17 +123,25 @@ fn render_text_segments(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
TextSegment::UserMention(pubkey) | TextSegment::ThreadUserMention(pubkey) => {
|
TextSegment::UserMention(pubkey) | TextSegment::ThreadUserMention(pubkey) => {
|
||||||
let action = Mention::new(note_context.ndb, note_context.img_cache, txn, pubkey)
|
let action = Mention::new(
|
||||||
.size(size)
|
note_context.ndb,
|
||||||
.selectable(selectable)
|
note_context.img_cache,
|
||||||
.show(ui);
|
txn,
|
||||||
|
pubkey.expect("expected pubkey"),
|
||||||
|
)
|
||||||
|
.size(size)
|
||||||
|
.selectable(selectable)
|
||||||
|
.show(ui);
|
||||||
|
|
||||||
if action.is_some() {
|
if action.is_some() {
|
||||||
note_action = action;
|
note_action = action;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TextSegment::NoteLink(note_id) => {
|
TextSegment::NoteLink(note_id) => {
|
||||||
if let Ok(note) = note_context.ndb.get_note_by_id(txn, note_id) {
|
if let Ok(note) = note_context
|
||||||
|
.ndb
|
||||||
|
.get_note_by_id(txn, note_id.expect("expected text segment note_id"))
|
||||||
|
{
|
||||||
let r = ui.add(
|
let r = ui.add(
|
||||||
Label::new(
|
Label::new(
|
||||||
RichText::new(tr!(
|
RichText::new(tr!(
|
||||||
@@ -158,7 +172,10 @@ fn render_text_segments(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TextSegment::ThreadLink(note_id) => {
|
TextSegment::ThreadLink(note_id) => {
|
||||||
if let Ok(note) = note_context.ndb.get_note_by_id(txn, note_id) {
|
if let Ok(note) = note_context
|
||||||
|
.ndb
|
||||||
|
.get_note_by_id(txn, note_id.expect("expected text segment threadlink"))
|
||||||
|
{
|
||||||
let r = ui.add(
|
let r = ui.add(
|
||||||
Label::new(
|
Label::new(
|
||||||
RichText::new(tr!(
|
RichText::new(tr!(
|
||||||
@@ -231,7 +248,7 @@ pub fn reply_desc(
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
let segments = if note_reply.is_reply_to_root() {
|
if note_reply.is_reply_to_root() {
|
||||||
// Template: "replying to {user}'s {thread}"
|
// Template: "replying to {user}'s {thread}"
|
||||||
let template = tr!(
|
let template = tr!(
|
||||||
note_context.i18n,
|
note_context.i18n,
|
||||||
@@ -240,13 +257,23 @@ pub fn reply_desc(
|
|||||||
user = "{user}",
|
user = "{user}",
|
||||||
thread = "{thread}"
|
thread = "{thread}"
|
||||||
);
|
);
|
||||||
let segments = parse_i18n_template(&template);
|
let mut segments = parse_i18n_template(&template);
|
||||||
fill_template_data(
|
fill_template_data(
|
||||||
segments,
|
&mut segments,
|
||||||
reply_note.pubkey(),
|
reply_note.pubkey(),
|
||||||
reply.id,
|
reply.id,
|
||||||
None,
|
None,
|
||||||
Some(reply.id),
|
Some(reply.id),
|
||||||
|
);
|
||||||
|
render_text_segments(
|
||||||
|
ui,
|
||||||
|
&segments,
|
||||||
|
txn,
|
||||||
|
note_context,
|
||||||
|
note_options,
|
||||||
|
jobs,
|
||||||
|
size,
|
||||||
|
selectable,
|
||||||
)
|
)
|
||||||
} else if let Some(root) = note_reply.root() {
|
} else if let Some(root) = note_reply.root() {
|
||||||
if let Ok(root_note) = note_context.ndb.get_note_by_id(txn, root.id) {
|
if let Ok(root_note) = note_context.ndb.get_note_by_id(txn, root.id) {
|
||||||
@@ -259,8 +286,18 @@ pub fn reply_desc(
|
|||||||
user = "{user}",
|
user = "{user}",
|
||||||
note = "{note}"
|
note = "{note}"
|
||||||
);
|
);
|
||||||
let segments = parse_i18n_template(&template);
|
let mut segments = parse_i18n_template(&template);
|
||||||
fill_template_data(segments, reply_note.pubkey(), reply.id, None, None)
|
fill_template_data(&mut segments, reply_note.pubkey(), reply.id, None, None);
|
||||||
|
render_text_segments(
|
||||||
|
ui,
|
||||||
|
&segments,
|
||||||
|
txn,
|
||||||
|
note_context,
|
||||||
|
note_options,
|
||||||
|
jobs,
|
||||||
|
size,
|
||||||
|
selectable,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
// Template: "replying to {reply_user}'s {note} in {thread_user}'s {thread}"
|
// Template: "replying to {reply_user}'s {note} in {thread_user}'s {thread}"
|
||||||
// This would need more sophisticated placeholder handling
|
// This would need more sophisticated placeholder handling
|
||||||
@@ -273,13 +310,23 @@ pub fn reply_desc(
|
|||||||
thread_user = "{thread_user}",
|
thread_user = "{thread_user}",
|
||||||
thread = "{thread}"
|
thread = "{thread}"
|
||||||
);
|
);
|
||||||
let segments = parse_i18n_template(&template);
|
let mut segments = parse_i18n_template(&template);
|
||||||
fill_template_data(
|
fill_template_data(
|
||||||
segments,
|
&mut segments,
|
||||||
reply_note.pubkey(),
|
reply_note.pubkey(),
|
||||||
reply.id,
|
reply.id,
|
||||||
Some(root_note.pubkey()),
|
Some(root_note.pubkey()),
|
||||||
Some(root.id),
|
Some(root.id),
|
||||||
|
);
|
||||||
|
render_text_segments(
|
||||||
|
ui,
|
||||||
|
&segments,
|
||||||
|
txn,
|
||||||
|
note_context,
|
||||||
|
note_options,
|
||||||
|
jobs,
|
||||||
|
size,
|
||||||
|
selectable,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -290,8 +337,18 @@ pub fn reply_desc(
|
|||||||
"Template for replying to user in unknown thread",
|
"Template for replying to user in unknown thread",
|
||||||
user = "{user}"
|
user = "{user}"
|
||||||
);
|
);
|
||||||
let segments = parse_i18n_template(&template);
|
let mut segments = parse_i18n_template(&template);
|
||||||
fill_template_data(segments, reply_note.pubkey(), reply.id, None, None)
|
fill_template_data(&mut segments, reply_note.pubkey(), reply.id, None, None);
|
||||||
|
render_text_segments(
|
||||||
|
ui,
|
||||||
|
&segments,
|
||||||
|
txn,
|
||||||
|
note_context,
|
||||||
|
note_options,
|
||||||
|
jobs,
|
||||||
|
size,
|
||||||
|
selectable,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Fallback
|
// Fallback
|
||||||
@@ -301,18 +358,17 @@ pub fn reply_desc(
|
|||||||
"Fallback template for replying to user",
|
"Fallback template for replying to user",
|
||||||
user = "{user}"
|
user = "{user}"
|
||||||
);
|
);
|
||||||
let segments = parse_i18n_template(&template);
|
let mut segments = parse_i18n_template(&template);
|
||||||
fill_template_data(segments, reply_note.pubkey(), reply.id, None, None)
|
fill_template_data(&mut segments, reply_note.pubkey(), reply.id, None, None);
|
||||||
};
|
render_text_segments(
|
||||||
|
ui,
|
||||||
render_text_segments(
|
&segments,
|
||||||
ui,
|
txn,
|
||||||
&segments,
|
note_context,
|
||||||
txn,
|
note_options,
|
||||||
note_context,
|
jobs,
|
||||||
note_options,
|
size,
|
||||||
jobs,
|
selectable,
|
||||||
size,
|
)
|
||||||
selectable,
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user