Skip to main content

DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/IPC/WindServiceHandlers/NativeHost/
PickFolder.rs

1//! Wire method: `nativeHost:pickFolderAndOpen`, `:pickFileAndOpen`,
2//! `:pickFileFolderAndOpen`, `:pickWorkspaceAndOpen`.
3//!
4//! Atom I1 (2026-04-21): before webview reload, mutate
5//! ApplicationState.Workspace and fire `$deltaWorkspaceFolders` to Cocoon so
6//! extensions see the folder arrive synchronously.
7
8use std::sync::Arc;
9
10use serde_json::Value;
11use tauri::{AppHandle, Manager};
12
13use crate::{
14	ApplicationState::{
15		DTO::WorkspaceFolderStateDTO::WorkspaceFolderStateDTO,
16		State::{
17			ApplicationState::ApplicationState,
18			WorkspaceState::WorkspaceDelta::UpdateWorkspaceFoldersAndBroadcast,
19		},
20	},
21	dev_log,
22};
23
24pub async fn Fn(ApplicationHandle:AppHandle, _Arguments:Vec<Value>) -> Result<Value, String> {
25	use std::path::PathBuf;
26
27	use tauri_plugin_dialog::DialogExt;
28
29	dev_log!("folder", "pickFolderAndOpen requested");
30
31	let Handle = ApplicationHandle.clone();
32
33	tokio::task::spawn_blocking(move || {
34		let FolderPath = Handle.dialog().file().blocking_pick_folder();
35
36		if let Some(Path) = FolderPath {
37			let PathStr = Path.to_string();
38			dev_log!("folder", "picked: {}", PathStr);
39
40			if let Some(State) = Handle.try_state::<Arc<ApplicationState>>() {
41				let PathBuf = PathBuf::from(&PathStr);
42				let Canonical = PathBuf.canonicalize().unwrap_or(PathBuf.clone());
43				if let Ok(Uri) = url::Url::from_directory_path(&Canonical) {
44					let Name = Canonical
45						.file_name()
46						.and_then(|N| N.to_str())
47						.map(str::to_string)
48						.unwrap_or_else(|| Canonical.display().to_string());
49					match WorkspaceFolderStateDTO::New(Uri, Name, 0) {
50						Ok(Dto) => {
51							dev_log!("folder", "pre-nav workspace-delta: broadcasting 1 folder to Cocoon");
52							UpdateWorkspaceFoldersAndBroadcast(&Handle, &State.Workspace, vec![Dto]);
53						},
54						Err(Error) => {
55							dev_log!(
56								"folder",
57								"warn: [pickFolderAndOpen] WorkspaceFolderStateDTO::New failed: {}",
58								Error
59							);
60						},
61					}
62				} else {
63					dev_log!(
64						"folder",
65						"warn: [pickFolderAndOpen] path → file URI conversion failed for {}",
66						PathStr
67					);
68				}
69			} else {
70				dev_log!(
71					"folder",
72					"warn: [pickFolderAndOpen] ApplicationState not managed by Tauri - delta skipped"
73				);
74			}
75
76			if let Some(Window) = Handle.get_webview_window("main") {
77				if let Ok(CurrentUrl) = Window.url() {
78					let Origin = CurrentUrl.origin().unicode_serialization();
79					let EncodedPath = url::form_urlencoded::Serializer::new(String::new())
80						.append_pair("folder", &PathStr)
81						.finish();
82					let NewUrl = format!("{}/?{}", Origin, EncodedPath);
83					dev_log!("folder", "navigating: {}", NewUrl);
84					let _ = Window.navigate(NewUrl.parse().unwrap());
85					dev_log!("folder", "post-nav Window.navigate() returned; webview reloading");
86				}
87			}
88		} else {
89			dev_log!("folder", "pickFolderAndOpen cancelled by user");
90		}
91	});
92
93	Ok(Value::Null)
94}