Skip to content

Commit

Permalink
implement logic for getting the installation progress (lapce#1281)
Browse files Browse the repository at this point in the history
* implement logic for getting the installation progress

* get the progress bar in the ui

* add status text to progress bar

* remove unused volt_downloader.rs + add suggestion from PR

* add progress indication if app is removed

* remove progress percentage + add ability for error text

* use rect height as distance to next progress, so it show's like a list

* use different font color if there is a error while installation

* handle remove_volt remove_dir_all error

* add error handeling for removing in progressbar

* remove redundant if statement in drawing progress

* show error messages from download plugins in the status bar

* run rustfmt

* Satisfy clippy: To big variants

* Satisfy clippy: adjust error check accordingly

* run rustfmt

* Satisfy clippy: fix local issues

* apply review changes

* only save (workspace) plugins if neccessary

* fix brackets after merge again
  • Loading branch information
tzAcee authored and ghishadow committed Sep 28, 2022
1 parent c0b4f0f commit 8a4788b
Show file tree
Hide file tree
Showing 9 changed files with 351 additions and 50 deletions.
6 changes: 4 additions & 2 deletions lapce-data/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,8 +561,10 @@ pub enum LapceUICommand {
UpdateExplorerItems(PathBuf, HashMap<PathBuf, FileNodeItem>, bool),
LoadPlugins(Vec<VoltInfo>),
LoadPluginsFailed,
VoltInstalled(VoltMetadata),
VoltRemoved(VoltInfo),
VoltInstalled(VoltMetadata, bool),
VoltInstalling(VoltMetadata, String),
VoltRemoving(VoltMetadata, String),
VoltRemoved(VoltInfo, bool),
EnableVolt(VoltInfo),
DisableVolt(VoltInfo),
EnableVoltWorkspace(VoltInfo),
Expand Down
55 changes: 46 additions & 9 deletions lapce-data/src/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub mod plugin_install_status;

use std::{collections::HashSet, sync::Arc};

use anyhow::Result;
Expand All @@ -8,6 +10,8 @@ use lapce_rpc::plugin::{VoltInfo, VoltMetadata};
use lsp_types::Url;
use strum_macros::Display;

use plugin_install_status::PluginInstallStatus;

use crate::{
command::{LapceUICommand, LAPCE_UI_COMMAND},
config::Config,
Expand Down Expand Up @@ -70,6 +74,7 @@ pub struct PluginData {
pub uninstalled_id: WidgetId,

pub volts: VoltsList,
pub installing: IndexMap<String, PluginInstallStatus>,
pub installed: IndexMap<String, VoltMetadata>,
pub disabled: HashSet<String>,
pub workspace_disabled: HashSet<String>,
Expand Down Expand Up @@ -98,6 +103,7 @@ impl PluginData {
installed_id: WidgetId::next(),
uninstalled_id: WidgetId::next(),
volts: VoltsList::new(),
installing: IndexMap::new(),
installed: IndexMap::new(),
disabled: HashSet::from_iter(disabled.into_iter()),
workspace_disabled: HashSet::from_iter(workspace_disabled.into_iter()),
Expand All @@ -109,7 +115,7 @@ impl PluginData {
if meta.wasm.is_none() {
let _ = event_sink.submit_command(
LAPCE_UI_COMMAND,
LapceUICommand::VoltInstalled(meta),
LapceUICommand::VoltInstalled(meta, false),
Target::Widget(tab_id),
);
}
Expand Down Expand Up @@ -184,29 +190,60 @@ impl PluginData {
pub fn install_volt(proxy: Arc<LapceProxy>, volt: VoltInfo) -> Result<()> {
let meta_str = reqwest::blocking::get(&volt.meta)?.text()?;
let meta: VoltMetadata = toml_edit::easy::from_str(&meta_str)?;

proxy.core_rpc.volt_installing(meta.clone(), "".to_string());

if meta.wasm.is_some() {
proxy.proxy_rpc.install_volt(volt);
} else {
std::thread::spawn(move || -> Result<()> {
let meta = download_volt(volt, false)?;
proxy.core_rpc.volt_installed(meta);
let download_volt_result =
download_volt(volt, true, &meta, &meta_str);
if download_volt_result.is_err() {
proxy.core_rpc.volt_installing(
meta.clone(),
"Could not download Volt".to_string(),
);
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_secs(3));
proxy.core_rpc.volt_installed(meta, true);
});
return Ok(());
}

let meta = download_volt_result?;
proxy.core_rpc.volt_installed(meta, false);
Ok(())
});
}
Ok(())
}

pub fn remove_volt(proxy: Arc<LapceProxy>, meta: VoltMetadata) -> Result<()> {
proxy.core_rpc.volt_removing(meta.clone(), "".to_string());
if meta.wasm.is_some() {
proxy.proxy_rpc.remove_volt(meta);
} else {
std::thread::spawn(move || -> Result<()> {
let path = meta
.dir
.as_ref()
.ok_or_else(|| anyhow::anyhow!("don't have dir"))?;
std::fs::remove_dir_all(path)?;
proxy.core_rpc.volt_removed(meta.info());
let path = meta.dir.as_ref().ok_or_else(|| {
proxy.core_rpc.volt_removing(
meta.clone(),
"Plugin Directory does not exist".to_string(),
);
anyhow::anyhow!("don't have dir")
})?;
if std::fs::remove_dir_all(path).is_err() {
proxy.core_rpc.volt_removing(
meta.clone(),
"Could not remove Plugin Directory".to_string(),
);
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_secs(3));
proxy.core_rpc.volt_removed(meta.info(), true);
});
} else {
proxy.core_rpc.volt_removed(meta.info(), false);
}
Ok(())
});
}
Expand Down
42 changes: 42 additions & 0 deletions lapce-data/src/plugin/plugin_install_status.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum PluginInstallType {
Installation,
Uninstallation,
}

#[derive(Clone, Debug)]
pub struct PluginInstallStatus {
error: String,
plugin_name: String,
install_type: PluginInstallType,
}

impl PluginInstallStatus {
pub fn new(
install_type: PluginInstallType,
plugin_name: &str,
error: String,
) -> Self {
Self {
error,
plugin_name: plugin_name.to_string(),
install_type,
}
}

pub fn set_error(&mut self, error_string: &str) {
self.error = error_string.to_string();
}

pub fn error_string(&self) -> &str {
&self.error
}

pub fn install_type(&self) -> &PluginInstallType {
&self.install_type
}

pub fn plugin_name(&self) -> &str {
&self.plugin_name
}
}
28 changes: 24 additions & 4 deletions lapce-data/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,17 +179,37 @@ impl CoreHandler for LapceProxy {
Target::Widget(self.tab_id),
);
}
VoltInstalled { volt } => {
VoltInstalled {
volt,
only_installing,
} => {
let _ = self.event_sink.submit_command(
LAPCE_UI_COMMAND,
LapceUICommand::VoltInstalled(volt, only_installing),
Target::Widget(self.tab_id),
);
}
VoltInstalling { volt, error } => {
let _ = self.event_sink.submit_command(
LAPCE_UI_COMMAND,
LapceUICommand::VoltInstalled(volt),
LapceUICommand::VoltInstalling(volt, error),
Target::Widget(self.tab_id),
);
}
VoltRemoved { volt } => {
VoltRemoving { volt, error } => {
let _ = self.event_sink.submit_command(
LAPCE_UI_COMMAND,
LapceUICommand::VoltRemoving(volt, error),
Target::Widget(self.tab_id),
);
}
VoltRemoved {
volt,
only_installing,
} => {
let _ = self.event_sink.submit_command(
LAPCE_UI_COMMAND,
LapceUICommand::VoltRemoved(volt),
LapceUICommand::VoltRemoved(volt, only_installing),
Target::Widget(self.tab_id),
);
}
Expand Down
66 changes: 51 additions & 15 deletions lapce-proxy/src/plugin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -855,10 +855,12 @@ pub enum PluginNotification {
},
}

pub fn download_volt(volt: VoltInfo, wasm: bool) -> Result<VoltMetadata> {
let meta_str = reqwest::blocking::get(&volt.meta)?.text()?;
let meta: VoltMetadata = toml_edit::easy::from_str(&meta_str)?;

pub fn download_volt(
volt: VoltInfo,
wasm: bool,
meta: &VoltMetadata,
meta_str: &String,
) -> Result<VoltMetadata> {
if meta.wasm.is_some() != wasm {
return Err(anyhow!("plugin type not fit"));
}
Expand All @@ -879,7 +881,6 @@ pub fn download_volt(volt: VoltInfo, wasm: bool) -> Result<VoltMetadata> {
.open(&meta_path)?;
file.write_all(meta_str.as_bytes())?;
}

let url = url::Url::parse(&volt.meta)?;
if let Some(wasm) = meta.wasm.as_ref() {
let url = url.join(wasm)?;
Expand Down Expand Up @@ -923,24 +924,59 @@ pub fn install_volt(
configurations: Option<serde_json::Value>,
volt: VoltInfo,
) -> Result<()> {
let meta = download_volt(volt, true)?;
let local_catalog_rpc = catalog_rpc.clone();
let local_meta = meta.clone();
thread::spawn(move || {
let _ = start_volt(workspace, configurations, local_catalog_rpc, local_meta);
});
let meta_str = reqwest::blocking::get(&volt.meta)?.text()?;
let meta: VoltMetadata = toml_edit::easy::from_str(&meta_str)?;

catalog_rpc.core_rpc.volt_installed(meta);
thread::spawn(move || -> Result<()> {
let download_volt_result = download_volt(volt, true, &meta, &meta_str);
if download_volt_result.is_err() {
catalog_rpc.core_rpc.volt_installing(
meta.clone(),
"Could not download Volt".to_string(),
);
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_secs(3));
catalog_rpc.core_rpc.volt_installed(meta, true);
});
return Ok(());
}

let meta = download_volt_result?;
let local_catalog_rpc = catalog_rpc.clone();
let local_meta = meta.clone();

let _ = start_volt(workspace, configurations, local_catalog_rpc, local_meta);
catalog_rpc.core_rpc.volt_installed(meta, false);
Ok(())
});
Ok(())
}

pub fn remove_volt(
catalog_rpc: PluginCatalogRpcHandler,
volt: VoltMetadata,
) -> Result<()> {
let path = volt.dir.as_ref().ok_or_else(|| anyhow!("don't have dir"))?;
fs::remove_dir_all(path)?;
catalog_rpc.core_rpc.volt_removed(volt.info());
thread::spawn(move || -> Result<()> {
let path = volt.dir.as_ref().ok_or_else(|| {
catalog_rpc
.core_rpc
.volt_removing(volt.clone(), "Plugin Directory not set".to_string());
anyhow::anyhow!("don't have dir")
})?;
if let Err(e) = std::fs::remove_dir_all(path) {
eprintln!("Could not delete plugin folder: {}", e);
catalog_rpc.core_rpc.volt_removing(
volt.clone(),
"Could not remove Plugin Directory".to_string(),
);
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_secs(3));
catalog_rpc.core_rpc.volt_removed(volt.info(), true);
});
} else {
catalog_rpc.core_rpc.volt_removed(volt.info(), false);
}
Ok(())
});
Ok(())
}
2 changes: 1 addition & 1 deletion lapce-proxy/src/plugin/wasi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ pub fn load_all_volts(
if meta.wasm.is_none() {
continue;
}
plugin_rpc.core_rpc.volt_installed(meta.clone());
plugin_rpc.core_rpc.volt_installed(meta.clone(), false);
if disabled_volts.contains(&meta.id()) {
continue;
}
Expand Down
38 changes: 31 additions & 7 deletions lapce-rpc/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{

pub enum CoreRpc {
Request(RequestId, CoreRequest),
Notification(CoreNotification),
Notification(Box<CoreNotification>), // Box it since clippy complains
Shutdown,
}

Expand Down Expand Up @@ -62,9 +62,19 @@ pub enum CoreNotification {
},
VoltInstalled {
volt: VoltMetadata,
only_installing: bool,
},
VoltInstalling {
volt: VoltMetadata,
error: String,
},
VoltRemoving {
volt: VoltMetadata,
error: String,
},
VoltRemoved {
volt: VoltInfo,
only_installing: bool,
},
ListDir {
items: Vec<FileNodeItem>,
Expand Down Expand Up @@ -133,7 +143,7 @@ impl CoreRpcHandler {
handler.handle_request(id, rpc);
}
CoreRpc::Notification(rpc) => {
handler.handle_notification(rpc);
handler.handle_notification(*rpc);
}
CoreRpc::Shutdown => {
return;
Expand Down Expand Up @@ -178,7 +188,7 @@ impl CoreRpcHandler {
}

pub fn notification(&self, notification: CoreNotification) {
let _ = self.tx.send(CoreRpc::Notification(notification));
let _ = self.tx.send(CoreRpc::Notification(Box::new(notification)));
}

pub fn proxy_connected(&self) {
Expand Down Expand Up @@ -212,12 +222,26 @@ impl CoreRpcHandler {
});
}

pub fn volt_installed(&self, volt: VoltMetadata) {
self.notification(CoreNotification::VoltInstalled { volt });
pub fn volt_installed(&self, volt: VoltMetadata, only_installing: bool) {
self.notification(CoreNotification::VoltInstalled {
volt,
only_installing,
});
}

pub fn volt_installing(&self, volt: VoltMetadata, error: String) {
self.notification(CoreNotification::VoltInstalling { volt, error });
}

pub fn volt_removed(&self, volt: VoltInfo) {
self.notification(CoreNotification::VoltRemoved { volt });
pub fn volt_removing(&self, volt: VoltMetadata, error: String) {
self.notification(CoreNotification::VoltRemoving { volt, error });
}

pub fn volt_removed(&self, volt: VoltInfo, only_installing: bool) {
self.notification(CoreNotification::VoltRemoved {
volt,
only_installing,
});
}

pub fn log(&self, level: log::Level, message: String) {
Expand Down
Loading

0 comments on commit 8a4788b

Please sign in to comment.