Skip to main content

Mountain/IPC/WindServiceHandlers/NativeHost/
PickFolder.rs

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