fetch top level messages from db
This commit is contained in:
parent
4dc702bf5b
commit
a68e5d5324
2 changed files with 74 additions and 20 deletions
51
src/db.rs
51
src/db.rs
|
@ -2,14 +2,17 @@ use std::path::PathBuf;
|
|||
use std::sync::LazyLock;
|
||||
|
||||
use anyhow::Result;
|
||||
use egui_extras::Table;
|
||||
use include_dir::{include_dir, Dir};
|
||||
use nostr::{Event, Kind};
|
||||
use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ValueRef};
|
||||
use rusqlite::Connection;
|
||||
use rusqlite_migration::{Migrations, M};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::account_manager::AccountManager;
|
||||
use crate::mail_event::MAIL_EVENT_KIND;
|
||||
use crate::mail_event::{MailMessage, MAIL_EVENT_KIND};
|
||||
use crate::TableEntry;
|
||||
|
||||
static MIGRATIONS_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/migrations");
|
||||
|
||||
|
@ -30,11 +33,7 @@ impl Db {
|
|||
Ok(Self { connection: conn })
|
||||
}
|
||||
|
||||
pub fn store_event(
|
||||
&self,
|
||||
event: &Event,
|
||||
account_manager: &mut AccountManager,
|
||||
) -> Result<()> {
|
||||
pub fn store_event(&self, event: &Event, account_manager: &mut AccountManager) -> Result<()> {
|
||||
// Try to unwrap the gift wrap if this event is a gift wrap
|
||||
let store_unwrapped =
|
||||
is_gift_wrap(event) && account_manager.unwrap_gift_wrap(event).is_ok();
|
||||
|
@ -44,7 +43,10 @@ impl Db {
|
|||
let mut rumor = unwrapped.rumor.clone();
|
||||
rumor.ensure_id();
|
||||
|
||||
let id = rumor.id.expect("Invalid Gift Wrapped Event: There is no ID!").to_hex();
|
||||
let id = rumor
|
||||
.id
|
||||
.expect("Invalid Gift Wrapped Event: There is no ID!")
|
||||
.to_hex();
|
||||
let raw = json!(rumor).to_string();
|
||||
|
||||
self.connection.execute(
|
||||
|
@ -76,6 +78,41 @@ impl Db {
|
|||
Ok(count > 0)
|
||||
}
|
||||
|
||||
/// These messages will be displayed inside the top-level table.
|
||||
pub fn get_top_level_messages(&self) -> Result<Vec<TableEntry>> {
|
||||
let mut stmt = self.connection
|
||||
.prepare(
|
||||
"SELECT DISTINCT e.id, e.content, e.created_at, e.pubkey, jsonb_extract(value, '$[1]') AS subject
|
||||
FROM events e, json_each(e.tags) AS tag
|
||||
WHERE jsonb_extract(tag.value, '$[0]') = 'subject'
|
||||
AND (EXISTS (
|
||||
SELECT 1
|
||||
FROM json_each(e.tags) AS tag
|
||||
WHERE jsonb_extract(tag.value, '$[0]') = 'e'
|
||||
)
|
||||
OR NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM events f, json_each(f.tags) AS tag
|
||||
WHERE jsonb_extract(tag.value, '$[0]') = 'e'
|
||||
AND jsonb_extract(tag.value, '$[1]') = e.id
|
||||
))
|
||||
ORDER BY created_at DESC
|
||||
")?;
|
||||
let msgs_iter = stmt.query_map([], |row| {
|
||||
Ok(TableEntry {
|
||||
id: row.get(0)?,
|
||||
content: row.get(1)?,
|
||||
created_at: row.get(2)?,
|
||||
pubkey: row.get(3)?,
|
||||
subject: row.get(4)?,
|
||||
})
|
||||
})?;
|
||||
|
||||
let messages = msgs_iter.collect::<Result<Vec<TableEntry>, rusqlite::Error>>()?;
|
||||
|
||||
Ok(messages)
|
||||
}
|
||||
|
||||
/// Get all event IDs for mail events
|
||||
pub fn get_mail_event_ids(&self) -> Result<Vec<String>> {
|
||||
let mut stmt = self
|
||||
|
|
43
src/main.rs
43
src/main.rs
|
@ -3,10 +3,11 @@
|
|||
use eframe::egui::{self, FontDefinitions, Sense, Vec2b};
|
||||
use egui::FontFamily::Proportional;
|
||||
use egui_extras::{Column, TableBuilder};
|
||||
use nostr::{EventId, SingleLetterTag, TagKind};
|
||||
use relay::RelayMessage;
|
||||
use rusqlite::types::FromSql;
|
||||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
use nostr::{EventId, SingleLetterTag, TagKind};
|
||||
use tracing::{debug, error, info, Level};
|
||||
|
||||
mod account_manager;
|
||||
|
@ -19,6 +20,15 @@ mod ui;
|
|||
// not sure if i will use this but i'm committing it for later.
|
||||
// mod threaded_event;
|
||||
|
||||
// WE PROBABLY SHOULDN'T MAKE EVERYTHING A STRING, GRR!
|
||||
pub struct TableEntry {
|
||||
pub id: String,
|
||||
pub content: String,
|
||||
pub subject: String,
|
||||
pub pubkey: String,
|
||||
pub created_at: i64,
|
||||
}
|
||||
|
||||
fn main() -> Result<(), eframe::Error> {
|
||||
let (non_blocking, _guard) = tracing_appender::non_blocking(std::io::stdout()); // add log files in prod one day
|
||||
tracing_subscriber::fmt()
|
||||
|
@ -88,6 +98,7 @@ pub struct Hoot {
|
|||
events: Vec<nostr::Event>,
|
||||
account_manager: account_manager::AccountManager,
|
||||
db: db::Db,
|
||||
table_entries: Vec<TableEntry>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
|
@ -110,6 +121,12 @@ fn update_app(app: &mut Hoot, ctx: &egui::Context) {
|
|||
Ok(..) => {}
|
||||
Err(v) => error!("something went wrong trying to load keys: {}", v),
|
||||
}
|
||||
|
||||
match app.db.get_top_level_messages() {
|
||||
Ok(msgs) => app.table_entries = msgs,
|
||||
Err(e) => error!("Could not fetch table entries to display from DB: {}", e),
|
||||
}
|
||||
|
||||
let _ = app
|
||||
.relays
|
||||
.add_url("wss://relay.chakany.systems".to_string(), wake_up.clone());
|
||||
|
@ -291,6 +308,12 @@ fn render_app(app: &mut Hoot, ctx: &egui::Context) {
|
|||
Page::Inbox => {
|
||||
// Top bar with search
|
||||
ui.horizontal(|ui| {
|
||||
if ui.button("Refresh").clicked() {
|
||||
match app.db.get_top_level_messages() {
|
||||
Ok(msgs) => app.table_entries = msgs,
|
||||
Err(e) => error!("Could not fetch table entries to display from DB: {}", e),
|
||||
}
|
||||
}
|
||||
ui.add_space(16.0);
|
||||
let search_width = ui.available_width() - 100.0;
|
||||
ui.add_sized(
|
||||
|
@ -332,7 +355,7 @@ fn render_app(app: &mut Hoot, ctx: &egui::Context) {
|
|||
})
|
||||
.body(|mut body| {
|
||||
let row_height = 30.0;
|
||||
let events = app.events.clone();
|
||||
let events = &app.table_entries;
|
||||
body.rows(row_height, events.len(), |mut row| {
|
||||
let event = &events[row.index()];
|
||||
|
||||
|
@ -343,25 +366,18 @@ fn render_app(app: &mut Hoot, ctx: &egui::Context) {
|
|||
ui.checkbox(&mut false, "");
|
||||
});
|
||||
row.col(|ui| {
|
||||
ui.label(event.pubkey.to_string());
|
||||
ui.label(&event.pubkey);
|
||||
});
|
||||
row.col(|ui| {
|
||||
// Try to get subject from tags
|
||||
let subject = match &event.tags.find(nostr::TagKind::Subject) {
|
||||
Some(s) => match s.content() {
|
||||
Some(c) => format!("{}: {}", c.to_string(), event.content),
|
||||
None => event.content.clone(),
|
||||
},
|
||||
None => event.content.clone(),
|
||||
};
|
||||
ui.label(subject);
|
||||
ui.label(&event.subject);
|
||||
});
|
||||
row.col(|ui| {
|
||||
ui.label("2 minutes ago");
|
||||
ui.label(event.created_at.to_string());
|
||||
});
|
||||
|
||||
if row.response().clicked() {
|
||||
app.focused_post = event.id.to_string();
|
||||
app.focused_post = event.id.clone();
|
||||
app.page = Page::Post;
|
||||
}
|
||||
});
|
||||
|
@ -500,6 +516,7 @@ impl Hoot {
|
|||
events: Vec::new(),
|
||||
account_manager: account_manager::AccountManager::new(),
|
||||
db,
|
||||
table_entries: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue