use sea_orm::{ActiveModelTrait, Database, DatabaseConnection, DbErr, EntityTrait, QueryFilter, ColumnTrait, Set, QueryOrder};
use tokio::runtime::Runtime;
use std::sync::{Arc};
-use tokio::sync::mpsc;
-use tokio::sync::mpsc::UnboundedSender;
+use tokio::sync::{broadcast, mpsc};
use migration::{Migrator, MigratorTrait};
use ui_rs::ui;
use entity::{collection, profile};
use entity::profile::Entity as Profile;
-use entity::collection::{CollectionType, Entity as Collection};
+use entity::collection::{CollectionType, Entity as Collection, Node};
pub struct Backend {
rt: Arc<Runtime>,
db: DatabaseConnection,
pub current_profile: Option<profile::Model>,
+ pub broadcast: Option<tokio::sync::broadcast::Sender<BroadcastMessage>>
}
type CmdFuture = Pin<Box<dyn Future<Output = ()> + Send>>;
pub type DynCmd = Box<dyn Cmd>;
pub struct BackendHandle {
- tx: UnboundedSender<DynCmd>,
+ pub tx: tokio::sync::mpsc::UnboundedSender<DynCmd>,
+ pub btx: tokio::sync::broadcast::Sender<BroadcastMessage>,
+ pub brx: tokio::sync::broadcast::Receiver<BroadcastMessage>
}
+impl Clone for BackendHandle {
+ fn clone(&self) -> Self {
+ BackendHandle {
+ tx: self.tx.clone(),
+ btx: self.btx.clone(),
+ brx: self.btx.subscribe()
+ }
+ }
+}
+
+#[derive(Clone)]
+pub enum BroadcastMessage {
+ NotebookStructureUpdate(Vec<Node>)
+}
impl Backend {
rt,
db,
current_profile: None,
+ broadcast: None
})
}
..Default::default()
};
- let notebooks = insert_notebooks.insert(&self.db).await?;
+ insert_notebooks.insert(&self.db).await?;
let insert_notes = collection::ActiveModel {
profile_id: Set(inserted.id),
})
}
- pub fn start(self) -> BackendHandle {
- let backend = Arc::new(self);
-
+ pub fn start(mut self) -> BackendHandle {
let (tx, mut rx) = mpsc::unbounded_channel::<DynCmd>();
+ let (btx, brx) = broadcast::channel::<BroadcastMessage>(16);
+ self.broadcast = Some(btx.clone());
+
+ let backend = Arc::new(self);
let rt = backend.rt.clone();
});
});
- BackendHandle { tx }
+ BackendHandle {
+ tx: tx,
+ btx: btx,
+ brx: brx,
+ }
}
}
use ui_rs::{action, ui_actions, UiModel};
use ui_rs::ui::*;
use crate::App;
-use entity::collection::Model as Collection;
+use entity::collection::{Model as Collection, Node};
+use crate::backend::{BackendHandle, BroadcastMessage};
-#[derive(UiModel, Default)]
+#[derive(UiModel)]
pub struct MainWindow {
+ pub backend: BackendHandle,
+
#[bind]
notebooks: UiSourceList<Collection>
}
#[ui_actions]
impl MainWindow {
+ pub fn new(app: &App) -> MainWindow {
+ MainWindow {
+ backend: app.backend.clone(),
+ notebooks: UiSourceList::default()
+ }
+ }
+
#[action]
pub fn new_notebook(&mut self, _event: &ActionEvent) {
println!("new notebook");
pub fn go_forward(&mut self, _event: &ActionEvent) {
}
+
+ #[action]
+ pub fn message(&mut self, _event: &ActionEvent) {
+ while let Ok(msg) = self.backend.brx.try_recv() {
+ match msg {
+ BroadcastMessage::NotebookStructureUpdate(nodes) => fill_sourcelist_from_nodes(&mut self.notebooks, &nodes),
+ }
+ }
+ }
}
-pub fn create_window(app: &AppContext<MainWindow>) -> UiObject<MainWindow> {
- let windowdata: MainWindow = Default::default();
+pub fn create_window(app: &App, ctx: &AppContext<MainWindow>) -> UiObject<MainWindow> {
+ let windowdata: MainWindow = MainWindow::new(app);
+
+ let window = ctx.splitview_window("note", true, windowdata, |obj, data| {
+ init_window_data(data, app);
- let window = app.splitview_window("note", true, windowdata, |obj, data| {
obj.sidebar_builder().create(|obj|{
obj.sourcelist(|b|{
b.fill(true);
window
}
-pub fn init_window_data(window: &mut MainWindow, data: &App) {
- for elm in data.notebooks.iter() {
+fn init_window_data(window: &mut MainWindow, data: &App) {
+ fill_sourcelist_from_nodes(&mut window.notebooks, &data.notebooks);
+}
+
+fn fill_sourcelist_from_nodes(list: &mut UiSourceList<Collection>, nodes: &Vec<Node>) {
+ list.clear();
+
+ for elm in nodes.iter() {
let mut notebook = SubList::new();
notebook.set_header(elm.collection.name.as_str());
sublist_data.push(child.collection.clone());
}
- window.notebooks.push(notebook);
+ list.push(notebook);
}
- window.notebooks.update();
+ list.update();
}