Skip to content

Commit

Permalink
ui: fix quote repost hitbox
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
jb55 committed Dec 4, 2024
1 parent 2296944 commit 78210e8
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 31 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ eframe = { workspace = true }
egui_extras = { workspace = true }
ehttp = "0.2.0"
egui_tabs = { git = "https://github.com/damus-io/egui-tabs", branch = "egui-0.28" }
egui_nav = { git = "https://github.com/damus-io/egui-nav", rev = "956338a90e09c7cda951d554626483e0cdbc7825" }
egui_nav = { git = "https://github.com/damus-io/egui-nav", rev = "fd0900bdff4be35709372e921f2b49f68b261469" }
egui_virtual_list = { git = "https://github.com/jb55/hello_egui", branch = "egui-0.28", package = "egui_virtual_list" }
reqwest = { version = "0.12.4", default-features = false, features = [ "rustls-tls-native-roots" ] }
image = { version = "0.25", features = ["jpeg", "png", "webp"] }
Expand Down
7 changes: 4 additions & 3 deletions src/ui/note/contents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub fn render_note_preview(
img_cache: &mut ImageCache,
txn: &Transaction,
id: &[u8; 32],
_id_str: &str,
parent: NoteKey,
) -> NoteResponse {
#[cfg(feature = "profiling")]
puffin::profile_function!();
Expand Down Expand Up @@ -117,6 +117,7 @@ pub fn render_note_preview(
.wide(true)
.note_previews(false)
.options_button(true)
.parent(parent)
.show(ui)
})
.inner
Expand Down Expand Up @@ -213,8 +214,8 @@ fn render_note_contents(
}
});

let note_action = if let Some((id, block_str)) = inline_note {
render_note_preview(ui, ndb, note_cache, img_cache, txn, id, block_str).action
let note_action = if let Some((id, _block_str)) = inline_note {
render_note_preview(ui, ndb, note_cache, img_cache, txn, id, note_key).action
} else {
None
};
Expand Down
61 changes: 36 additions & 25 deletions src/ui/note/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub struct NoteView<'a> {
ndb: &'a Ndb,
note_cache: &'a mut NoteCache,
img_cache: &'a mut ImageCache,
parent: Option<NoteKey>,
note: &'a nostrdb::Note<'a>,
flags: NoteOptions,
}
Expand Down Expand Up @@ -195,10 +196,12 @@ impl<'a> NoteView<'a> {
note: &'a nostrdb::Note<'a>,
) -> Self {
let flags = NoteOptions::actionbar | NoteOptions::note_previews;
let parent: Option<NoteKey> = None;
Self {
ndb,
note_cache,
img_cache,
parent,
note,
flags,
}
Expand Down Expand Up @@ -257,6 +260,11 @@ impl<'a> NoteView<'a> {
&mut self.flags
}

pub fn parent(mut self, parent: NoteKey) -> Self {
self.parent = Some(parent);
self
}

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");
Expand Down Expand Up @@ -440,8 +448,9 @@ impl<'a> NoteView<'a> {
let mut note_action: Option<NoteAction> = None;
let mut selected_option: Option<NoteContextSelection> = None;

let hitbox_id = note_hitbox_id(note_key, self.options(), self.parent);
let profile = self.ndb.get_profile_by_pubkey(txn, self.note.pubkey());
let maybe_hitbox = maybe_note_hitbox(ui, note_key);
let maybe_hitbox = maybe_note_hitbox(ui, hitbox_id);
let container_right = {
let r = ui.available_rect_before_wrap();
let x = r.max.x;
Expand Down Expand Up @@ -571,14 +580,11 @@ impl<'a> NoteView<'a> {
.response
};

note_action = check_note_hitbox(
ui,
self.note.id(),
note_key,
&response,
maybe_hitbox,
note_action,
);
let note_action = if note_hitbox_clicked(ui, hitbox_id, &response.rect, maybe_hitbox) {
Some(NoteAction::OpenThread(NoteId::new(*self.note.id())))
} else {
note_action
};

NoteResponse::new(response)
.with_action(note_action)
Expand Down Expand Up @@ -610,16 +616,18 @@ fn get_reposted_note<'a>(ndb: &Ndb, txn: &'a Transaction, note: &Note) -> Option
note.filter(|note| note.kind() == 1)
}

fn note_hitbox_id(note_key: NoteKey) -> egui::Id {
Id::new(("note_size", note_key))
fn note_hitbox_id(
note_key: NoteKey,
note_options: NoteOptions,
parent: Option<NoteKey>,
) -> egui::Id {
Id::new(("note_size", note_key, note_options, parent))
}

fn maybe_note_hitbox(ui: &mut egui::Ui, note_key: NoteKey) -> Option<Response> {
fn maybe_note_hitbox(ui: &mut egui::Ui, hitbox_id: egui::Id) -> Option<Response> {
ui.ctx()
.data_mut(|d| d.get_persisted(note_hitbox_id(note_key)))
.data_mut(|d| d.get_persisted(hitbox_id))
.map(|note_size: Vec2| {
let id = ui.make_persistent_id(("hitbox_interact", note_key));

// The hitbox should extend the entire width of the
// container. The hitbox height was cached last layout.
let container_rect = ui.max_rect();
Expand All @@ -628,28 +636,31 @@ fn maybe_note_hitbox(ui: &mut egui::Ui, note_key: NoteKey) -> Option<Response> {
max: pos2(container_rect.max.x, container_rect.min.y + note_size.y),
};

ui.interact(rect, id, egui::Sense::click())
let response = ui.interact(rect, hitbox_id, egui::Sense::click());

response
.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Other, true, "hitbox"));

response
})
}

fn check_note_hitbox(
fn note_hitbox_clicked(
ui: &mut egui::Ui,
note_id: &[u8; 32],
note_key: NoteKey,
note_response: &Response,
hitbox_id: egui::Id,
note_rect: &Rect,
maybe_hitbox: Option<Response>,
prior_action: Option<NoteAction>,
) -> Option<NoteAction> {
) -> bool {
// Stash the dimensions of the note content so we can render the
// hitbox in the next frame
ui.ctx().data_mut(|d| {
d.insert_persisted(note_hitbox_id(note_key), note_response.rect.size());
d.insert_persisted(hitbox_id, note_rect.size());
});

// If there was an hitbox and it was clicked open the thread
match maybe_hitbox {
Some(hitbox) if hitbox.clicked() => Some(NoteAction::OpenThread(NoteId::new(*note_id))),
_ => prior_action,
Some(hitbox) => hitbox.clicked(),
_ => false,
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/ui/note/post.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ impl<'a> PostView<'a> {
self.img_cache,
txn,
id.bytes(),
"",
nostrdb::NoteKey::new(0),
);
});
});
Expand Down

0 comments on commit 78210e8

Please sign in to comment.