diff --git a/src/ui/activities/auth_activity/layout.rs b/src/ui/activities/auth_activity/layout.rs index 020b0e0..351ed4f 100644 --- a/src/ui/activities/auth_activity/layout.rs +++ b/src/ui/activities/auth_activity/layout.rs @@ -62,6 +62,7 @@ impl AuthActivity { .constraints( [ Constraint::Length(5), + Constraint::Length(1), // Version Constraint::Length(3), Constraint::Length(3), Constraint::Length(3), @@ -80,32 +81,33 @@ 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]); // Draw input fields - f.render_widget(self.draw_remote_address(), auth_chunks[1]); - f.render_widget(self.draw_remote_port(), auth_chunks[2]); - f.render_widget(self.draw_protocol_select(), auth_chunks[3]); - f.render_widget(self.draw_protocol_username(), auth_chunks[4]); - f.render_widget(self.draw_protocol_password(), auth_chunks[5]); + f.render_widget(self.draw_remote_address(), auth_chunks[2]); + f.render_widget(self.draw_remote_port(), auth_chunks[3]); + f.render_widget(self.draw_protocol_select(), auth_chunks[4]); + f.render_widget(self.draw_protocol_username(), auth_chunks[5]); + f.render_widget(self.draw_protocol_password(), auth_chunks[6]); // Draw footer - f.render_widget(self.draw_footer(), auth_chunks[6]); + f.render_widget(self.draw_footer(), auth_chunks[7]); // Set cursor if let InputForm::AuthCredentials = self.input_form { match self.selected_field { InputField::Address => f.set_cursor( - auth_chunks[1].x + self.address.width() as u16 + 1, - auth_chunks[1].y + 1, - ), - InputField::Port => f.set_cursor( - auth_chunks[2].x + self.port.width() as u16 + 1, + auth_chunks[2].x + self.address.width() as u16 + 1, auth_chunks[2].y + 1, ), + InputField::Port => f.set_cursor( + auth_chunks[3].x + self.port.width() as u16 + 1, + auth_chunks[3].y + 1, + ), InputField::Username => f.set_cursor( - auth_chunks[4].x + self.username.width() as u16 + 1, - auth_chunks[4].y + 1, + auth_chunks[5].x + self.username.width() as u16 + 1, + auth_chunks[5].y + 1, ), InputField::Password => f.set_cursor( - auth_chunks[5].x + self.password_placeholder.width() as u16 + 1, - auth_chunks[5].y + 1, + auth_chunks[6].x + self.password_placeholder.width() as u16 + 1, + auth_chunks[6].y + 1, ), _ => {} } @@ -284,6 +286,21 @@ impl AuthActivity { .style(Style::default().fg(Color::White).add_modifier(Modifier::BOLD)) } + /// ### draw_new_version + /// + /// Draw new version disclaimer + fn draw_new_version(&self) -> Paragraph { + let content: String = match self.new_version.as_ref() { + Some(ver) => format!("TermSCP {} is now available! Download it from ", ver), + None => String::new(), + }; + Paragraph::new(content).style( + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ) + } + /// ### draw_footer /// /// Draw authentication page footer diff --git a/src/ui/activities/auth_activity/mod.rs b/src/ui/activities/auth_activity/mod.rs index effcad9..ffe55d3 100644 --- a/src/ui/activities/auth_activity/mod.rs +++ b/src/ui/activities/auth_activity/mod.rs @@ -40,6 +40,7 @@ use crate::filetransfer::FileTransferProtocol; use crate::system::bookmarks_client::BookmarksClient; use crate::system::config_client::ConfigClient; use crate::system::environment; +use crate::utils::git; // Includes use crossterm::event::Event as InputEvent; @@ -118,6 +119,8 @@ 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 { @@ -154,6 +157,7 @@ impl AuthActivity { bookmarks_list: Vec::new(), recents_idx: 0, recents_list: Vec::new(), + new_version: None, } } @@ -192,6 +196,27 @@ impl AuthActivity { } } } + + /// ### on_create + /// + /// If enabled in configuration, check for updates from Github + fn check_for_updates(&mut self) { + if let Some(client) = self.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), + )) + } + } + } + } + } } impl Activity for AuthActivity { @@ -216,6 +241,8 @@ impl Activity for AuthActivity { if self.config_client.is_none() { self.init_config_client(); } + // If check for updates is enabled, check for updates + self.check_for_updates(); } /// ### on_draw diff --git a/src/utils/git.rs b/src/utils/git.rs index 1221c91..a6b5e4f 100644 --- a/src/utils/git.rs +++ b/src/utils/git.rs @@ -44,13 +44,14 @@ struct TagInfo { pub fn check_for_updates(current_version: &str) -> Result, String> { // Send request - let github_version: Result = match ureq::get("https://api.github.com/repos/veeso/termscp/releases/latest").call() { - Ok(response) => match response.into_json::() { - Ok(tag_info) => Ok(tag_info.tag_name.clone()), - Err(err) => Err(err.to_string()) - } - Err(err) => Err(err.to_string()) - }; + let github_version: Result = + match ureq::get("https://api.github.com/repos/veeso/termscp/releases/latest").call() { + Ok(response) => match response.into_json::() { + Ok(tag_info) => Ok(tag_info.tag_name), + Err(err) => Err(err.to_string()), + }, + Err(err) => Err(err.to_string()), + }; // Check version match github_version { Err(err) => Err(err), @@ -65,9 +66,7 @@ pub fn check_for_updates(current_version: &str) -> Result, String Ok(None) // No new version } } - None => { - Err(String::from("Got bad response from Github")) - } + None => Err(String::from("Got bad response from Github")), } } } @@ -83,5 +82,4 @@ mod tests { assert!(check_for_updates("100.0.0").ok().unwrap().is_none()); assert!(check_for_updates("0.0.1").ok().unwrap().is_some()); } - -} \ No newline at end of file +}