remote sub new timeline
Signed-off-by: kernelkind <kernelkind@gmail.com>
This commit is contained in:
124
src/app.rs
124
src/app.rs
@@ -6,8 +6,7 @@ use crate::{
|
|||||||
column::{Column, Columns},
|
column::{Column, Columns},
|
||||||
draft::Drafts,
|
draft::Drafts,
|
||||||
error::{Error, FilterError},
|
error::{Error, FilterError},
|
||||||
filter,
|
filter::{self, FilterState},
|
||||||
filter::FilterState,
|
|
||||||
frame_history::FrameHistory,
|
frame_history::FrameHistory,
|
||||||
imgcache::ImageCache,
|
imgcache::ImageCache,
|
||||||
key_storage::KeyStorageType,
|
key_storage::KeyStorageType,
|
||||||
@@ -17,7 +16,7 @@ use crate::{
|
|||||||
route::Route,
|
route::Route,
|
||||||
subscriptions::{SubKind, Subscriptions},
|
subscriptions::{SubKind, Subscriptions},
|
||||||
thread::Threads,
|
thread::Threads,
|
||||||
timeline::{Timeline, TimelineKind, ViewFilter},
|
timeline::{Timeline, TimelineId, TimelineKind, ViewFilter},
|
||||||
ui::{self, DesktopSidePanel},
|
ui::{self, DesktopSidePanel},
|
||||||
unknowns::UnknownIds,
|
unknowns::UnknownIds,
|
||||||
view_state::ViewState,
|
view_state::ViewState,
|
||||||
@@ -41,6 +40,7 @@ use tracing::{debug, error, info, trace, warn};
|
|||||||
pub enum DamusState {
|
pub enum DamusState {
|
||||||
Initializing,
|
Initializing,
|
||||||
Initialized,
|
Initialized,
|
||||||
|
NewTimelineSub(TimelineId),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We derive Deserialize/Serialize so we can persist app state on shutdown.
|
/// We derive Deserialize/Serialize so we can persist app state on shutdown.
|
||||||
@@ -394,44 +394,100 @@ fn setup_initial_nostrdb_subs(
|
|||||||
columns: &mut Columns,
|
columns: &mut Columns,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for timeline in columns.timelines_mut() {
|
for timeline in columns.timelines_mut() {
|
||||||
match &timeline.filter {
|
setup_nostrdb_sub(ndb, note_cache, timeline)?
|
||||||
FilterState::Ready(filters) => {
|
}
|
||||||
{ setup_initial_timeline(ndb, timeline, note_cache, &filters.clone()) }?
|
|
||||||
}
|
|
||||||
|
|
||||||
FilterState::Broken(err) => {
|
Ok(())
|
||||||
error!("FetchingRemote state broken in setup_initial_nostr_subs: {err}")
|
}
|
||||||
}
|
|
||||||
FilterState::FetchingRemote(_) => {
|
fn setup_nostrdb_sub(ndb: &Ndb, note_cache: &mut NoteCache, timeline: &mut Timeline) -> Result<()> {
|
||||||
error!("FetchingRemote state in setup_initial_nostr_subs")
|
match &timeline.filter {
|
||||||
}
|
FilterState::Ready(filters) => {
|
||||||
FilterState::GotRemote(_) => {
|
{ setup_initial_timeline(ndb, timeline, note_cache, &filters.clone()) }?
|
||||||
error!("GotRemote state in setup_initial_nostr_subs")
|
}
|
||||||
}
|
|
||||||
FilterState::NeedsRemote(_filters) => {
|
FilterState::Broken(err) => {
|
||||||
// can't do anything yet, we defer to first connect to send
|
error!("FetchingRemote state broken in setup_initial_nostr_subs: {err}")
|
||||||
// remote filters
|
}
|
||||||
}
|
FilterState::FetchingRemote(_) => {
|
||||||
|
error!("FetchingRemote state in setup_initial_nostr_subs")
|
||||||
|
}
|
||||||
|
FilterState::GotRemote(_) => {
|
||||||
|
error!("GotRemote state in setup_initial_nostr_subs")
|
||||||
|
}
|
||||||
|
FilterState::NeedsRemote(_filters) => {
|
||||||
|
// can't do anything yet, we defer to first connect to send
|
||||||
|
// remote filters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_damus(damus: &mut Damus, ctx: &egui::Context) {
|
fn setup_new_nostrdb_sub(
|
||||||
if damus.state == DamusState::Initializing {
|
ndb: &Ndb,
|
||||||
#[cfg(feature = "profiling")]
|
note_cache: &mut NoteCache,
|
||||||
setup_profiling();
|
columns: &mut Columns,
|
||||||
|
new_timeline_id: TimelineId,
|
||||||
damus.state = DamusState::Initialized;
|
) -> Result<()> {
|
||||||
// this lets our eose handler know to close unknownids right away
|
if let Some(timeline) = columns.find_timeline_mut(new_timeline_id) {
|
||||||
damus
|
info!("Setting up timeline sub for {}", timeline.id);
|
||||||
.subscriptions()
|
if let FilterState::Ready(filters) = &timeline.filter {
|
||||||
.insert("unknownids".to_string(), SubKind::OneShot);
|
for filter in filters {
|
||||||
setup_initial_nostrdb_subs(&damus.ndb, &mut damus.note_cache, &mut damus.columns)
|
info!("Setting up filter {:?}", filter.json());
|
||||||
.expect("home subscription failed");
|
}
|
||||||
|
}
|
||||||
|
setup_nostrdb_sub(ndb, note_cache, timeline)?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_damus(damus: &mut Damus, ctx: &egui::Context) {
|
||||||
|
match damus.state {
|
||||||
|
DamusState::Initializing => {
|
||||||
|
#[cfg(feature = "profiling")]
|
||||||
|
setup_profiling();
|
||||||
|
|
||||||
|
damus.state = DamusState::Initialized;
|
||||||
|
// this lets our eose handler know to close unknownids right away
|
||||||
|
damus
|
||||||
|
.subscriptions()
|
||||||
|
.insert("unknownids".to_string(), SubKind::OneShot);
|
||||||
|
setup_initial_nostrdb_subs(&damus.ndb, &mut damus.note_cache, &mut damus.columns)
|
||||||
|
.expect("home subscription failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
DamusState::NewTimelineSub(new_timeline_id) => {
|
||||||
|
info!("adding new timeline {}", new_timeline_id);
|
||||||
|
setup_new_nostrdb_sub(
|
||||||
|
&damus.ndb,
|
||||||
|
&mut damus.note_cache,
|
||||||
|
&mut damus.columns,
|
||||||
|
new_timeline_id,
|
||||||
|
)
|
||||||
|
.expect("new timeline subscription failed");
|
||||||
|
|
||||||
|
if let Some(filter) = {
|
||||||
|
let timeline = damus
|
||||||
|
.columns
|
||||||
|
.find_timeline(new_timeline_id)
|
||||||
|
.expect("timeline");
|
||||||
|
match &timeline.filter {
|
||||||
|
FilterState::Ready(filters) => Some(filters.clone()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
} {
|
||||||
|
let subid = Uuid::new_v4().to_string();
|
||||||
|
damus.pool.subscribe(subid, filter);
|
||||||
|
|
||||||
|
damus.state = DamusState::Initialized;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DamusState::Initialized => (),
|
||||||
|
};
|
||||||
|
|
||||||
if let Err(err) = try_process_event(damus, ctx) {
|
if let Err(err) = try_process_event(damus, ctx) {
|
||||||
error!("error processing event: {}", err);
|
error!("error processing event: {}", err);
|
||||||
}
|
}
|
||||||
@@ -714,6 +770,10 @@ impl Damus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_new_timeline(&mut self, timeline_id: TimelineId) {
|
||||||
|
self.state = DamusState::NewTimelineSub(timeline_id);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn mock<P: AsRef<Path>>(data_path: P) -> Self {
|
pub fn mock<P: AsRef<Path>>(data_path: P) -> Self {
|
||||||
let mut columns = Columns::new();
|
let mut columns = Columns::new();
|
||||||
let filter = Filter::from_json(include_str!("../queries/global.json")).unwrap();
|
let filter = Filter::from_json(include_str!("../queries/global.json")).unwrap();
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ use crate::{
|
|||||||
thread::thread_unsubscribe,
|
thread::thread_unsubscribe,
|
||||||
timeline::route::{render_timeline_route, AfterRouteExecution, TimelineRoute},
|
timeline::route::{render_timeline_route, AfterRouteExecution, TimelineRoute},
|
||||||
ui::{
|
ui::{
|
||||||
self, add_column::{AddColumnResponse, AddColumnView}, note::PostAction, RelayView, View
|
self,
|
||||||
|
add_column::{AddColumnResponse, AddColumnView},
|
||||||
|
note::PostAction,
|
||||||
|
RelayView, View,
|
||||||
},
|
},
|
||||||
Damus,
|
Damus,
|
||||||
};
|
};
|
||||||
@@ -75,7 +78,7 @@ pub fn render_nav(col: usize, app: &mut Damus, ui: &mut egui::Ui) {
|
|||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
Route::AddColumn => AddColumnView::new(app.accounts.get_selected_account())
|
Route::AddColumn => AddColumnView::new(&app.ndb, app.accounts.get_selected_account())
|
||||||
.ui(ui)
|
.ui(ui)
|
||||||
.map(AfterRouteExecution::AddColumn),
|
.map(AfterRouteExecution::AddColumn),
|
||||||
});
|
});
|
||||||
@@ -96,6 +99,7 @@ pub fn render_nav(col: usize, app: &mut Damus, ui: &mut egui::Ui) {
|
|||||||
AfterRouteExecution::AddColumn(add_column_resp) => {
|
AfterRouteExecution::AddColumn(add_column_resp) => {
|
||||||
match add_column_resp {
|
match add_column_resp {
|
||||||
AddColumnResponse::Timeline(timeline) => {
|
AddColumnResponse::Timeline(timeline) => {
|
||||||
|
app.add_new_timeline(timeline.id);
|
||||||
app.columns_mut().add_timeline(timeline);
|
app.columns_mut().add_timeline(timeline);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,40 +1,41 @@
|
|||||||
use egui::{RichText, Ui};
|
use egui::{RichText, Ui};
|
||||||
use nostrdb::FilterBuilder;
|
use nostrdb::Ndb;
|
||||||
|
|
||||||
use crate::{app_style::NotedeckTextStyle, timeline::Timeline, user_account::UserAccount};
|
use crate::{
|
||||||
|
app_style::NotedeckTextStyle,
|
||||||
|
timeline::{Timeline, TimelineKind},
|
||||||
|
user_account::UserAccount,
|
||||||
|
};
|
||||||
|
|
||||||
pub enum AddColumnResponse {
|
pub enum AddColumnResponse {
|
||||||
Timeline(Timeline),
|
Timeline(Timeline),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AddColumnView<'a> {
|
pub struct AddColumnView<'a> {
|
||||||
|
ndb: &'a Ndb,
|
||||||
cur_account: Option<&'a UserAccount>,
|
cur_account: Option<&'a UserAccount>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AddColumnView<'a> {
|
impl<'a> AddColumnView<'a> {
|
||||||
pub fn new(cur_account: Option<&'a UserAccount>) -> Self {
|
pub fn new(ndb: &'a Ndb, cur_account: Option<&'a UserAccount>) -> Self {
|
||||||
Self { cur_account }
|
Self { ndb, cur_account }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ui(&mut self, ui: &mut Ui) -> Option<AddColumnResponse> {
|
pub fn ui(&mut self, ui: &mut Ui) -> Option<AddColumnResponse> {
|
||||||
ui.label(RichText::new("Add column").text_style(NotedeckTextStyle::Heading.text_style()));
|
ui.label(RichText::new("Add column").text_style(NotedeckTextStyle::Heading.text_style()));
|
||||||
|
|
||||||
if ui.button("create global timeline").clicked() {
|
if ui.button("create global timeline").clicked() {
|
||||||
Some(AddColumnResponse::Timeline(create_global_timeline()))
|
Some(AddColumnResponse::Timeline(
|
||||||
|
TimelineKind::Universe
|
||||||
|
.into_timeline(self.ndb, None)
|
||||||
|
.expect("universe timeline"),
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_global_timeline() -> Timeline {
|
|
||||||
let filter = FilterBuilder::new().kinds([1]).build();
|
|
||||||
Timeline::new(
|
|
||||||
crate::timeline::TimelineKind::Generic,
|
|
||||||
crate::filter::FilterState::Ready(vec![filter]),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// struct ColumnOption {
|
// struct ColumnOption {
|
||||||
// title: &'static str,
|
// title: &'static str,
|
||||||
// description: &'static str,
|
// description: &'static str,
|
||||||
|
|||||||
Reference in New Issue
Block a user