From f75dd5d4e3031dda5ad407d29341f773c34bbcc0 Mon Sep 17 00:00:00 2001 From: ChristianVisintin Date: Mon, 8 Mar 2021 14:20:13 +0100 Subject: [PATCH] Cache version fetched from Github --- CHANGELOG.md | 1 + src/ui/activities/auth_activity/layout.rs | 8 ++-- src/ui/activities/auth_activity/mod.rs | 45 ++++++++++++++++------- src/ui/store.rs | 37 ++++++------------- 4 files changed, 49 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7ad0aa..97d70d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ Released on FIXME: date - Enhancements: - Improved performance regarding configuration I/O (config client is now shared in the activity context) + - Fetch latest version from Github once; cache previous value in the Context Storage. - Bugfix: - Fixed file format cursor position in the GUI diff --git a/src/ui/activities/auth_activity/layout.rs b/src/ui/activities/auth_activity/layout.rs index 351ed4f..d04037c 100644 --- a/src/ui/activities/auth_activity/layout.rs +++ b/src/ui/activities/auth_activity/layout.rs @@ -27,6 +27,7 @@ use super::{ AuthActivity, Context, DialogYesNoOption, FileTransferProtocol, InputField, InputForm, Popup, }; +use crate::ui::store::Store; use crate::utils::fmt::align_text_center; // Ext use std::string::ToString; @@ -44,6 +45,7 @@ impl AuthActivity { /// Draw UI pub(super) fn draw(&mut self) { let mut ctx: Context = self.context.take().unwrap(); + let store: &Store = &ctx.store; let _ = ctx.terminal.draw(|f| { // Prepare chunks let chunks = Layout::default() @@ -81,7 +83,7 @@ impl AuthActivity { .split(chunks[1]); // Draw header f.render_widget(self.draw_header(), auth_chunks[0]); - f.render_widget(self.draw_new_version(), auth_chunks[1]); + f.render_widget(self.draw_new_version(store), auth_chunks[1]); // Draw input fields f.render_widget(self.draw_remote_address(), auth_chunks[2]); f.render_widget(self.draw_remote_port(), auth_chunks[3]); @@ -289,8 +291,8 @@ impl AuthActivity { /// ### draw_new_version /// /// Draw new version disclaimer - fn draw_new_version(&self) -> Paragraph { - let content: String = match self.new_version.as_ref() { + fn draw_new_version(&self, store: &Store) -> Paragraph { + let content: String = match store.get_string(super::STORE_KEY_LATEST_VERSION) { Some(ver) => format!("TermSCP {} is now available! Download it from ", ver), None => String::new(), }; diff --git a/src/ui/activities/auth_activity/mod.rs b/src/ui/activities/auth_activity/mod.rs index b9d701b..4eee6c7 100644 --- a/src/ui/activities/auth_activity/mod.rs +++ b/src/ui/activities/auth_activity/mod.rs @@ -48,6 +48,9 @@ use tui::style::Color; // Types type DialogCallback = fn(&mut AuthActivity); +// Store keys +const STORE_KEY_LATEST_VERSION: &str = "AUTH_LATEST_VERSION"; + /// ### InputField /// /// InputField describes the current input field to edit @@ -115,8 +118,6 @@ pub struct AuthActivity { bookmarks_list: Vec, // List of bookmarks recents_idx: usize, // Index of selected recent recents_list: Vec, // list of recents - // misc - new_version: Option, // Contains new version of termscp } impl Default for AuthActivity { @@ -152,7 +153,6 @@ impl AuthActivity { bookmarks_list: Vec::new(), recents_idx: 0, recents_list: Vec::new(), - new_version: None, } } @@ -160,19 +160,36 @@ impl AuthActivity { /// /// If enabled in configuration, check for updates from Github fn check_for_updates(&mut self) { - if let Some(client) = self.context.as_ref().unwrap().config_client.as_ref() { - if client.get_check_for_updates() { - // Send request - match git::check_for_updates(env!("CARGO_PKG_VERSION")) { - Ok(version) => self.new_version = version, - Err(err) => { - // Report error - self.popup = Some(Popup::Alert( - Color::Red, - format!("Could not check for new updates: {}", err), - )) + // Check version only if unset in the store + let ctx: &Context = self.context.as_ref().unwrap(); + if !ctx.store.isset(STORE_KEY_LATEST_VERSION) { + let mut new_version: Option = match ctx.config_client.as_ref() { + Some(client) => { + if client.get_check_for_updates() { + // Send request + match git::check_for_updates(env!("CARGO_PKG_VERSION")) { + Ok(version) => version, + Err(err) => { + // Report error + self.popup = Some(Popup::Alert( + Color::Red, + format!("Could not check for new updates: {}", err), + )); + // None + None + } + } + } else { + None } } + None => None, + }; + let ctx: &mut Context = self.context.as_mut().unwrap(); + // Set version into the store (or just a flag) + match new_version.take() { + Some(new_version) => ctx.store.set_string(STORE_KEY_LATEST_VERSION, new_version), // If Some, set String + None => ctx.store.set(STORE_KEY_LATEST_VERSION), // If None, just set flag } } } diff --git a/src/ui/store.rs b/src/ui/store.rs index 6999064..bad0bc7 100644 --- a/src/ui/store.rs +++ b/src/ui/store.rs @@ -32,6 +32,7 @@ use std::collections::HashMap; /// ## StoreState /// /// Store state describes a value in the store +#[allow(dead_code)] enum StoreState { Str(String), // String Signed(isize), // Signed number @@ -52,6 +53,7 @@ pub(crate) struct Store { store: HashMap, } +#[allow(dead_code)] impl Store { /// ### init /// @@ -68,11 +70,8 @@ impl Store { /// Get string from store pub fn get_string(&self, key: &str) -> Option<&str> { match self.store.get(key) { - None => None, - Some(val) => match val { - StoreState::Str(s) => Some(s.as_str()), - _ => None, - }, + Some(StoreState::Str(s)) => Some(s.as_str()), + _ => None, } } @@ -81,11 +80,8 @@ impl Store { /// Get signed from store pub fn get_signed(&self, key: &str) -> Option { match self.store.get(key) { - None => None, - Some(val) => match val { - StoreState::Signed(i) => Some(*i), - _ => None, - }, + Some(StoreState::Signed(i)) => Some(*i), + _ => None, } } @@ -94,11 +90,8 @@ impl Store { /// Get unsigned from store pub fn get_unsigned(&self, key: &str) -> Option { match self.store.get(key) { - None => None, - Some(val) => match val { - StoreState::Unsigned(u) => Some(*u), - _ => None, - }, + Some(StoreState::Unsigned(u)) => Some(*u), + _ => None, } } @@ -107,11 +100,8 @@ impl Store { /// get float from store pub fn get_float(&self, key: &str) -> Option { match self.store.get(key) { - None => None, - Some(val) => match val { - StoreState::Float(f) => Some(*f), - _ => None, - }, + Some(StoreState::Float(f)) => Some(*f), + _ => None, } } @@ -120,11 +110,8 @@ impl Store { /// get boolean from store pub fn get_boolean(&self, key: &str) -> Option { match self.store.get(key) { - None => None, - Some(val) => match val { - StoreState::Boolean(b) => Some(*b), - _ => None, - }, + Some(StoreState::Boolean(b)) => Some(*b), + _ => None, } }