Skip to content

Commit 9bcc338

Browse files
committed
ui: fix quote repost hitbox
The response from the wide rendered note was incorrect, leading to and incorrectly sized hitbox. This fixes that. Additionally, we include note options and note parent into the hitbox key, as this may influence the size of the note. Before: https://cdn.jb55.com/s/b2464c22a65adb12.png After: https://cdn.jb55.com/s/52545564d98d278e.png Fixes: #519 Closes: #537 Changelog-Fixed: Fix broken quote repost hitbox Signed-off-by: William Casarin <[email protected]>
1 parent aafddf5 commit 9bcc338

File tree

5 files changed

+96
-80
lines changed

5 files changed

+96
-80
lines changed

Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ eframe = { workspace = true }
2626
egui_extras = { workspace = true }
2727
ehttp = "0.2.0"
2828
egui_tabs = { git = "https://github.com/damus-io/egui-tabs", branch = "egui-0.28" }
29-
egui_nav = { git = "https://github.com/damus-io/egui-nav", rev = "956338a90e09c7cda951d554626483e0cdbc7825" }
29+
egui_nav = { git = "https://github.com/damus-io/egui-nav", rev = "fd0900bdff4be35709372e921f2b49f68b261469" }
3030
egui_virtual_list = { git = "https://github.com/jb55/hello_egui", branch = "egui-0.28", package = "egui_virtual_list" }
3131
reqwest = { version = "0.12.4", default-features = false, features = [ "rustls-tls-native-roots" ] }
3232
image = { version = "0.25", features = ["jpeg", "png", "webp"] }

src/ui/note/contents.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub fn render_note_preview(
7373
img_cache: &mut ImageCache,
7474
txn: &Transaction,
7575
id: &[u8; 32],
76-
_id_str: &str,
76+
parent: NoteKey,
7777
) -> NoteResponse {
7878
#[cfg(feature = "profiling")]
7979
puffin::profile_function!();
@@ -117,6 +117,7 @@ pub fn render_note_preview(
117117
.wide(true)
118118
.note_previews(false)
119119
.options_button(true)
120+
.parent(parent)
120121
.show(ui)
121122
})
122123
.inner
@@ -213,8 +214,8 @@ fn render_note_contents(
213214
}
214215
});
215216

