mirror of
https://github.com/veeso/termscp.git
synced 2025-12-07 09:36:00 -08:00
Merge pull request #54 from veeso/release-notes-in-app
Release notes in-app
This commit is contained in:
@@ -23,17 +23,20 @@
|
|||||||
|
|
||||||
Released on FIXME: ??
|
Released on FIXME: ??
|
||||||
|
|
||||||
> 🏄 Summer update 2021🌴
|
> 🍹 Summer update 2021 🍨
|
||||||
|
|
||||||
- **Open any file** in explorer:
|
- **Open any file** in explorer:
|
||||||
- Open file with default program for file type with `<V>`
|
- Open file with default program for file type with `<V>`
|
||||||
- Open file with a specific program with `<W>`
|
- Open file with a specific program with `<W>`
|
||||||
|
- **In-app release notes**
|
||||||
|
- Possibility to see the release note of the new available release whenever a new version is available
|
||||||
|
- Just press `<CTRL+R>` when a new version is available from the auth activity to read the release notes
|
||||||
- Bugfix:
|
- Bugfix:
|
||||||
- Fixed broken input cursor when typing UTF8 characters (tui-realm 0.3.2)
|
- Fixed broken input cursor when typing UTF8 characters (tui-realm 0.3.2)
|
||||||
- Dependencies:
|
- Dependencies:
|
||||||
- Added `open 1.7.0`
|
- Added `open 1.7.0`
|
||||||
- Updated `textwrap` to `0.14.0`
|
- Updated `textwrap` to `0.14.0`
|
||||||
- Updated `tui-realm` to `0.4.1`
|
- Updated `tui-realm` to `0.4.3`
|
||||||
|
|
||||||
## 0.5.1
|
## 0.5.1
|
||||||
|
|
||||||
|
|||||||
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -1,5 +1,7 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aes"
|
name = "aes"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
@@ -1451,9 +1453,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tuirealm"
|
name = "tuirealm"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9897335542e4a4a87ad391419c35e54b4088661e671ba53e578fbbb1154740c2"
|
checksum = "0fcbd06f2aa6a2424aaa245c10e8767fe3f0fee234ac8c144cb15eaf2ee37ce9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"textwrap",
|
"textwrap",
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ tempfile = "3.1.0"
|
|||||||
textwrap = "0.14.0"
|
textwrap = "0.14.0"
|
||||||
thiserror = "^1.0.0"
|
thiserror = "^1.0.0"
|
||||||
toml = "0.5.8"
|
toml = "0.5.8"
|
||||||
tuirealm = { version = "0.4.2", features = [ "with-components" ] }
|
tuirealm = { version = "0.4.3", features = [ "with-components" ] }
|
||||||
ureq = { version = "2.1.0", features = [ "json" ] }
|
ureq = { version = "2.1.0", features = [ "json" ] }
|
||||||
whoami = "1.1.1"
|
whoami = "1.1.1"
|
||||||
wildmatch = "2.0.0"
|
wildmatch = "2.0.0"
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ use tuirealm::{Update, View};
|
|||||||
const COMPONENT_TEXT_H1: &str = "TEXT_H1";
|
const COMPONENT_TEXT_H1: &str = "TEXT_H1";
|
||||||
const COMPONENT_TEXT_H2: &str = "TEXT_H2";
|
const COMPONENT_TEXT_H2: &str = "TEXT_H2";
|
||||||
const COMPONENT_TEXT_NEW_VERSION: &str = "TEXT_NEW_VERSION";
|
const COMPONENT_TEXT_NEW_VERSION: &str = "TEXT_NEW_VERSION";
|
||||||
|
const COMPONENT_TEXT_NEW_VERSION_NOTES: &str = "TEXTAREA_NEW_VERSION";
|
||||||
const COMPONENT_TEXT_FOOTER: &str = "TEXT_FOOTER";
|
const COMPONENT_TEXT_FOOTER: &str = "TEXT_FOOTER";
|
||||||
const COMPONENT_TEXT_HELP: &str = "TEXT_HELP";
|
const COMPONENT_TEXT_HELP: &str = "TEXT_HELP";
|
||||||
const COMPONENT_TEXT_ERROR: &str = "TEXT_ERROR";
|
const COMPONENT_TEXT_ERROR: &str = "TEXT_ERROR";
|
||||||
@@ -66,6 +67,7 @@ const COMPONENT_RECENTS_LIST: &str = "RECENTS_LIST";
|
|||||||
|
|
||||||
// Store keys
|
// Store keys
|
||||||
const STORE_KEY_LATEST_VERSION: &str = "AUTH_LATEST_VERSION";
|
const STORE_KEY_LATEST_VERSION: &str = "AUTH_LATEST_VERSION";
|
||||||
|
const STORE_KEY_RELEASE_NOTES: &str = "AUTH_RELEASE_NOTES";
|
||||||
|
|
||||||
/// ### AuthActivity
|
/// ### AuthActivity
|
||||||
///
|
///
|
||||||
@@ -111,16 +113,13 @@ impl AuthActivity {
|
|||||||
let ctx: &Context = self.context.as_ref().unwrap();
|
let ctx: &Context = self.context.as_ref().unwrap();
|
||||||
if !ctx.store.isset(STORE_KEY_LATEST_VERSION) {
|
if !ctx.store.isset(STORE_KEY_LATEST_VERSION) {
|
||||||
debug!("Version is not set in storage");
|
debug!("Version is not set in storage");
|
||||||
let mut new_version: Option<String> = match ctx.config_client.as_ref() {
|
let mut github_tag: Option<git::GithubTag> = match ctx.config_client.as_ref() {
|
||||||
Some(client) => {
|
Some(client) => {
|
||||||
if client.get_check_for_updates() {
|
if client.get_check_for_updates() {
|
||||||
debug!("Check for updates is enabled");
|
debug!("Check for updates is enabled");
|
||||||
// Send request
|
// Send request
|
||||||
match git::check_for_updates(env!("CARGO_PKG_VERSION")) {
|
match git::check_for_updates(env!("CARGO_PKG_VERSION")) {
|
||||||
Ok(version) => {
|
Ok(github_tag) => github_tag,
|
||||||
info!("Latest version is: {:?}", version);
|
|
||||||
version
|
|
||||||
}
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
// Report error
|
// Report error
|
||||||
error!("Failed to get latest version: {}", err);
|
error!("Failed to get latest version: {}", err);
|
||||||
@@ -140,9 +139,18 @@ impl AuthActivity {
|
|||||||
};
|
};
|
||||||
let ctx: &mut Context = self.context.as_mut().unwrap();
|
let ctx: &mut Context = self.context.as_mut().unwrap();
|
||||||
// Set version into the store (or just a flag)
|
// Set version into the store (or just a flag)
|
||||||
match new_version.take() {
|
match github_tag.take() {
|
||||||
Some(new_version) => ctx.store.set_string(STORE_KEY_LATEST_VERSION, new_version), // If Some, set String
|
Some(git::GithubTag { tag_name, body }) => {
|
||||||
None => ctx.store.set(STORE_KEY_LATEST_VERSION), // If None, just set flag
|
// If some store version and release notes
|
||||||
|
info!("Latest version is: {}", tag_name);
|
||||||
|
ctx.store.set_string(STORE_KEY_LATEST_VERSION, tag_name);
|
||||||
|
ctx.store.set_string(STORE_KEY_RELEASE_NOTES, body);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
info!("Latest version is: {} (current)", env!("CARGO_PKG_VERSION"));
|
||||||
|
// Just set flag as check
|
||||||
|
ctx.store.set(STORE_KEY_LATEST_VERSION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ use super::{
|
|||||||
COMPONENT_INPUT_PORT, COMPONENT_INPUT_USERNAME, COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK,
|
COMPONENT_INPUT_PORT, COMPONENT_INPUT_USERNAME, COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK,
|
||||||
COMPONENT_RADIO_BOOKMARK_DEL_RECENT, COMPONENT_RADIO_BOOKMARK_SAVE_PWD,
|
COMPONENT_RADIO_BOOKMARK_DEL_RECENT, COMPONENT_RADIO_BOOKMARK_SAVE_PWD,
|
||||||
COMPONENT_RADIO_PROTOCOL, COMPONENT_RADIO_QUIT, COMPONENT_RECENTS_LIST, COMPONENT_TEXT_ERROR,
|
COMPONENT_RADIO_PROTOCOL, COMPONENT_RADIO_QUIT, COMPONENT_RECENTS_LIST, COMPONENT_TEXT_ERROR,
|
||||||
COMPONENT_TEXT_HELP, COMPONENT_TEXT_SIZE_ERR,
|
COMPONENT_TEXT_HELP, COMPONENT_TEXT_NEW_VERSION_NOTES, COMPONENT_TEXT_SIZE_ERR,
|
||||||
};
|
};
|
||||||
use crate::ui::keymap::*;
|
use crate::ui::keymap::*;
|
||||||
use tuirealm::components::InputPropsBuilder;
|
use tuirealm::components::InputPropsBuilder;
|
||||||
@@ -116,18 +116,6 @@ impl Update for AuthActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// <TAB> bookmarks
|
|
||||||
(COMPONENT_BOOKMARKS_LIST, &MSG_KEY_TAB)
|
|
||||||
| (COMPONENT_RECENTS_LIST, &MSG_KEY_TAB) => {
|
|
||||||
// Give focus to address
|
|
||||||
self.view.active(COMPONENT_INPUT_ADDR);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
// Any <TAB>, go to bookmarks
|
|
||||||
(_, &MSG_KEY_TAB) => {
|
|
||||||
self.view.active(COMPONENT_BOOKMARKS_LIST);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
// Bookmarks commands
|
// Bookmarks commands
|
||||||
// <RIGHT> / <LEFT>
|
// <RIGHT> / <LEFT>
|
||||||
(COMPONENT_BOOKMARKS_LIST, &MSG_KEY_RIGHT) => {
|
(COMPONENT_BOOKMARKS_LIST, &MSG_KEY_RIGHT) => {
|
||||||
@@ -219,10 +207,12 @@ impl Update for AuthActivity {
|
|||||||
self.umount_recent_del_dialog();
|
self.umount_recent_del_dialog();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_RADIO_BOOKMARK_DEL_RECENT, _) => None,
|
||||||
(COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK, &MSG_KEY_ESC) => {
|
(COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK, &MSG_KEY_ESC) => {
|
||||||
self.umount_bookmark_del_dialog();
|
self.umount_bookmark_del_dialog();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK, _) => None,
|
||||||
// Error message
|
// Error message
|
||||||
(COMPONENT_TEXT_ERROR, &MSG_KEY_ENTER) | (COMPONENT_TEXT_ERROR, &MSG_KEY_ESC) => {
|
(COMPONENT_TEXT_ERROR, &MSG_KEY_ENTER) | (COMPONENT_TEXT_ERROR, &MSG_KEY_ESC) => {
|
||||||
// Umount text error
|
// Umount text error
|
||||||
@@ -230,17 +220,31 @@ impl Update for AuthActivity {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
(COMPONENT_TEXT_ERROR, _) => None,
|
(COMPONENT_TEXT_ERROR, _) => None,
|
||||||
|
(COMPONENT_TEXT_NEW_VERSION_NOTES, &MSG_KEY_ESC)
|
||||||
|
| (COMPONENT_TEXT_NEW_VERSION_NOTES, &MSG_KEY_ENTER) => {
|
||||||
|
// Umount release notes
|
||||||
|
self.umount_release_notes();
|
||||||
|
None
|
||||||
|
}
|
||||||
|
(COMPONENT_TEXT_NEW_VERSION_NOTES, _) => None,
|
||||||
// Help
|
// Help
|
||||||
(_, &MSG_KEY_CTRL_H) => {
|
(_, &MSG_KEY_CTRL_H) => {
|
||||||
// Show help
|
// Show help
|
||||||
self.mount_help();
|
self.mount_help();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
// Release notes
|
||||||
|
(_, &MSG_KEY_CTRL_R) => {
|
||||||
|
// Show release notes
|
||||||
|
self.mount_release_notes();
|
||||||
|
None
|
||||||
|
}
|
||||||
(COMPONENT_TEXT_HELP, &MSG_KEY_ENTER) | (COMPONENT_TEXT_HELP, &MSG_KEY_ESC) => {
|
(COMPONENT_TEXT_HELP, &MSG_KEY_ENTER) | (COMPONENT_TEXT_HELP, &MSG_KEY_ESC) => {
|
||||||
// Hide text help
|
// Hide text help
|
||||||
self.umount_help();
|
self.umount_help();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_TEXT_HELP, _) => None,
|
||||||
// Enter setup
|
// Enter setup
|
||||||
(_, &MSG_KEY_CTRL_C) => {
|
(_, &MSG_KEY_CTRL_C) => {
|
||||||
self.exit_reason = Some(super::ExitReason::EnterSetup);
|
self.exit_reason = Some(super::ExitReason::EnterSetup);
|
||||||
@@ -308,6 +312,18 @@ impl Update for AuthActivity {
|
|||||||
}
|
}
|
||||||
// -- text size error; block everything
|
// -- text size error; block everything
|
||||||
(COMPONENT_TEXT_SIZE_ERR, _) => None,
|
(COMPONENT_TEXT_SIZE_ERR, _) => None,
|
||||||
|
// <TAB> bookmarks
|
||||||
|
(COMPONENT_BOOKMARKS_LIST, &MSG_KEY_TAB)
|
||||||
|
| (COMPONENT_RECENTS_LIST, &MSG_KEY_TAB) => {
|
||||||
|
// Give focus to address
|
||||||
|
self.view.active(COMPONENT_INPUT_ADDR);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
// Any <TAB>, go to bookmarks
|
||||||
|
(_, &MSG_KEY_TAB) => {
|
||||||
|
self.view.active(COMPONENT_BOOKMARKS_LIST);
|
||||||
|
None
|
||||||
|
}
|
||||||
// On submit on any unhandled (connect)
|
// On submit on any unhandled (connect)
|
||||||
(_, Msg::OnSubmit(_)) | (_, &MSG_KEY_ENTER) => {
|
(_, Msg::OnSubmit(_)) | (_, &MSG_KEY_ENTER) => {
|
||||||
// Match <ENTER> key for all other components
|
// Match <ENTER> key for all other components
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ use tuirealm::components::{
|
|||||||
radio::{Radio, RadioPropsBuilder},
|
radio::{Radio, RadioPropsBuilder},
|
||||||
scrolltable::{ScrollTablePropsBuilder, Scrolltable},
|
scrolltable::{ScrollTablePropsBuilder, Scrolltable},
|
||||||
span::{Span, SpanPropsBuilder},
|
span::{Span, SpanPropsBuilder},
|
||||||
|
textarea::{Textarea, TextareaPropsBuilder},
|
||||||
};
|
};
|
||||||
use tuirealm::tui::{
|
use tuirealm::tui::{
|
||||||
layout::{Constraint, Direction, Layout},
|
layout::{Constraint, Direction, Layout},
|
||||||
@@ -187,15 +188,13 @@ impl AuthActivity {
|
|||||||
Box::new(Span::new(
|
Box::new(Span::new(
|
||||||
SpanPropsBuilder::default()
|
SpanPropsBuilder::default()
|
||||||
.with_foreground(Color::Yellow)
|
.with_foreground(Color::Yellow)
|
||||||
.with_spans(
|
.with_spans(vec![
|
||||||
vec![
|
|
||||||
TextSpan::from("termscp "),
|
TextSpan::from("termscp "),
|
||||||
TextSpanBuilder::new(version).underlined().bold().build(),
|
TextSpanBuilder::new(version).underlined().bold().build(),
|
||||||
TextSpan::from(" is now available! Download it from <https://github.com/veeso/termscp/releases/latest>")
|
TextSpan::from(" is NOW available! Get it from <https://veeso.github.io/termscp/>; view release notes with <CTRL+R>"),
|
||||||
]
|
])
|
||||||
)
|
.build(),
|
||||||
.build()
|
)),
|
||||||
))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// Bookmarks
|
// Bookmarks
|
||||||
@@ -346,6 +345,15 @@ impl AuthActivity {
|
|||||||
.render(super::COMPONENT_RADIO_BOOKMARK_DEL_RECENT, f, popup);
|
.render(super::COMPONENT_RADIO_BOOKMARK_DEL_RECENT, f, popup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_NEW_VERSION_NOTES) {
|
||||||
|
if props.visible {
|
||||||
|
// make popup
|
||||||
|
let popup = draw_area_in(f.size(), 90, 90);
|
||||||
|
f.render_widget(Clear, popup);
|
||||||
|
self.view
|
||||||
|
.render(super::COMPONENT_TEXT_NEW_VERSION_NOTES, f, popup);
|
||||||
|
}
|
||||||
|
}
|
||||||
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_HELP) {
|
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_HELP) {
|
||||||
if props.visible {
|
if props.visible {
|
||||||
// make popup
|
// make popup
|
||||||
@@ -753,6 +761,35 @@ impl AuthActivity {
|
|||||||
self.view.umount(super::COMPONENT_TEXT_HELP);
|
self.view.umount(super::COMPONENT_TEXT_HELP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ### mount_release_notes
|
||||||
|
///
|
||||||
|
/// mount release notes text area
|
||||||
|
pub(super) fn mount_release_notes(&mut self) {
|
||||||
|
if let Some(ctx) = self.context.as_ref() {
|
||||||
|
if let Some(release_notes) = ctx.store.get_string(super::STORE_KEY_RELEASE_NOTES) {
|
||||||
|
// make spans
|
||||||
|
let spans: Vec<TextSpan> = release_notes.lines().map(TextSpan::from).collect();
|
||||||
|
self.view.mount(
|
||||||
|
super::COMPONENT_TEXT_NEW_VERSION_NOTES,
|
||||||
|
Box::new(Textarea::new(
|
||||||
|
TextareaPropsBuilder::default()
|
||||||
|
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightYellow)
|
||||||
|
.with_texts(Some(String::from("Release notes")), spans)
|
||||||
|
.build(),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
self.view.active(super::COMPONENT_TEXT_NEW_VERSION_NOTES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ### umount_release_notes
|
||||||
|
///
|
||||||
|
/// Umount release notes text area
|
||||||
|
pub(super) fn umount_release_notes(&mut self) {
|
||||||
|
self.view.umount(super::COMPONENT_TEXT_NEW_VERSION_NOTES);
|
||||||
|
}
|
||||||
|
|
||||||
/// ### get_input
|
/// ### get_input
|
||||||
///
|
///
|
||||||
/// Collect input values from view
|
/// Collect input values from view
|
||||||
|
|||||||
@@ -379,6 +379,7 @@ impl Update for FileTransferActivity {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(COMPONENT_INPUT_COPY, _) => None,
|
||||||
// -- exec popup
|
// -- exec popup
|
||||||
(COMPONENT_INPUT_EXEC, &MSG_KEY_ESC) => {
|
(COMPONENT_INPUT_EXEC, &MSG_KEY_ESC) => {
|
||||||
self.umount_exec();
|
self.umount_exec();
|
||||||
@@ -399,6 +400,7 @@ impl Update for FileTransferActivity {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(COMPONENT_INPUT_EXEC, _) => None,
|
||||||
// -- find popup
|
// -- find popup
|
||||||
(COMPONENT_INPUT_FIND, &MSG_KEY_ESC) => {
|
(COMPONENT_INPUT_FIND, &MSG_KEY_ESC) => {
|
||||||
self.umount_find_input();
|
self.umount_find_input();
|
||||||
@@ -466,6 +468,7 @@ impl Update for FileTransferActivity {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(COMPONENT_INPUT_GOTO, _) => None,
|
||||||
// -- make directory
|
// -- make directory
|
||||||
(COMPONENT_INPUT_MKDIR, &MSG_KEY_ESC) => {
|
(COMPONENT_INPUT_MKDIR, &MSG_KEY_ESC) => {
|
||||||
self.umount_mkdir();
|
self.umount_mkdir();
|
||||||
@@ -485,6 +488,7 @@ impl Update for FileTransferActivity {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(COMPONENT_INPUT_MKDIR, _) => None,
|
||||||
// -- new file
|
// -- new file
|
||||||
(COMPONENT_INPUT_NEWFILE, &MSG_KEY_ESC) => {
|
(COMPONENT_INPUT_NEWFILE, &MSG_KEY_ESC) => {
|
||||||
self.umount_newfile();
|
self.umount_newfile();
|
||||||
@@ -504,6 +508,7 @@ impl Update for FileTransferActivity {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(COMPONENT_INPUT_NEWFILE, _) => None,
|
||||||
// -- open with
|
// -- open with
|
||||||
(COMPONENT_INPUT_OPEN_WITH, &MSG_KEY_ESC) => {
|
(COMPONENT_INPUT_OPEN_WITH, &MSG_KEY_ESC) => {
|
||||||
self.umount_openwith();
|
self.umount_openwith();
|
||||||
@@ -520,6 +525,7 @@ impl Update for FileTransferActivity {
|
|||||||
self.umount_openwith();
|
self.umount_openwith();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_INPUT_OPEN_WITH, _) => None,
|
||||||
// -- rename
|
// -- rename
|
||||||
(COMPONENT_INPUT_RENAME, &MSG_KEY_ESC) => {
|
(COMPONENT_INPUT_RENAME, &MSG_KEY_ESC) => {
|
||||||
self.umount_rename();
|
self.umount_rename();
|
||||||
@@ -539,6 +545,7 @@ impl Update for FileTransferActivity {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(COMPONENT_INPUT_RENAME, _) => None,
|
||||||
// -- save as
|
// -- save as
|
||||||
(COMPONENT_INPUT_SAVEAS, &MSG_KEY_ESC) => {
|
(COMPONENT_INPUT_SAVEAS, &MSG_KEY_ESC) => {
|
||||||
self.umount_saveas();
|
self.umount_saveas();
|
||||||
@@ -563,12 +570,14 @@ impl Update for FileTransferActivity {
|
|||||||
FileExplorerTab::FindRemote => self.update_local_filelist(),
|
FileExplorerTab::FindRemote => self.update_local_filelist(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(COMPONENT_INPUT_SAVEAS, _) => None,
|
||||||
// -- fileinfo
|
// -- fileinfo
|
||||||
(COMPONENT_LIST_FILEINFO, &MSG_KEY_ENTER)
|
(COMPONENT_LIST_FILEINFO, &MSG_KEY_ENTER)
|
||||||
| (COMPONENT_LIST_FILEINFO, &MSG_KEY_ESC) => {
|
| (COMPONENT_LIST_FILEINFO, &MSG_KEY_ESC) => {
|
||||||
self.umount_file_info();
|
self.umount_file_info();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_LIST_FILEINFO, _) => None,
|
||||||
// -- delete
|
// -- delete
|
||||||
(COMPONENT_RADIO_DELETE, &MSG_KEY_ESC)
|
(COMPONENT_RADIO_DELETE, &MSG_KEY_ESC)
|
||||||
| (COMPONENT_RADIO_DELETE, Msg::OnSubmit(Payload::One(Value::Usize(1)))) => {
|
| (COMPONENT_RADIO_DELETE, Msg::OnSubmit(Payload::One(Value::Usize(1)))) => {
|
||||||
@@ -612,6 +621,7 @@ impl Update for FileTransferActivity {
|
|||||||
FileExplorerTab::FindRemote => self.update_remote_filelist(),
|
FileExplorerTab::FindRemote => self.update_remote_filelist(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(COMPONENT_RADIO_DELETE, _) => None,
|
||||||
// -- disconnect
|
// -- disconnect
|
||||||
(COMPONENT_RADIO_DISCONNECT, &MSG_KEY_ESC)
|
(COMPONENT_RADIO_DISCONNECT, &MSG_KEY_ESC)
|
||||||
| (COMPONENT_RADIO_DISCONNECT, Msg::OnSubmit(Payload::One(Value::Usize(1)))) => {
|
| (COMPONENT_RADIO_DISCONNECT, Msg::OnSubmit(Payload::One(Value::Usize(1)))) => {
|
||||||
@@ -623,6 +633,7 @@ impl Update for FileTransferActivity {
|
|||||||
self.umount_disconnect();
|
self.umount_disconnect();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_RADIO_DISCONNECT, _) => None,
|
||||||
// -- quit
|
// -- quit
|
||||||
(COMPONENT_RADIO_QUIT, &MSG_KEY_ESC)
|
(COMPONENT_RADIO_QUIT, &MSG_KEY_ESC)
|
||||||
| (COMPONENT_RADIO_QUIT, Msg::OnSubmit(Payload::One(Value::Usize(1)))) => {
|
| (COMPONENT_RADIO_QUIT, Msg::OnSubmit(Payload::One(Value::Usize(1)))) => {
|
||||||
@@ -634,6 +645,7 @@ impl Update for FileTransferActivity {
|
|||||||
self.umount_quit();
|
self.umount_quit();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_RADIO_QUIT, _) => None,
|
||||||
// -- sorting
|
// -- sorting
|
||||||
(COMPONENT_RADIO_SORTING, &MSG_KEY_ESC)
|
(COMPONENT_RADIO_SORTING, &MSG_KEY_ESC)
|
||||||
| (COMPONENT_RADIO_SORTING, Msg::OnSubmit(_)) => {
|
| (COMPONENT_RADIO_SORTING, Msg::OnSubmit(_)) => {
|
||||||
@@ -666,27 +678,32 @@ impl Update for FileTransferActivity {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(COMPONENT_RADIO_SORTING, _) => None,
|
||||||
// -- error
|
// -- error
|
||||||
(COMPONENT_TEXT_ERROR, &MSG_KEY_ESC) | (COMPONENT_TEXT_ERROR, &MSG_KEY_ENTER) => {
|
(COMPONENT_TEXT_ERROR, &MSG_KEY_ESC) | (COMPONENT_TEXT_ERROR, &MSG_KEY_ENTER) => {
|
||||||
self.umount_error();
|
self.umount_error();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_TEXT_ERROR, _) => None,
|
||||||
// -- fatal
|
// -- fatal
|
||||||
(COMPONENT_TEXT_FATAL, &MSG_KEY_ESC) | (COMPONENT_TEXT_FATAL, &MSG_KEY_ENTER) => {
|
(COMPONENT_TEXT_FATAL, &MSG_KEY_ESC) | (COMPONENT_TEXT_FATAL, &MSG_KEY_ENTER) => {
|
||||||
self.exit_reason = Some(super::ExitReason::Disconnect);
|
self.exit_reason = Some(super::ExitReason::Disconnect);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_TEXT_FATAL, _) => None,
|
||||||
// -- help
|
// -- help
|
||||||
(COMPONENT_TEXT_HELP, &MSG_KEY_ESC) | (COMPONENT_TEXT_HELP, &MSG_KEY_ENTER) => {
|
(COMPONENT_TEXT_HELP, &MSG_KEY_ESC) | (COMPONENT_TEXT_HELP, &MSG_KEY_ENTER) => {
|
||||||
self.umount_help();
|
self.umount_help();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_TEXT_HELP, _) => None,
|
||||||
// -- progress bar
|
// -- progress bar
|
||||||
(COMPONENT_PROGRESS_BAR_PARTIAL, &MSG_KEY_CTRL_C) => {
|
(COMPONENT_PROGRESS_BAR_PARTIAL, &MSG_KEY_CTRL_C) => {
|
||||||
// Set transfer aborted to True
|
// Set transfer aborted to True
|
||||||
self.transfer.abort();
|
self.transfer.abort();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_PROGRESS_BAR_PARTIAL, _) => None,
|
||||||
// -- fallback
|
// -- fallback
|
||||||
(_, _) => None, // Nothing to do
|
(_, _) => None, // Nothing to do
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ impl Update for SetupActivity {
|
|||||||
self.umount_error();
|
self.umount_error();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_TEXT_ERROR, _) => None,
|
||||||
// Exit
|
// Exit
|
||||||
(COMPONENT_RADIO_QUIT, Msg::OnSubmit(Payload::One(Value::Usize(0)))) => {
|
(COMPONENT_RADIO_QUIT, Msg::OnSubmit(Payload::One(Value::Usize(0)))) => {
|
||||||
// Save changes
|
// Save changes
|
||||||
@@ -135,12 +136,14 @@ impl Update for SetupActivity {
|
|||||||
self.umount_quit();
|
self.umount_quit();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_RADIO_QUIT, _) => None,
|
||||||
// Close help
|
// Close help
|
||||||
(COMPONENT_TEXT_HELP, &MSG_KEY_ENTER) | (COMPONENT_TEXT_HELP, &MSG_KEY_ESC) => {
|
(COMPONENT_TEXT_HELP, &MSG_KEY_ENTER) | (COMPONENT_TEXT_HELP, &MSG_KEY_ESC) => {
|
||||||
// Umount help
|
// Umount help
|
||||||
self.umount_help();
|
self.umount_help();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_TEXT_HELP, _) => None,
|
||||||
// Delete key
|
// Delete key
|
||||||
(COMPONENT_RADIO_DEL_SSH_KEY, Msg::OnSubmit(Payload::One(Value::Usize(0)))) => {
|
(COMPONENT_RADIO_DEL_SSH_KEY, Msg::OnSubmit(Payload::One(Value::Usize(0)))) => {
|
||||||
// Delete key
|
// Delete key
|
||||||
@@ -156,6 +159,7 @@ impl Update for SetupActivity {
|
|||||||
self.umount_del_ssh_key();
|
self.umount_del_ssh_key();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_RADIO_DEL_SSH_KEY, _) => None,
|
||||||
// Save popup
|
// Save popup
|
||||||
(COMPONENT_RADIO_SAVE, Msg::OnSubmit(Payload::One(Value::Usize(0)))) => {
|
(COMPONENT_RADIO_SAVE, Msg::OnSubmit(Payload::One(Value::Usize(0)))) => {
|
||||||
// Save config
|
// Save config
|
||||||
@@ -170,6 +174,7 @@ impl Update for SetupActivity {
|
|||||||
self.umount_save_popup();
|
self.umount_save_popup();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
(COMPONENT_RADIO_SAVE, _) => None,
|
||||||
// Edit SSH Key
|
// Edit SSH Key
|
||||||
// <TAB> Change view
|
// <TAB> Change view
|
||||||
(COMPONENT_LIST_SSH_KEYS, &MSG_KEY_TAB) => {
|
(COMPONENT_LIST_SSH_KEYS, &MSG_KEY_TAB) => {
|
||||||
|
|||||||
@@ -30,38 +30,39 @@ use super::parser::parse_semver;
|
|||||||
// Others
|
// Others
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
struct TagInfo {
|
/// ## GithubTag
|
||||||
tag_name: String,
|
///
|
||||||
|
/// Info related to a github tag
|
||||||
|
pub struct GithubTag {
|
||||||
|
pub tag_name: String,
|
||||||
|
pub body: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### check_for_updates
|
/// ### check_for_updates
|
||||||
///
|
///
|
||||||
/// Check if there is a new version available for termscp.
|
/// Check if there is a new version available for termscp.
|
||||||
/// This is performed through the Github API
|
/// This is performed through the Github API
|
||||||
/// In case of success returns Ok(Option<String>), where the Option is Some(new_version); otherwise if no version is available, return None
|
/// In case of success returns Ok(Option<GithubTag>), where the Option is Some(new_version); otherwise if no version is available, return None
|
||||||
/// In case of error returns Error with the error description
|
/// In case of error returns Error with the error description
|
||||||
|
|
||||||
pub fn check_for_updates(current_version: &str) -> Result<Option<String>, String> {
|
pub fn check_for_updates(current_version: &str) -> Result<Option<GithubTag>, String> {
|
||||||
// Send request
|
// Send request
|
||||||
let github_version: Result<String, String> =
|
let github_tag: Result<GithubTag, String> =
|
||||||
match ureq::get("https://api.github.com/repos/veeso/termscp/releases/latest").call() {
|
match ureq::get("https://api.github.com/repos/veeso/termscp/releases/latest").call() {
|
||||||
Ok(response) => match response.into_json::<TagInfo>() {
|
Ok(response) => response.into_json::<GithubTag>().map_err(|x| x.to_string()),
|
||||||
Ok(tag_info) => Ok(tag_info.tag_name),
|
|
||||||
Err(err) => Err(err.to_string()),
|
|
||||||
},
|
|
||||||
Err(err) => Err(err.to_string()),
|
Err(err) => Err(err.to_string()),
|
||||||
};
|
};
|
||||||
// Check version
|
// Check version
|
||||||
match github_version {
|
match github_tag {
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
Ok(version) => {
|
Ok(tag) => {
|
||||||
// Parse version
|
// Parse version
|
||||||
match parse_semver(version.as_str()) {
|
match parse_semver(tag.tag_name.as_str()) {
|
||||||
Some(new_version) => {
|
Some(new_version) => {
|
||||||
// Check if version is different
|
// Check if version is different
|
||||||
if new_version.as_str() > current_version {
|
if new_version.as_str() > current_version {
|
||||||
Ok(Some(new_version)) // New version is available
|
Ok(Some(tag)) // New version is available
|
||||||
} else {
|
} else {
|
||||||
Ok(None) // No new version
|
Ok(None) // No new version
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user