Просмотр исходного кода

ui: render msgs as a vec![Spans]. finish first version of dnetview.

Previously, we were trying to render messages using a seperate widget
called Paragraph. This would enable us to put msgs on the right of the
screen using the enum Alignment.

However, rendering msgs as a seperate widget meant we had to keep track
of the position of other widgets in order to align properly. This quickly
became highly complex.

Instead, we have now rendered all the data in a single widget called List.
List is composed of a ListItem which is composed of Spans. Spans
indiciate a seperate line whereas Span is a grapheme on a single line.

We render addrs and msgs on the same line as follows:

    lines.push(Spans::from(vec![addr, msgs])

Where lines is a Vec<Spans> that initializes ListItem.

We are currently aligning the msgs Span with empty spaces, which is the
method used by tui-rs/example/list.rs. Ideally we would use some variant
of Alignment for this so we don't have variation between screen sizes.
lunar-mining 4 лет назад
Родитель
Сommit
560acab1b6
2 измененных файлов с 37 добавлено и 42 удалено
  1. 4 8
      bin/dnetview/src/main.rs
  2. 33 34
      bin/dnetview/src/ui.rs

+ 4 - 8
bin/dnetview/src/main.rs

@@ -54,7 +54,7 @@ impl Map {
 
         match reply {
             JsonResult::Resp(r) => {
-                //debug!(target: "RPC", "<-- {}", serde_json::to_string(&r)?);
+                debug!(target: "RPC", "<-- {}", serde_json::to_string(&r)?);
                 Ok(r.result)
             }
 
@@ -143,23 +143,20 @@ async fn run_rpc(config: &DnvConfig, ex: Arc<Executor<'_>>, model: Arc<Model>) -
     Ok(())
 }
 
+// TODO: clean up into seperate functions.
+// TODO: replace if/else with match where possible
+// TODO: test unwraps will never ever crash
 async fn poll(client: Map, model: Arc<Model>) -> Result<()> {
-    // TODO: clean up into seperate functions.
-    // TODO: replace if/else with match where possible
-    // TODO: test unwraps will never ever crash
-    //debug!("Attemping to poll: {}", client.url);
     loop {
         let reply = client.get_info().await?;
 
         if reply.as_object().is_some() && !reply.as_object().unwrap().is_empty() {
-            //debug!("reply: {:?}", reply);
             // TODO: we are ignoring this value for now
             let _ext_addr = reply.as_object().unwrap().get("external_addr");
 
             let inbound_obj = &reply.as_object().unwrap()["session_inbound"];
             let manual_obj = &reply.as_object().unwrap()["session_manual"];
             let outbound_obj = &reply.as_object().unwrap()["session_outbound"];
-            //debug!("OOBJ {:?}", outbound_obj);
 
             let mut iconnects = Vec::new();
             let mut mconnects = Vec::new();
@@ -226,7 +223,6 @@ async fn poll(client: Map, model: Arc<Model>) -> Result<()> {
                 oconnects.push(oinfo);
             }
 
-            debug!("OCONNECTS: {:?}", oconnects);
             let infos = NodeInfo { outbound: oconnects, manual: mconnects, inbound: iconnects };
             let mut node_info = HashMap::new();
 

+ 33 - 34
bin/dnetview/src/ui.rs

@@ -3,7 +3,7 @@ use log::debug;
 
 use tui::{
     backend::Backend,
-    layout::{Alignment, Constraint, Direction, Layout},
+    layout::{Alignment, Constraint, Direction, Layout, Rect},
     style::Style,
     text::{Span, Spans},
     widgets::{Block, Borders, List, ListItem, Paragraph},
@@ -26,43 +26,45 @@ pub fn ui<B: Backend>(f: &mut Frame<'_, B>, mut view: View) {
                 for outbound in &node.outbound.clone() {
                     lines.push(Spans::from(Span::styled("   Outgoing", style)));
                     for slot in outbound.slots.clone() {
-                        lines.push(Spans::from(Span::styled(
-                            format!("       {}", slot.addr),
-                            style,
-                        )));
+                        let addr = Span::styled(format!("       {}", slot.addr), style);
                         if slot.channel.last_status.as_str() != "Null" {
                             let msg: Span = match slot.channel.last_status.as_str() {
-                                "recv" => {
-                                    Span::styled(format!("[R: {}]", slot.channel.last_msg), style)
-                                }
-                                "sent" => {
-                                    Span::styled(format!("[S: {}]", slot.channel.last_msg), style)
-                                }
+                                "recv" => Span::styled(
+                                    format!("               [R: {}]", slot.channel.last_msg),
+                                    style,
+                                ),
+                                "sent" => Span::styled(
+                                    format!("               [S: {}]", slot.channel.last_msg),
+                                    style,
+                                ),
                                 a => Span::styled(format!("{}", a), style),
                             };
+                            lines.push(Spans::from(vec![addr, msg]));
                         } else {
-                            // TODO
+                            // discard Null values for now
+                            lines.push(Spans::from(addr));
                         }
                     }
                 }
                 for connect in &node.inbound {
                     lines.push(Spans::from(Span::styled("   Incoming", Style::default())));
-                    lines.push(Spans::from(Span::styled(
-                        format!("       {}", connect.connected),
-                        style,
-                    )));
-
+                    let addr = Span::styled(format!("       {}", connect.connected), style);
                     if connect.channel.last_status.as_str() != "Null" {
                         let msg: Span = match connect.channel.last_status.as_str() {
-                            "recv" => {
-                                Span::styled(format!("[R: {}]", connect.channel.last_msg), style)
-                            }
-                            "sent" => {
-                                Span::styled(format!("[R: {}]", connect.channel.last_msg), style)
-                            }
+                            "recv" => Span::styled(
+                                format!("               [R: {}]", connect.channel.last_msg),
+                                style,
+                            ),
+                            "sent" => Span::styled(
+                                format!("               [R: {}]", connect.channel.last_msg),
+                                style,
+                            ),
                             a => Span::styled(format!("{}", a), style),
                         };
-                    };
+                        lines.push(Spans::from(vec![addr, msg]));
+                    } else {
+                        lines.push(Spans::from(addr));
+                    }
                 }
                 for connect in &node.manual {
                     lines.push(Spans::from(Span::styled("   Manual", Style::default())));
@@ -89,15 +91,12 @@ pub fn ui<B: Backend>(f: &mut Frame<'_, B>, mut view: View) {
 
     f.render_stateful_widget(nodes, slice[0], &mut view.id_list.state);
 
-    //let msgs = Paragraph::new(msgs).style(Style::default()).alignment(Alignment::Right);
-    //f.render_widget(msgs, slice[0]);
-
-    //render_info_right(view.clone(), f, slice);
+    render_info_right(view.clone(), f, slice);
 }
 
-//fn render_info_right<B: Backend>(_view: View, f: &mut Frame<'_, B>, slice: Vec<Rect>) {
-//    let span = vec![];
-//    let graph =
-//        Paragraph::new(span).block(Block::default().borders(Borders::ALL)).style(Style::default());
-//    f.render_widget(graph, slice[1]);
-//}
+fn render_info_right<B: Backend>(_view: View, f: &mut Frame<'_, B>, slice: Vec<Rect>) {
+    let span = vec![];
+    let graph =
+        Paragraph::new(span).block(Block::default().borders(Borders::ALL)).style(Style::default());
+    f.render_widget(graph, slice[1]);
+}