Don't actually render posts too far outside of the viewable window. Just fake it.

This commit is contained in:
Mike Dilger 2023-01-02 05:52:25 +13:00
parent 4f74b8940a
commit 7a830ec89f

View File

@ -9,11 +9,16 @@ use egui::{
}; };
use nostr_types::{EventKind, Id, PublicKeyHex}; use nostr_types::{EventKind, Id, PublicKeyHex};
struct FeedPostParams {
id: Id,
indent: usize,
as_reply_to: bool,
threaded: bool,
}
pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Frame, ui: &mut Ui) { pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Frame, ui: &mut Ui) {
let feed = GLOBALS.feed.blocking_lock().get(); let feed = GLOBALS.feed.blocking_lock().get();
//let screen_rect = ctx.input().screen_rect; // Rect
Globals::trim_desired_events_sync(); Globals::trim_desired_events_sync();
let desired_count: isize = match GLOBALS.desired_events.try_read() { let desired_count: isize = match GLOBALS.desired_events.try_read() {
Ok(v) => v.len() as isize, Ok(v) => v.len() as isize,
@ -79,7 +84,18 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram
}); });
} else { } else {
if let Some(id) = app.replying_to { if let Some(id) = app.replying_to {
render_post(app, ctx, frame, ui, id, 0, true); render_post_actual(
app,
ctx,
frame,
ui,
FeedPostParams {
id,
indent: 0,
as_reply_to: true,
threaded: false,
},
);
} }
ui.with_layout(Layout::right_to_left(Align::TOP), |ui| { ui.with_layout(Layout::right_to_left(Align::TOP), |ui| {
@ -125,6 +141,8 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram
ui.separator(); ui.separator();
let threaded = GLOBALS.settings.blocking_read().view_threaded;
ScrollArea::vertical().show(ui, |ui| { ScrollArea::vertical().show(ui, |ui| {
let bgcolor = if ctx.style().visuals.dark_mode { let bgcolor = if ctx.style().visuals.dark_mode {
Color32::BLACK Color32::BLACK
@ -133,28 +151,110 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram
}; };
Frame::none().fill(bgcolor).show(ui, |ui| { Frame::none().fill(bgcolor).show(ui, |ui| {
for id in feed.iter() { for id in feed.iter() {
// Stop rendering at the bottom of the window: render_post_maybe_fake(
// (This confuses the scrollbar a bit, so I'm taking it out for now) app,
//let pos2 = ui.next_widget_position(); ctx,
//if pos2.y > screen_rect.max.y { frame,
// break; ui,
//} FeedPostParams {
id: *id,
render_post(app, ctx, frame, ui, *id, 0, false); indent: 0,
as_reply_to: false,
threaded,
},
);
} }
}); });
}); });
} }
fn render_post( fn render_post_maybe_fake(
app: &mut GossipUi, app: &mut GossipUi,
ctx: &Context, ctx: &Context,
_frame: &mut eframe::Frame, _frame: &mut eframe::Frame,
ui: &mut Ui, ui: &mut Ui,
id: Id, feed_post_params: FeedPostParams,
indent: usize,
as_reply_to: bool,
) { ) {
let FeedPostParams {
id,
indent,
as_reply_to,
threaded,
} = feed_post_params;
// We always get the event even offscreen so we can estimate its height
let maybe_event = GLOBALS.events.blocking_read().get(&id).cloned();
if maybe_event.is_none() {
return;
}
let event = maybe_event.unwrap();
let screen_rect = ctx.input().screen_rect; // Rect
let pos2 = ui.next_widget_position();
// If too far off of the screen, don't actually render the post, just make some space
// so the scrollbar isn't messed up
if pos2.y < -2000.0 || pos2.y > screen_rect.max.y + 2000.0 {
// ESTIMATE HEIGHT
// This doesn't have to be perfect, but the closer we are, the less wobbly the scroll bar is.
// This is affected by font size, so adjust if we add that as a setting.
// A single-line post currently is 110 pixels high. Every additional line adds 18 pixels.
let mut height = 92.0;
let mut lines = event.content.lines().count();
// presume wrapping at 80 chars, although window width makes a big diff.
lines += event.content.lines().filter(|l| l.len() > 80).count();
height += 18.0 * (lines as f32);
ui.add_space(height);
// Yes, and we need to fake render threads to get their approx height too.
if threaded && !as_reply_to && !app.hides.contains(&id) {
let replies = Globals::get_replies_sync(event.id);
for reply_id in replies {
render_post_maybe_fake(
app,
ctx,
_frame,
ui,
FeedPostParams {
id: reply_id,
indent: indent + 1,
as_reply_to,
threaded,
},
);
}
}
} else {
render_post_actual(
app,
ctx,
_frame,
ui,
FeedPostParams {
id,
indent,
as_reply_to,
threaded,
},
);
}
}
fn render_post_actual(
app: &mut GossipUi,
ctx: &Context,
_frame: &mut eframe::Frame,
ui: &mut Ui,
feed_post_params: FeedPostParams,
) {
let FeedPostParams {
id,
indent,
as_reply_to,
threaded,
} = feed_post_params;
let maybe_event = GLOBALS.events.blocking_read().get(&id).cloned(); let maybe_event = GLOBALS.events.blocking_read().get(&id).cloned();
if maybe_event.is_none() { if maybe_event.is_none() {
return; return;
@ -169,7 +269,6 @@ fn render_post(
let maybe_person = GLOBALS.people.blocking_write().get(&event.pubkey.into()); let maybe_person = GLOBALS.people.blocking_write().get(&event.pubkey.into());
let reactions = Globals::get_reactions_sync(event.id); let reactions = Globals::get_reactions_sync(event.id);
let replies = Globals::get_replies_sync(event.id);
// Person Things we can render: // Person Things we can render:
// pubkey // pubkey
@ -204,8 +303,6 @@ fn render_post(
// Try LayoutJob // Try LayoutJob
let threaded = GLOBALS.settings.blocking_read().view_threaded;
#[allow(clippy::collapsible_else_if)] #[allow(clippy::collapsible_else_if)]
let bgcolor = if GLOBALS.event_is_new.blocking_read().contains(&event.id) { let bgcolor = if GLOBALS.event_is_new.blocking_read().contains(&event.id) {
if ctx.style().visuals.dark_mode { if ctx.style().visuals.dark_mode {
@ -339,8 +436,20 @@ fn render_post(
ui.separator(); ui.separator();
if threaded && !as_reply_to && !app.hides.contains(&id) { if threaded && !as_reply_to && !app.hides.contains(&id) {
let replies = Globals::get_replies_sync(event.id);
for reply_id in replies { for reply_id in replies {
render_post(app, ctx, _frame, ui, reply_id, indent + 1, as_reply_to); render_post_maybe_fake(
app,
ctx,
_frame,
ui,
FeedPostParams {
id: reply_id,
indent: indent + 1,
as_reply_to,
threaded,
},
);
} }
} }
} }