diff --git a/src/app_data/mod.rs b/src/app_data/mod.rs index 0e7dc7b..b61970d 100644 --- a/src/app_data/mod.rs +++ b/src/app_data/mod.rs @@ -56,21 +56,6 @@ impl fmt::Display for Header { } impl AppData { - pub const fn get_sorted(&self) -> Option<(Header, SortedOrder)> { - self.sorted_by - } - - /// Change the sorted order, also set the selected container state to match new order - pub fn set_sorted(&mut self, x: Option<(Header, SortedOrder)>) { - self.sorted_by = x; - self.sort_containers(); - self.containers - .state - .select(self.containers.items.iter().position(|i| { - self.get_selected_container_id() - .map_or(false, |id| i.id == id) - })); - } /// Generate a default app_state pub fn default(args: CliArgs) -> Self { Self { @@ -82,6 +67,41 @@ impl AppData { } } + pub const fn get_sorted(&self) -> Option<(Header, SortedOrder)> { + self.sorted_by + } + + /// Remove the sorted header & order, and sort by default - created datetime + pub fn reset_sorted(&mut self) { + self.set_sorted(None); + } + + /// Sort containers based on a given header, if headings match, and already ascending, remove sorting + pub fn set_sort_by_header(&mut self, selected_header: Header) { + let mut output = Some((selected_header, SortedOrder::Asc)); + if let Some((current_header, order)) = self.get_sorted() { + if current_header == selected_header { + match order { + SortedOrder::Desc => output = None, + SortedOrder::Asc => output = Some((selected_header, SortedOrder::Desc)), + } + } + } + self.set_sorted(output); + } + + /// Change the sorted order, also set the selected container state to match new order + fn set_sorted(&mut self, x: Option<(Header, SortedOrder)>) { + self.sorted_by = x; + self.sort_containers(); + self.containers + .state + .select(self.containers.items.iter().position(|i| { + self.get_selected_container_id() + .map_or(false, |id| i.id == id) + })); + } + /// Current time as unix timestamp #[allow(clippy::expect_used)] fn get_systemtime() -> u64 { @@ -185,7 +205,7 @@ impl AppData { /// Sort the containers vec, based on a heading, either ascending or descending, /// If not sort set, then sort by created time - fn sort_containers(&mut self) { + pub fn sort_containers(&mut self) { if let Some((head, ord)) = self.sorted_by { match head { Header::State => match ord { @@ -411,6 +431,7 @@ impl AppData { } /// Update container mem, cpu, & network stats, in single function so only need to call .lock() once + /// Will also, if a sort is set, sort the containers pub fn update_stats( &mut self, id: &ContainerId, @@ -439,6 +460,10 @@ impl AppData { container.tx.update(tx); container.mem_limit.update(mem_limit); } + // need to benchmark this? + if self.get_sorted().is_some() { + self.sort_containers(); + } } /// Update, or insert, containers diff --git a/src/docker_data/mod.rs b/src/docker_data/mod.rs index af53655..7e89b90 100644 --- a/src/docker_data/mod.rs +++ b/src/docker_data/mod.rs @@ -156,18 +156,20 @@ impl DockerData { let docker = Arc::clone(&self.docker); let app_data = Arc::clone(&self.app_data); let spawns = Arc::clone(&self.spawns); - let key = SpawnId::Stats((id.clone(), self.binate)); - let spawn_key = key.clone(); - self.spawns.lock().entry(key).or_insert_with(|| { - tokio::spawn(Self::update_container_stat( - docker, - id.clone(), - app_data, - *is_running, - spawns, - spawn_key, - )) - }); + let spawn_key = SpawnId::Stats((id.clone(), self.binate)); + self.spawns + .lock() + .entry(spawn_key.clone()) + .or_insert_with(|| { + tokio::spawn(Self::update_container_stat( + docker, + id.clone(), + app_data, + *is_running, + spawns, + spawn_key, + )) + }); } self.binate = self.binate.toggle(); } @@ -299,6 +301,7 @@ impl DockerData { } }; self.update_all_container_stats(&all_ids); + self.app_data.lock().sort_containers(); } /// Animate the loading icon