view.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. use async_std::sync::Arc;
  2. use darkfi::error::Result;
  3. use fxhash::{FxHashMap, FxHashSet};
  4. use log::debug;
  5. use serde::{Deserialize, Serialize};
  6. use tui::widgets::ListState;
  7. use tui::{
  8. backend::Backend,
  9. layout::{Constraint, Direction, Layout, Rect},
  10. style::Style,
  11. text::{Span, Spans},
  12. widgets::{Block, Borders, List, ListItem, Paragraph},
  13. Frame,
  14. };
  15. use crate::model::{ConnectInfo, Model, NodeInfo, SelectableObject, SessionInfo};
  16. #[derive(Debug, Clone)]
  17. pub struct View {
  18. pub id_list: IdListView,
  19. pub info_list: InfoListView,
  20. pub node_info: NodeInfoView,
  21. pub session_info: SessionInfoView,
  22. pub connect_info: ConnectInfoView,
  23. }
  24. impl View {
  25. pub fn new(
  26. id_list: IdListView,
  27. info_list: InfoListView,
  28. node_info: NodeInfoView,
  29. session_info: SessionInfoView,
  30. connect_info: ConnectInfoView,
  31. ) -> View {
  32. View { id_list, info_list, node_info, session_info, connect_info }
  33. }
  34. pub fn update(&mut self, model: Vec<SelectableObject>) -> Result<()> {
  35. for obj in model {
  36. let obj_clone = obj.clone();
  37. match obj {
  38. SelectableObject::Node(node) => {
  39. let node1 = node.clone();
  40. self.node_info.clone().update(node1.clone())?;
  41. self.id_list.ids.insert(node1.clone().node_id);
  42. self.info_list.infos.insert(node.node_id, obj_clone);
  43. }
  44. SelectableObject::Session(session) => {
  45. let session1 = session.clone();
  46. self.session_info.clone().update(session1.clone())?;
  47. self.id_list.ids.insert(session1.clone().session_id);
  48. self.info_list.infos.insert(session1.clone().session_id, obj_clone);
  49. }
  50. SelectableObject::Connect(connect) => {
  51. let connect1 = connect.clone();
  52. self.connect_info.clone().update(connect)?;
  53. self.id_list.ids.insert(connect1.clone().connect_id);
  54. self.info_list.infos.insert(connect1.clone().connect_id, obj_clone);
  55. }
  56. }
  57. }
  58. Ok(())
  59. }
  60. pub fn render<B: Backend>(mut self, f: &mut Frame<'_, B>) {
  61. //debug!("VIEW AT RENDER {:?}", self.id_list.ids);
  62. //let mut nodes = Vec::new();
  63. let style = Style::default();
  64. let list_margin = 2;
  65. let list_direction = Direction::Horizontal;
  66. let list_cnstrnts = vec![Constraint::Percentage(50), Constraint::Percentage(50)];
  67. let mut nodes = Vec::new();
  68. for id in self.id_list.ids {
  69. match self.info_list.infos.get(&id) {
  70. Some(obj) => {
  71. match obj {
  72. SelectableObject::Node(info) => {
  73. let name_span = Span::raw(&info.node_name);
  74. let lines = vec![Spans::from(name_span)];
  75. let names = ListItem::new(lines);
  76. nodes.push(names);
  77. for child in &info.children {
  78. //let name_span = Span::raw(&child.session_name);
  79. let name =
  80. Span::styled(format!(" {}", child.session_name), style);
  81. let lines = vec![Spans::from(name)];
  82. let names = ListItem::new(lines);
  83. nodes.push(names);
  84. for child in &child.children {
  85. //let name_span = Span::raw(&child.connect_id);
  86. let name = Span::styled(
  87. format!(" {}", child.connect_id),
  88. style,
  89. );
  90. let lines = vec![Spans::from(name)];
  91. let names = ListItem::new(lines);
  92. nodes.push(names);
  93. }
  94. }
  95. }
  96. SelectableObject::Session(info) => {
  97. //let name_span = Span::raw(&info.session_name);
  98. //let lines = vec![Spans::from(name_span)];
  99. //let names = ListItem::new(lines);
  100. //nodes.push(names);
  101. //self.session_info.clone().render(info),
  102. }
  103. SelectableObject::Connect(info) => {
  104. //let name_span = Span::raw(&info.connect_id);
  105. //let lines = vec![Spans::from(name_span)];
  106. //let names = ListItem::new(lines);
  107. //nodes.push(names);
  108. //self.connect_info.clone().render(info),
  109. }
  110. }
  111. //
  112. }
  113. None => {
  114. // TODO
  115. } //
  116. }
  117. //
  118. }
  119. let slice = Layout::default()
  120. .direction(list_direction)
  121. .margin(list_margin)
  122. .constraints(list_cnstrnts)
  123. .split(f.size());
  124. let nodes =
  125. List::new(nodes).block(Block::default().borders(Borders::ALL)).highlight_symbol(">> ");
  126. f.render_stateful_widget(nodes, slice[0], &mut self.id_list.state);
  127. }
  128. }
  129. #[derive(Debug, Clone)]
  130. pub struct NodeInfoView {
  131. pub node_id: String,
  132. pub node_name: String,
  133. pub children: Vec<SessionInfo>,
  134. }
  135. impl NodeInfoView {
  136. pub fn default() -> NodeInfoView {
  137. let node_id = String::new();
  138. let node_name = String::new();
  139. let children: Vec<SessionInfo> = Vec::new();
  140. NodeInfoView { node_id, node_name, children }
  141. }
  142. pub fn update(mut self, data: NodeInfo) -> Result<()> {
  143. //self.state.slect(Some(0));
  144. self.node_id = data.node_id;
  145. self.node_name = data.node_name;
  146. self.children = data.children;
  147. Ok(())
  148. }
  149. pub fn render(self, node: &NodeInfo) -> List {
  150. let mut nodes = Vec::new();
  151. let mut lines: Vec<Spans> = Vec::new();
  152. let name_span = Span::raw(&node.node_name);
  153. lines.push(Spans::from(name_span));
  154. let ids = ListItem::new(lines);
  155. nodes.push(ids);
  156. let nodes =
  157. List::new(nodes).block(Block::default().borders(Borders::ALL)).highlight_symbol(">> ");
  158. nodes
  159. }
  160. }
  161. #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Hash)]
  162. pub struct SessionInfoView {
  163. pub session_name: String,
  164. pub session_id: String,
  165. pub parent: String,
  166. pub children: Vec<ConnectInfo>,
  167. }
  168. impl SessionInfoView {
  169. pub fn default() -> SessionInfoView {
  170. let session_name = String::new();
  171. let session_id = String::new();
  172. let parent = String::new();
  173. let children: Vec<ConnectInfo> = Vec::new();
  174. SessionInfoView { session_name, session_id, parent, children }
  175. }
  176. pub fn update(mut self, data: SessionInfo) -> Result<()> {
  177. self.session_name = data.session_name;
  178. self.session_id = data.session_id;
  179. self.parent = data.parent;
  180. self.children = data.children;
  181. Ok(())
  182. }
  183. pub fn render(self, session: &SessionInfo) {
  184. //let mut lines: Vec<Spans> = Vec::new();
  185. //let name_span = Span::raw(self.session_name);
  186. //let ids = ListItem::new(lines);
  187. }
  188. }
  189. #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Hash)]
  190. pub struct ConnectInfoView {
  191. pub connect_id: String,
  192. pub addr: String,
  193. pub is_empty: bool,
  194. pub last_msg: String,
  195. pub last_status: String,
  196. pub state: String,
  197. pub msg_log: Vec<String>,
  198. pub parent: String,
  199. }
  200. impl ConnectInfoView {
  201. pub fn default() -> ConnectInfoView {
  202. let connect_id = String::new();
  203. let addr = String::new();
  204. let is_empty = true;
  205. let last_msg = String::new();
  206. let last_status = String::new();
  207. let state = String::new();
  208. let msg_log: Vec<String> = Vec::new();
  209. let parent = String::new();
  210. ConnectInfoView {
  211. connect_id,
  212. addr,
  213. is_empty,
  214. last_msg,
  215. last_status,
  216. state,
  217. msg_log,
  218. parent,
  219. }
  220. }
  221. pub fn update(mut self, data: ConnectInfo) -> Result<()> {
  222. self.connect_id = data.connect_id;
  223. self.addr = data.addr;
  224. self.is_empty = data.is_empty;
  225. self.last_msg = data.last_msg;
  226. self.last_status = data.last_status;
  227. self.state = data.state;
  228. self.msg_log = data.msg_log;
  229. self.parent = data.parent;
  230. Ok(())
  231. }
  232. pub fn render(self, connect: &ConnectInfo) {
  233. let mut lines: Vec<Spans> = Vec::new();
  234. //let name_span = Span::raw(self.connect_id);
  235. }
  236. }
  237. //#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Hash)]
  238. //pub enum SelectableObject {
  239. // Node(NodeInfoView),
  240. // Session(SessionInfoView),
  241. // Connect(ConnectInfoViewView),
  242. //}
  243. #[derive(Debug, Clone)]
  244. pub struct IdListView {
  245. pub state: ListState,
  246. pub ids: FxHashSet<String>,
  247. }
  248. impl IdListView {
  249. pub fn new(ids: FxHashSet<String>) -> IdListView {
  250. IdListView { state: ListState::default(), ids }
  251. }
  252. pub fn next(&mut self) {
  253. let i = match self.state.selected() {
  254. Some(i) => {
  255. debug!("INDEX: {}", i);
  256. if i >= self.ids.len() - 1 {
  257. 0
  258. } else {
  259. i + 1
  260. }
  261. }
  262. None => 0,
  263. };
  264. debug!("NEW INDEX: {}", i);
  265. debug!("IDS LEN: {}", self.ids.len());
  266. self.state.select(Some(i));
  267. }
  268. pub fn previous(&mut self) {
  269. let i = match self.state.selected() {
  270. Some(i) => {
  271. if i == 0 {
  272. self.ids.len() - 1
  273. } else {
  274. debug!("NEW INDEX {}", i);
  275. i - 1
  276. }
  277. }
  278. None => 0,
  279. };
  280. debug!("INDEX: {}", i);
  281. debug!("IDS LEN: {}", self.ids.len());
  282. self.state.select(Some(i));
  283. }
  284. pub fn unselect(&mut self) {
  285. self.state.select(None);
  286. }
  287. }
  288. #[derive(Debug, Clone)]
  289. pub struct InfoListView {
  290. pub index: usize,
  291. pub infos: FxHashMap<String, SelectableObject>,
  292. }
  293. impl InfoListView {
  294. pub fn new(infos: FxHashMap<String, SelectableObject>) -> InfoListView {
  295. let index = 0;
  296. InfoListView { index, infos }
  297. }
  298. pub async fn next(&mut self) {
  299. self.index = (self.index + 1) % self.infos.len();
  300. }
  301. pub async fn previous(&mut self) {
  302. if self.index > 0 {
  303. self.index -= 1;
  304. } else {
  305. self.index = self.infos.len() - 1;
  306. }
  307. }
  308. }