load timelines from commandline

great way to test queries statelessly
This commit is contained in:
William Casarin
2024-03-22 11:15:09 +01:00
parent 35a9fa3dd8
commit 89f7f838a7
2 changed files with 59 additions and 48 deletions

1
queries/global.json Normal file
View File

@@ -0,0 +1 @@
{"limit": 10, "kinds":[1]}

View File

@@ -63,17 +63,19 @@ impl Ord for NoteRef {
} }
struct Timeline { struct Timeline {
pub filter: Vec<Filter>,
pub notes: Vec<NoteRef>, pub notes: Vec<NoteRef>,
pub subscription: Option<Subscription>, pub subscription: Option<Subscription>,
} }
impl Timeline { impl Timeline {
pub fn new() -> Self { pub fn new(filter: Vec<Filter>) -> Self {
let mut notes: Vec<NoteRef> = vec![]; let mut notes: Vec<NoteRef> = vec![];
notes.reserve(1000); notes.reserve(1000);
let subscription: Option<Subscription> = None; let subscription: Option<Subscription> = None;
Timeline { Timeline {
filter,
notes, notes,
subscription, subscription,
} }
@@ -83,9 +85,7 @@ impl Timeline {
/// We derive Deserialize/Serialize so we can persist app state on shutdown. /// We derive Deserialize/Serialize so we can persist app state on shutdown.
pub struct Damus { pub struct Damus {
state: DamusState, state: DamusState,
n_panels: u32,
compose: String, compose: String,
initial_filter: Vec<enostr::Filter>,
note_cache: HashMap<NoteKey, NoteCache>, note_cache: HashMap<NoteKey, NoteCache>,
pool: RelayPool, pool: RelayPool,
@@ -138,12 +138,15 @@ fn get_home_filter(limit: u16) -> Filter {
fn send_initial_filters(damus: &mut Damus, relay_url: &str) { fn send_initial_filters(damus: &mut Damus, relay_url: &str) {
info!("Sending initial filters to {}", relay_url); info!("Sending initial filters to {}", relay_url);
let mut c: u32 = 1;
let subid = "initial";
for relay in &mut damus.pool.relays { for relay in &mut damus.pool.relays {
let relay = &mut relay.relay; let relay = &mut relay.relay;
if relay.url == relay_url { if relay.url == relay_url {
relay.subscribe(subid.to_string(), damus.initial_filter.clone()); for timeline in &damus.timelines {
relay.subscribe(format!("initial{}", c), timeline.filter.clone());
c += 1;
}
return; return;
} }
} }
@@ -292,25 +295,32 @@ fn setup_profiling() {
} }
fn setup_initial_nostrdb_subs(damus: &mut Damus) -> Result<()> { fn setup_initial_nostrdb_subs(damus: &mut Damus) -> Result<()> {
let filters: Vec<nostrdb::Filter> = damus for timeline in &mut damus.timelines {
.initial_filter let filters: Vec<nostrdb::Filter> = timeline
.iter() .filter
.map(|f| crate::filter::convert_enostr_filter(f)) .iter()
.collect(); .map(|f| crate::filter::convert_enostr_filter(f))
damus.timelines[0].subscription = Some(damus.ndb.subscribe(filters.clone())?); .collect();
let txn = Transaction::new(&damus.ndb)?; timeline.subscription = Some(damus.ndb.subscribe(filters.clone())?);
let res = damus.ndb.query( let txn = Transaction::new(&damus.ndb)?;
&txn, info!(
filters, "querying sub {} {:?}",
damus.initial_filter[0].limit.unwrap_or(200) as i32, timeline.subscription.as_ref().unwrap().id,
)?; timeline.filter
damus.timelines[0].notes = res );
.iter() let res = damus.ndb.query(
.map(|qr| NoteRef { &txn,
key: qr.note_key, filters,
created_at: qr.note.created_at(), timeline.filter[0].limit.unwrap_or(200) as i32,
}) )?;
.collect(); timeline.notes = res
.iter()
.map(|qr| NoteRef {
key: qr.note_key,
created_at: qr.note.created_at(),
})
.collect();
}
Ok(()) Ok(())
} }
@@ -360,7 +370,7 @@ fn get_unknown_author_ids<'a>(
} }
fn handle_eose(damus: &mut Damus, subid: &str, relay_url: &str) -> Result<()> { fn handle_eose(damus: &mut Damus, subid: &str, relay_url: &str) -> Result<()> {
if subid == "initial" { if subid.starts_with("initial") {
let txn = Transaction::new(&damus.ndb)?; let txn = Transaction::new(&damus.ndb)?;
let authors = get_unknown_author_ids(&txn, damus, 0)?; let authors = get_unknown_author_ids(&txn, damus, 0)?;
let n_authors = authors.len(); let n_authors = authors.len();
@@ -438,11 +448,16 @@ impl Damus {
egui_extras::install_image_loaders(&cc.egui_ctx); egui_extras::install_image_loaders(&cc.egui_ctx);
let mut timelines: Vec<Timeline> = vec![];
let initial_limit = 100; let initial_limit = 100;
let initial_filter = if args.len() > 1 { if args.len() > 1 {
serde_json::from_str(&args[1]).unwrap() for arg in &args[1..] {
let filter = serde_json::from_str(&arg).unwrap();
timelines.push(Timeline::new(filter));
}
} else { } else {
serde_json::from_str(&include_str!("../queries/timeline.json")).unwrap() let filter = serde_json::from_str(&include_str!("../queries/global.json")).unwrap();
timelines.push(Timeline::new(filter));
//vec![get_home_filter(initial_limit)] //vec![get_home_filter(initial_limit)]
}; };
@@ -456,9 +471,7 @@ impl Damus {
pool: RelayPool::new(), pool: RelayPool::new(),
img_cache: ImageCache::new(imgcache_dir), img_cache: ImageCache::new(imgcache_dir),
note_cache: HashMap::new(), note_cache: HashMap::new(),
initial_filter, timelines,
n_panels: 1,
timelines: vec![Timeline::new()],
ndb: Ndb::new(data_path.as_ref().to_str().expect("db path ok"), &config).expect("ndb"), ndb: Ndb::new(data_path.as_ref().to_str().expect("db path ok"), &config).expect("ndb"),
compose: "".to_string(), compose: "".to_string(),
frame_history: FrameHistory::default(), frame_history: FrameHistory::default(),
@@ -726,25 +739,20 @@ fn render_note_actionbar(ui: &mut egui::Ui) -> egui::InnerResponse<()> {
}) })
} }
fn render_notes(ui: &mut egui::Ui, damus: &mut Damus, timeline: usize, test_panel_id: usize) { fn render_notes(ui: &mut egui::Ui, damus: &mut Damus, timeline: usize) {
#[cfg(feature = "profiling")] #[cfg(feature = "profiling")]
puffin::profile_function!(); puffin::profile_function!();
let num_notes = damus.timelines[timeline].notes.len(); let num_notes = damus.timelines[timeline].notes.len();
for i in 0..num_notes { for i in 0..num_notes {
let _ = render_note( let _ = render_note(ui, damus, damus.timelines[timeline].notes[i].key, timeline);
ui,
damus,
damus.timelines[timeline].notes[i].key,
test_panel_id,
);
ui.add(egui::Separator::default().spacing(0.0)); ui.add(egui::Separator::default().spacing(0.0));
} }
} }
fn timeline_view(ui: &mut egui::Ui, app: &mut Damus, timeline: usize, test_panel_id: usize) { fn timeline_view(ui: &mut egui::Ui, app: &mut Damus, timeline: usize) {
//padding(4.0, ui, |ui| ui.heading("Notifications")); //padding(4.0, ui, |ui| ui.heading("Notifications"));
/* /*
let font_id = egui::TextStyle::Body.resolve(ui.style()); let font_id = egui::TextStyle::Body.resolve(ui.style());
@@ -761,7 +769,7 @@ fn timeline_view(ui: &mut egui::Ui, app: &mut Damus, timeline: usize, test_panel
*/ */
.show(ui, |ui| { .show(ui, |ui| {
ui.spacing_mut().item_spacing.y = 0.0; ui.spacing_mut().item_spacing.y = 0.0;
render_notes(ui, app, timeline, test_panel_id); render_notes(ui, app, timeline);
}); });
} }
@@ -789,6 +797,7 @@ fn render_panel<'a>(ctx: &egui::Context, app: &'a mut Damus, timeline_ind: usize
ui.visuals_mut().button_frame = false; ui.visuals_mut().button_frame = false;
egui::widgets::global_dark_light_mode_switch(ui); egui::widgets::global_dark_light_mode_switch(ui);
/*
if ui if ui
.add(egui::Button::new("+").frame(false)) .add(egui::Button::new("+").frame(false))
.on_hover_text("Add Timeline") .on_hover_text("Add Timeline")
@@ -805,6 +814,7 @@ fn render_panel<'a>(ctx: &egui::Context, app: &'a mut Damus, timeline_ind: usize
{ {
app.n_panels -= 1; app.n_panels -= 1;
} }
*/
//#[cfg(feature = "profiling")] //#[cfg(feature = "profiling")]
{ {
@@ -851,7 +861,7 @@ fn render_damus_mobile(ctx: &egui::Context, app: &mut Damus) {
main_panel(&ctx.style()).show(ctx, |ui| { main_panel(&ctx.style()).show(ctx, |ui| {
timeline_panel(ui, panel_width, 0, |ui| { timeline_panel(ui, panel_width, 0, |ui| {
timeline_view(ui, app, 0, 0); timeline_view(ui, app, 0);
}); });
}); });
} }
@@ -870,7 +880,7 @@ fn render_damus_desktop(ctx: &egui::Context, app: &mut Damus) {
puffin::profile_function!(); puffin::profile_function!();
let screen_size = ctx.screen_rect().width(); let screen_size = ctx.screen_rect().width();
let calc_panel_width = (screen_size / app.n_panels as f32) - 30.0; let calc_panel_width = (screen_size / app.timelines.len() as f32) - 30.0;
let min_width = 300.0; let min_width = 300.0;
let need_scroll = calc_panel_width < min_width; let need_scroll = calc_panel_width < min_width;
let panel_width = if need_scroll { let panel_width = if need_scroll {
@@ -879,12 +889,12 @@ fn render_damus_desktop(ctx: &egui::Context, app: &mut Damus) {
calc_panel_width calc_panel_width
}; };
if app.n_panels == 1 { if app.timelines.len() == 1 {
let panel_width = ctx.screen_rect().width(); let panel_width = ctx.screen_rect().width();
main_panel(&ctx.style()).show(ctx, |ui| { main_panel(&ctx.style()).show(ctx, |ui| {
timeline_panel(ui, panel_width, 0, |ui| { timeline_panel(ui, panel_width, 0, |ui| {
//postbox(ui, app); //postbox(ui, app);
timeline_view(ui, app, 0, 0); timeline_view(ui, app, 0);
}); });
/* /*
@@ -905,13 +915,13 @@ fn render_damus_desktop(ctx: &egui::Context, app: &mut Damus) {
egui::ScrollArea::horizontal() egui::ScrollArea::horizontal()
.auto_shrink([false; 2]) .auto_shrink([false; 2])
.show(ui, |ui| { .show(ui, |ui| {
for ind in 0..app.n_panels { for timeline_ind in 0..app.timelines.len() {
if ind == 0 { if timeline_ind == 0 {
//postbox(ui, app); //postbox(ui, app);
} }
timeline_panel(ui, panel_width, ind, |ui| { timeline_panel(ui, panel_width, timeline_ind as u32, |ui| {
// TODO: add new timeline to each panel // TODO: add new timeline to each panel
timeline_view(ui, app, 0, ind as usize); timeline_view(ui, app, timeline_ind);
}); });
} }
}); });