Skip to content

Commit

Permalink
Merge initial threads
Browse files Browse the repository at this point in the history
  • Loading branch information
jb55 committed Aug 16, 2024
2 parents 51b4dfd + 579b47f commit 8c458f8
Show file tree
Hide file tree
Showing 18 changed files with 1,264 additions and 480 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.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ serde_json = "1.0.89"
env_logger = "0.10.0"
puffin_egui = { version = "0.27.0", optional = true }
puffin = { version = "0.19.0", optional = true }
nostrdb = { git = "https://github.com/damus-io/nostrdb-rs", rev = "f2f2ff40d0235c788f1e965375938380f2ee5419" }
nostrdb = { git = "https://github.com/damus-io/nostrdb-rs", rev = "04e5917b44b0112ecfd0eb93e8a1e2c81fce1d75" }
#nostrdb = { path = "/Users/jb55/dev/github/damus-io/nostrdb-rs" }
#nostrdb = "0.3.4"
hex = "0.4.3"
base32 = "0.4.0"
Expand Down
133 changes: 124 additions & 9 deletions src/actionbar.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,145 @@
use crate::{route::Route, Damus};
use crate::{
note::NoteRef,
route::Route,
thread::{Thread, ThreadResult},
Damus,
};
use enostr::NoteId;
use nostrdb::Transaction;
use tracing::{info, warn};

#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum BarAction {
Reply,
OpenThread,
}

pub struct NewThreadNotes {
pub root_id: NoteId,
pub notes: Vec<NoteRef>,
}

pub enum BarResult {
NewThreadNotes(NewThreadNotes),
}

/// open_thread is called when a note is selected and we need to navigate
/// to a thread It is responsible for managing the subscription and
/// making sure the thread is up to date. In a sense, it's a model for
/// the thread view. We don't have a concept of model/view/controller etc
/// in egui, but this is the closest thing to that.
fn open_thread(
app: &mut Damus,
txn: &Transaction,
timeline: usize,
selected_note: &[u8; 32],
) -> Option<BarResult> {
{
let timeline = &mut app.timelines[timeline];
timeline
.routes
.push(Route::Thread(NoteId::new(selected_note.to_owned())));
timeline.navigating = true;
}

let root_id = crate::note::root_note_id_from_selected_id(app, txn, selected_note);
let thread_res = app.threads.thread_mut(&app.ndb, txn, root_id);

// The thread is stale, let's update it
let (thread, result) = match thread_res {
ThreadResult::Stale(thread) => {
let notes = Thread::new_notes(&thread.view.notes, root_id, txn, &app.ndb);
let br = if notes.is_empty() {
None
} else {
Some(BarResult::new_thread_notes(
notes,
NoteId::new(root_id.to_owned()),
))
};

//
// we can't insert and update the VirtualList now, because we
// are already borrowing it mutably. Let's pass it as a
// result instead
//
// thread.view.insert(&notes);
(thread, br)
}

ThreadResult::Fresh(thread) => (thread, None),
};

// only start a subscription on nav and if we don't have
// an active subscription for this thread.
if thread.subscription().is_none() {
*thread.subscription_mut() = app.ndb.subscribe(Thread::filters(root_id)).ok();

match thread.subscription() {
Some(_sub) => {
thread.subscribers += 1;
info!(
"Locally subscribing to thread. {} total active subscriptions, {} on this thread",
app.ndb.subscription_count(),
thread.subscribers,
);
}
None => warn!(
"Error subscribing locally to selected note '{}''s thread",
hex::encode(selected_note)
),
}
} else {
thread.subscribers += 1;
info!(
"Re-using existing thread subscription. {} total active subscriptions, {} on this thread",
app.ndb.subscription_count(),
thread.subscribers,
)
}

result
}

impl BarAction {
pub fn execute(self, app: &mut Damus, timeline: usize, replying_to: &[u8; 32]) {
pub fn execute(
self,
app: &mut Damus,
timeline: usize,
replying_to: &[u8; 32],
txn: &Transaction,
) -> Option<BarResult> {
match self {
BarAction::Reply => {
let timeline = &mut app.timelines[timeline];
timeline
.routes
.push(Route::Reply(NoteId::new(replying_to.to_owned())));
timeline.navigating = true;
None
}

BarAction::OpenThread => {
let timeline = &mut app.timelines[timeline];
timeline
.routes
.push(Route::Thread(NoteId::new(replying_to.to_owned())));
timeline.navigating = true;
}
BarAction::OpenThread => open_thread(app, txn, timeline, replying_to),
}
}
}

impl BarResult {
pub fn new_thread_notes(notes: Vec<NoteRef>, root_id: NoteId) -> Self {
BarResult::NewThreadNotes(NewThreadNotes::new(notes, root_id))
}
}

impl NewThreadNotes {
pub fn new(notes: Vec<NoteRef>, root_id: NoteId) -> Self {
NewThreadNotes { notes, root_id }
}

/// Simple helper for processing a NewThreadNotes result. It simply
/// inserts/merges the notes into the thread cache
pub fn process(&self, thread: &mut Thread) {
// threads are chronological, ie reversed from reverse-chronological, the default.
let reversed = true;
thread.view.insert(&self.notes, reversed);
}
}
Loading

0 comments on commit 8c458f8

Please sign in to comment.