diff --git a/monobean/src/application.rs b/monobean/src/application.rs index 6ecc03e42..03cd320c1 100644 --- a/monobean/src/application.rs +++ b/monobean/src/application.rs @@ -43,10 +43,7 @@ pub enum Action { ShowHelloPage, ShowMainPage, MountRepo, - OpenEditorOn{ - hash: String, - name: String, - }, + OpenEditorOn { hash: String, name: String }, } mod imp { @@ -445,7 +442,7 @@ impl MonobeanApplication { window.show_main_page(); } Action::MountRepo => todo!(), - Action::OpenEditorOn{hash, name} => { + Action::OpenEditorOn { hash, name } => { CONTEXT.spawn_local(async move { let window = window.imp(); let code_page = window.code_page.get(); diff --git a/monobean/src/components/hello_page.rs b/monobean/src/components/hello_page.rs index 572b4d731..7af4792d6 100644 --- a/monobean/src/components/hello_page.rs +++ b/monobean/src/components/hello_page.rs @@ -176,7 +176,7 @@ impl HelloPage { // TODO: Ask user to input a passwd for pgp key. let sender = sender.clone(); let (tx, rx) = oneshot::channel(); - let pgp_command = Action::MegaCore(MegaCommands::LoadOrInitPgp{ + let pgp_command = Action::MegaCore(MegaCommands::LoadOrInitPgp { chan: tx, user_name: name_entry.text().parse().unwrap(), user_email: email_entry.text().parse().unwrap(), diff --git a/monobean/src/config.rs b/monobean/src/config.rs index 962428833..ca2f195e3 100644 --- a/monobean/src/config.rs +++ b/monobean/src/config.rs @@ -81,7 +81,7 @@ macro_rules! get_setting { /// 1. Uses the `MONOBEAN_BASE_DIR` environment variable if set /// 2. Falls back to system default paths when environment variable is not set: /// - On Linux: `~/.local/share/monobean` -/// - On Windows: `C:\ProgramData\monobean` +/// - On Windows: `C:\Users\{UserName}\AppData\Local\monobean` /// - On macOS: `~/Library/Application Support/monobean` /// /// # Returns diff --git a/monobean/src/core/mega_core.rs b/monobean/src/core/mega_core.rs index e84c348c1..cadba8386 100644 --- a/monobean/src/core/mega_core.rs +++ b/monobean/src/core/mega_core.rs @@ -3,8 +3,10 @@ use crate::core::servers::{HttpOptions, SshOptions}; use crate::core::CoreConfigChanged; use crate::error::{MonoBeanError, MonoBeanResult}; use async_channel::{Receiver, Sender}; +use ceres::api_service::import_api_service::ImportApiService; use ceres::api_service::mono_api_service::MonoApiService; use ceres::api_service::ApiHandler; +use ceres::protocol::repo::Repo; use common::config::Config; use common::model::P2pOptions; use jupiter::context::Context as MegaContext; @@ -12,7 +14,7 @@ use mercury::internal::object::tree::Tree; use std::fmt; use std::fmt::{Debug, Formatter}; use std::net::SocketAddr; -use std::path::PathBuf; +use std::path::{Component, Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use tokio::sync::{oneshot, OnceCell, RwLock}; @@ -266,12 +268,54 @@ impl MegaCore { *self.running_context.write().await = None; } - async fn load_tree(&self, path: Option) -> MonoBeanResult { - let ctx = self.running_context.read().await.clone().unwrap(); - let mono = MonoApiService { context: ctx }; + async fn api_handler(&self, path: impl AsRef) -> MonoBeanResult> { + let ctx = self.running_context.read().await.clone(); + if ctx.is_none() { + let err_msg = "Mega core is not running"; + tracing::error!(err_msg); + return Err(MonoBeanError::MegaCoreError(err_msg.to_string())); + } + + let ctx = ctx.unwrap(); + let import_dir = ctx.config.monorepo.import_dir.clone(); + + if path.as_ref().starts_with(&import_dir) && path.as_ref() != import_dir { + if let Some(model) = ctx + .services + .git_db_storage + .find_git_repo_like_path(path.as_ref().to_string_lossy().as_ref()) + .await + .unwrap() + { + let repo: Repo = model.into(); + return Ok(Box::new(ImportApiService { + context: ctx.clone(), + repo, + })); + } + } + let ret: Box = Box::new(MonoApiService { + context: ctx.clone(), + }); + + // Rust-analyzer cannot infer the type of `ret` correctly and always reports an error. + // Use `.into()` to workaround this issue. + #[allow(clippy::useless_conversion)] + Ok(ret.into()) + } + async fn load_tree(&self, path: Option) -> MonoBeanResult { let path = path.unwrap_or(PathBuf::from("/")); - let tree = mono.search_tree_by_path(&path).await; + let path = path + .components() + .filter(|c| !matches!(c, Component::RootDir)) + .fold("/".to_owned(), |acc, e| { + acc + &e.as_os_str().to_string_lossy() + "/" + }); + let path = PathBuf::from(path); + + let handler = self.api_handler(&path).await?; + let tree = handler.search_tree_by_path(&path).await; match tree { Ok(Some(tree)) => Ok(tree), _ => { @@ -290,21 +334,19 @@ impl MegaCore { .await .map_err(|err| MonoBeanError::MegaCoreError(err.to_string()))?; match raw { - Some(model) => { - match model.data { - Some(data) => match String::from_utf8(data) { - Ok(string) => Ok(string), - Err(err) => { - let err_msg = format!("Invalid UTF-8 data: {}", err); - tracing::error!(err_msg); - Err(MonoBeanError::MegaCoreError(err_msg)) - } - }, - None => { - let err_msg = "Blob data is missing".to_string(); + Some(model) => match model.data { + Some(data) => match String::from_utf8(data) { + Ok(string) => Ok(string), + Err(err) => { + let err_msg = format!("Invalid UTF-8 data: {}", err); tracing::error!(err_msg); Err(MonoBeanError::MegaCoreError(err_msg)) } + }, + None => { + let err_msg = "Blob data is missing".to_string(); + tracing::error!(err_msg); + Err(MonoBeanError::MegaCoreError(err_msg)) } }, _ => Ok(String::default()), diff --git a/monobean/src/main.rs b/monobean/src/main.rs index 01b31d709..8a7a15d7c 100644 --- a/monobean/src/main.rs +++ b/monobean/src/main.rs @@ -26,7 +26,8 @@ fn main() -> glib::ExitCode { let resources = { gio::Resource::load("Monobean.gresource").unwrap_or_else(|_| { - gio::Resource::load("/usr/share/monobean/monobean.gresource").expect("Failed to load resources") + gio::Resource::load("/usr/share/monobean/monobean.gresource") + .expect("Failed to load resources") }) }; gio::resources_register(&resources); diff --git a/monobean/src/window.rs b/monobean/src/window.rs index 33ff4860e..3004e4bc6 100644 --- a/monobean/src/window.rs +++ b/monobean/src/window.rs @@ -153,19 +153,20 @@ impl MonobeanWindow { fn setup_page(&self) { let imp = self.imp(); - let code_page= imp.code_page.get(); + let code_page = imp.code_page.get(); imp.hello_page.setup_hello_page(self.sender()); code_page.setup_code_page(self.sender(), None); - imp.content_stack.connect_visible_child_name_notify(move |stk| { - if stk.visible_child_name().is_some_and(|name| name == "code"){ - let file_tree = code_page.imp().file_tree_view.get(); - CONTEXT.spawn_local_with_priority(Priority::LOW, async move { - file_tree.refresh_root().await; - }); - } - }); + imp.content_stack + .connect_visible_child_name_notify(move |stk| { + if stk.visible_child_name().is_some_and(|name| name == "code") { + let file_tree = code_page.imp().file_tree_view.get(); + CONTEXT.spawn_local_with_priority(Priority::LOW, async move { + file_tree.refresh_root().await; + }); + } + }); // We are developing, so always show hello_page for debug let stack = imp.base_stack.clone();