216-
let note_action = if let Some((id, block_str)) = inline_note {
217-
render_note_preview(ui, ndb, note_cache, img_cache, txn, id, block_str).action
217+
let note_action = if let Some((id, _block_str)) = inline_note {
218+
render_note_preview(ui, ndb, note_cache, img_cache, txn, id, note_key).action
218219
} else {
219220
None
220221
};

src/ui/note/mod.rs

+89-74
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub struct NoteView<'a> {
3131
ndb: &'a Ndb,
3232
note_cache: &'a mut NoteCache,
3333
img_cache: &'a mut ImageCache,
34+
parent: Option<NoteKey>,
3435
note: &'a nostrdb::Note<'a>,
3536
flags: NoteOptions,
3637
}
@@ -195,10 +196,12 @@ impl<'a> NoteView<'a> {
195196
note: &'a nostrdb::Note<'a>,
196197
) -> Self {
197198
let flags = NoteOptions::actionbar | NoteOptions::note_previews;
199+
let parent: Option<NoteKey> = None;
198200
Self {
199201
ndb,
200202
note_cache,
201203
img_cache,
204+
parent,
202205
note,
203206
flags,
204207
}
@@ -257,6 +260,11 @@ impl<'a> NoteView<'a> {
257260
&mut self.flags
258261
}
259262

263+
pub fn parent(mut self, parent: NoteKey) -> Self {
264+
self.parent = Some(parent);
265+
self
266+
}
267+
260268
fn textmode_ui(&mut self, ui: &mut egui::Ui) -> egui::Response {
261269
let note_key = self.note.key().expect("todo: implement non-db notes");
262270
let txn = self.note.txn().expect("todo: implement non-db notes");
@@ -440,8 +448,9 @@ impl<'a> NoteView<'a> {
440448
let mut note_action: Option<NoteAction> = None;
441449
let mut selected_option: Option<NoteContextSelection> = None;
442450

451+
let hitbox_id = note_hitbox_id(note_key, self.options(), self.parent);
443452
let profile = self.ndb.get_profile_by_pubkey(txn, self.note.pubkey());
444-
let maybe_hitbox = maybe_note_hitbox(ui, note_key);
453+
let maybe_hitbox = maybe_note_hitbox(ui, hitbox_id);
445454
let container_right = {
446455
let r = ui.available_rect_before_wrap();
447456
let x = r.max.x;
@@ -451,64 +460,68 @@ impl<'a> NoteView<'a> {
451460

452461
// wide design
453462
let response = if self.options().has_wide() {
454-
ui.horizontal(|ui| {
455-
if self.pfp(note_key, &profile, ui).clicked() {
456-
note_action = Some(NoteAction::OpenProfile(Pubkey::new(*self.note.pubkey())));
457-
};
463+
ui.vertical(|ui| {
464+
ui.horizontal(|ui| {
465+
if self.pfp(note_key, &profile, ui).clicked() {
466+
note_action =
467+
Some(NoteAction::OpenProfile(Pubkey::new(*self.note.pubkey())));
468+
};
458469

459-
let size = ui.available_size();
460-
ui.vertical(|ui| {
461-
ui.add_sized([size.x, self.options().pfp_size()], |ui: &mut egui::Ui| {
462-
ui.horizontal_centered(|ui| {
463-
selected_option = NoteView::note_header(
464-
ui,
465-
self.note_cache,
466-
self.note,
467-
&profile,
468-
self.options(),
469-
container_right,
470-
)
471-
.context_selection;
472-
})
473-
.response
474-
});
470+
let size = ui.available_size();
471+
ui.vertical(|ui| {
472+
ui.add_sized([size.x, self.options().pfp_size()], |ui: &mut egui::Ui| {
473+
ui.horizontal_centered(|ui| {
474+
selected_option = NoteView::note_header(
475+
ui,
476+
self.note_cache,
477+
self.note,
478+
&profile,
479+
self.options(),
480+
container_right,
481+
)
482+
.context_selection;
483+
})
484+
.response
485+
});
475486

476-
let note_reply = self
477-
.note_cache
478-
.cached_note_or_insert_mut(note_key, self.note)
479-
.reply
480-
.borrow(self.note.tags());
487+
let note_reply = self
488+
.note_cache
489+
.cached_note_or_insert_mut(note_key, self.note)
490+
.reply
491+
.borrow(self.note.tags());
481492

482-
if note_reply.reply().is_some() {
483-
ui.horizontal(|ui| {
484-
reply_desc(ui, txn, &note_reply, self.ndb, self.img_cache);
485-
});
486-
}
493+
if note_reply.reply().is_some() {
494+
ui.horizontal(|ui| {
495+
reply_desc(ui, txn, &note_reply, self.ndb, self.img_cache);
496+
});
497+
}
498+
});
487499
});
488-
});
489500

490-
let mut contents = NoteContents::new(
491-
self.ndb,
492-
self.img_cache,
493-
self.note_cache,
494-
txn,
495-
self.note,
496-
note_key,
497-
self.options(),
498-
);
499-
let resp = ui.add(&mut contents);
501+
let mut contents = NoteContents::new(
502+
self.ndb,
503+
self.img_cache,
504+
self.note_cache,
505+
txn,
506+
self.note,
507+
note_key,
508+
self.options(),
509+
);
500510

501-
if let Some(action) = contents.action() {
502-
note_action = Some(*action);
503-
}
511+
ui.add(&mut contents);
504512

505-
if self.options().has_actionbar() {
506-
if let Some(action) = render_note_actionbar(ui, self.note.id(), note_key).inner {
507-
note_action = Some(action);
513+
if let Some(action) = contents.action() {
514+
note_action = Some(*action);
508515
}
509-
}
510516

511-
resp
517+
if self.options().has_actionbar() {
518+
if let Some(action) = render_note_actionbar(ui, self.note.id(), note_key).inner
519+
{
520+
note_action = Some(action);
521+
}
522+
}
523+
})
524+
.response
512525
} else {
513526
// main design
514527
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
@@ -567,14 +580,11 @@ impl<'a> NoteView<'a> {
567580
.response
568581
};
569582

570-
note_action = check_note_hitbox(
571-
ui,
572-
self.note.id(),
573-
note_key,
574-
&response,
575-
maybe_hitbox,
576-
note_action,
577-
);
583+
let note_action = if note_hitbox_clicked(ui, hitbox_id, &response.rect, maybe_hitbox) {
584+
Some(NoteAction::OpenThread(NoteId::new(*self.note.id())))
585+
} else {
586+
note_action
587+
};
578588

579589
NoteResponse::new(response)
580590
.with_action(note_action)
@@ -606,16 +616,18 @@ fn get_reposted_note<'a>(ndb: &Ndb, txn: &'a Transaction, note: &Note) -> Option
606616
note.filter(|note| note.kind() == 1)
607617
}
608618

609-
fn note_hitbox_id(note_key: NoteKey) -> egui::Id {
610-
Id::new(("note_size", note_key))
619+
fn note_hitbox_id(
620+
note_key: NoteKey,
621+
note_options: NoteOptions,
622+
parent: Option<NoteKey>,
623+
) -> egui::Id {
624+
Id::new(("note_size", note_key, note_options, parent))
611625
}
612626

613-
fn maybe_note_hitbox(ui: &mut egui::Ui, note_key: NoteKey) -> Option<Response> {
627+
fn maybe_note_hitbox(ui: &mut egui::Ui, hitbox_id: egui::Id) -> Option<Response> {
614628
ui.ctx()
615-
.data_mut(|d| d.get_persisted(note_hitbox_id(note_key)))
629+
.data_mut(|d| d.get_persisted(hitbox_id))
616630
.map(|note_size: Vec2| {
617-
let id = ui.make_persistent_id(("hitbox_interact", note_key));
618-
619631
// The hitbox should extend the entire width of the
620632
// container. The hitbox height was cached last layout.
621633
let container_rect = ui.max_rect();
@@ -624,28 +636,31 @@ fn maybe_note_hitbox(ui: &mut egui::Ui, note_key: NoteKey) -> Option<Response> {
624636
max: pos2(container_rect.max.x, container_rect.min.y + note_size.y),
625637
};
626638

627-
ui.interact(rect, id, egui::Sense::click())
639+
let response = ui.interact(rect, hitbox_id, egui::Sense::click());
640+
641+
response
642+
.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Other, true, "hitbox"));
643+
644+
response
628645
})
629646
}
630647

631-
fn check_note_hitbox(
648+
fn note_hitbox_clicked(
632649
ui: &mut egui::Ui,
633-
note_id: &[u8; 32],
634-
note_key: NoteKey,
635-
note_response: &Response,
650+
hitbox_id: egui::Id,
651+
note_rect: &Rect,
636652
maybe_hitbox: Option<Response>,
637-
prior_action: Option<NoteAction>,
638-
) -> Option<NoteAction> {
653+
) -> bool {
639654
// Stash the dimensions of the note content so we can render the
640655
// hitbox in the next frame
641656
ui.ctx().data_mut(|d| {
642-
d.insert_persisted(note_hitbox_id(note_key), note_response.rect.size());
657+
d.insert_persisted(hitbox_id, note_rect.size());
643658
});
644659

645660
// If there was an hitbox and it was clicked open the thread
646661
match maybe_hitbox {
647-
Some(hitbox) if hitbox.clicked() => Some(NoteAction::OpenThread(NoteId::new(*note_id))),
648-
_ => prior_action,
662+
Some(hitbox) => hitbox.clicked(),
663+
_ => false,
649664
}
650665
}
651666

src/ui/note/post.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ impl<'a> PostView<'a> {
200200
self.img_cache,
201201
txn,
202202
id.bytes(),
203-
"",
203+
nostrdb::NoteKey::new(0),
204204
);
205205
});
206206
});

0 commit comments

Comments
 (0)