ui.rs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. use crate::view::View;
  2. use log::debug;
  3. use tui::{
  4. backend::Backend,
  5. layout::{Alignment, Constraint, Direction, Layout, Rect},
  6. style::Style,
  7. text::{Span, Spans},
  8. widgets::{Block, Borders, List, ListItem, Paragraph},
  9. Frame,
  10. };
  11. pub fn ui<B: Backend>(f: &mut Frame<'_, B>, mut view: View) {
  12. let slice = Layout::default()
  13. .direction(Direction::Horizontal)
  14. .margin(2)
  15. .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
  16. .split(f.size());
  17. let nodes: Vec<ListItem> = view
  18. .id_list
  19. .node_id
  20. .iter()
  21. .map(|id| {
  22. let lines = vec![Spans::from(id.to_string())];
  23. ListItem::new(lines).style(Style::default())
  24. })
  25. .collect();
  26. let nodes =
  27. List::new(nodes).block(Block::default().borders(Borders::ALL)).highlight_symbol(">> ");
  28. f.render_stateful_widget(nodes, slice[0], &mut view.id_list.state);
  29. let index = view.info_list.index;
  30. render_info_left(view.clone(), f);
  31. render_info_right(view.clone(), f, index, slice);
  32. }
  33. fn render_info_left<B: Backend>(view: View, f: &mut Frame<'_, B>) {
  34. // TODO: this is a hack. there must be a better way of doing this.
  35. // e.g. a function called get_length()
  36. let length = render_outbound(view.clone(), f);
  37. let length = render_inbound(view.clone(), f, length);
  38. //render_manual(view.clone(), f, length);
  39. }
  40. //fn render_manual<B: Backend>(view: View, f: &mut Frame<'_, B>, length: usize) {
  41. // let new_num: u16 = length.try_into().unwrap();
  42. // let title_slice = Layout::default()
  43. // .direction(Direction::Horizontal)
  44. // .horizontal_margin(8)
  45. // .vertical_margin(new_num)
  46. // .constraints([Constraint::Percentage(100)].as_ref())
  47. // .split(f.size());
  48. //
  49. // let info_slice = Layout::default()
  50. // .direction(Direction::Horizontal)
  51. // .horizontal_margin(10)
  52. // .vertical_margin(new_num)
  53. // .constraints([Constraint::Percentage(45), Constraint::Percentage(55)].as_ref())
  54. // .split(f.size());
  55. //
  56. // let info = &view.info_list.infos;
  57. // let mut title = Vec::new();
  58. // for id in &view.id_list.node_id {
  59. // match info.get(id) {
  60. // Some(_) => {
  61. // title.push(Spans::from(Span::styled("Manual:", Style::default())));
  62. // }
  63. // None => {
  64. // // TODO
  65. // }
  66. // }
  67. // }
  68. //
  69. // let mut man_info = Vec::new();
  70. // for id in &view.id_list.node_id {
  71. // match info.get(id) {
  72. // Some(connects) => {
  73. // man_info.push(Spans::from(""));
  74. // man_info.push(Spans::from(format!("Key: {}", connects.manual[0].key)));
  75. // man_info.push(Spans::from(""));
  76. // }
  77. // None => {
  78. // // TODO
  79. // }
  80. // }
  81. // }
  82. //
  83. // let info_graph = Paragraph::new(man_info).style(Style::default()).alignment(Alignment::Left);
  84. // let title_graph = Paragraph::new(title).style(Style::default()).alignment(Alignment::Left);
  85. //
  86. // f.render_widget(info_graph, info_slice[0]);
  87. // f.render_widget(title_graph, title_slice[0]);
  88. //}
  89. fn render_inbound<B: Backend>(view: View, f: &mut Frame<'_, B>, length: usize) -> usize {
  90. let mut i_info = Vec::new();
  91. let mut msgs = Vec::new();
  92. // TODO: find better way of doing this
  93. let new_num: u16 = length.try_into().unwrap();
  94. let num = new_num + 3;
  95. let title_slice = Layout::default()
  96. .direction(Direction::Horizontal)
  97. .horizontal_margin(8)
  98. .vertical_margin(num)
  99. .constraints([Constraint::Percentage(100)].as_ref())
  100. .split(f.size());
  101. let info_slice = Layout::default()
  102. .direction(Direction::Horizontal)
  103. .horizontal_margin(10)
  104. .vertical_margin(num)
  105. .constraints([Constraint::Percentage(45), Constraint::Percentage(55)].as_ref())
  106. .split(f.size());
  107. let info = &view.info_list.infos;
  108. let mut title = Vec::new();
  109. for id in &view.id_list.node_id {
  110. match info.get(id) {
  111. Some(_) => {
  112. title.push(Spans::from(Span::styled("Inbound:", Style::default())));
  113. }
  114. None => {
  115. // TODO
  116. }
  117. }
  118. }
  119. for id in &view.id_list.node_id {
  120. match info.get(id) {
  121. Some(connects) => {
  122. if connects.inbound.is_empty() {
  123. i_info.push(Spans::from(""));
  124. i_info.push(Spans::from("Null"));
  125. msgs.push(Spans::from(""));
  126. msgs.push(Spans::from("[R: Null]"));
  127. msgs.push(Spans::from("[S: Null]"));
  128. } else {
  129. for connect in &connects.inbound {
  130. i_info.push(Spans::from(""));
  131. i_info.push(Spans::from(connect.connected.clone()));
  132. match connect.channel.last_status.as_str() {
  133. "recv" => {
  134. msgs.push(Spans::from(""));
  135. msgs.push(Spans::from(format!(
  136. "[R: {}]",
  137. connect.channel.last_msg
  138. )));
  139. }
  140. "sent" => {
  141. msgs.push(Spans::from(""));
  142. msgs.push(Spans::from(format!(
  143. "[S: {}]",
  144. connect.channel.last_msg
  145. )));
  146. }
  147. _ => {
  148. // TODO: handle these values
  149. }
  150. }
  151. }
  152. }
  153. }
  154. None => {
  155. // TODO
  156. }
  157. }
  158. }
  159. for _n in 1..info.len() {
  160. i_info.push(Spans::from(""))
  161. }
  162. let info_graph =
  163. Paragraph::new(i_info.clone()).style(Style::default()).alignment(Alignment::Left);
  164. let msg_graph = Paragraph::new(msgs).style(Style::default()).alignment(Alignment::Right);
  165. let title_graph =
  166. Paragraph::new(title.clone()).style(Style::default()).alignment(Alignment::Left);
  167. f.render_widget(info_graph, info_slice[0]);
  168. f.render_widget(msg_graph, info_slice[0]);
  169. f.render_widget(title_graph, title_slice[0]);
  170. return i_info.len() + title.len() + length + 2
  171. }
  172. fn render_outbound<B: Backend>(view: View, f: &mut Frame<'_, B>) -> usize {
  173. // TODO: move all this boilerplate into functions
  174. let title_slice = Layout::default()
  175. .direction(Direction::Horizontal)
  176. .horizontal_margin(8)
  177. .vertical_margin(4)
  178. .constraints([Constraint::Percentage(100)].as_ref())
  179. .split(f.size());
  180. let info_slice = Layout::default()
  181. .direction(Direction::Horizontal)
  182. .horizontal_margin(10)
  183. .vertical_margin(4)
  184. .constraints([Constraint::Percentage(45), Constraint::Percentage(55)].as_ref())
  185. .split(f.size());
  186. let info = &view.info_list.infos;
  187. let mut title = Vec::new();
  188. for id in &view.id_list.node_id {
  189. match info.get(id) {
  190. Some(_) => {
  191. title.push(Spans::from(Span::styled("Outbound:", Style::default())));
  192. }
  193. None => {
  194. // TODO
  195. }
  196. }
  197. }
  198. let mut slots = Vec::new();
  199. let mut msgs = Vec::new();
  200. for id in &view.id_list.node_id {
  201. match info.get(id) {
  202. Some(connects) => {
  203. for slot in &connects.outbound[0].slots {
  204. slots.push(Spans::from(""));
  205. slots.push(Spans::from(format!("{}", slot.addr)));
  206. match slot.channel.last_status.as_str() {
  207. "recv" => {
  208. msgs.push(Spans::from(""));
  209. msgs.push(Spans::from(format!("[R: {}]", slot.channel.last_msg)));
  210. }
  211. "sent" => {
  212. msgs.push(Spans::from(""));
  213. msgs.push(Spans::from(format!("[S: {}]", slot.channel.last_msg)));
  214. }
  215. _ => {
  216. // TODO: right now we do nothing with these values
  217. }
  218. }
  219. }
  220. }
  221. None => {
  222. // TODO
  223. }
  224. }
  225. }
  226. for _n in 1..info.len() {
  227. slots.push(Spans::from(""))
  228. }
  229. let slots_graph =
  230. Paragraph::new(slots.clone()).style(Style::default()).alignment(Alignment::Left);
  231. let msgs_graph = Paragraph::new(msgs).style(Style::default()).alignment(Alignment::Right);
  232. let title_graph =
  233. Paragraph::new(title.clone()).style(Style::default()).alignment(Alignment::Left);
  234. f.render_widget(msgs_graph, info_slice[0]);
  235. f.render_widget(slots_graph, info_slice[0]);
  236. f.render_widget(title_graph, title_slice[0]);
  237. let out_len = slots.len() + title.len();
  238. return out_len
  239. }
  240. fn render_info_right<B: Backend>(
  241. _view: View,
  242. f: &mut Frame<'_, B>,
  243. _index: usize,
  244. slice: Vec<Rect>,
  245. ) {
  246. let span = vec![];
  247. let graph =
  248. Paragraph::new(span).block(Block::default().borders(Borders::ALL)).style(Style::default());
  249. f.render_widget(graph, slice[1]);
  250. }