Mountain/IPC/WindServiceHandlers/NativeDialog/
ShowOpenDialog.rs1use serde_json::{Value, json};
17use tauri::AppHandle;
18
19use crate::{IPC::WindServiceHandlers::NativeDialog::ParseDialogFilters::Fn as ParseDialogFilters, dev_log};
20
21pub async fn Fn(ApplicationHandle:AppHandle, Args:Vec<Value>) -> Result<Value, String> {
22 use tauri_plugin_dialog::DialogExt;
23
24 dev_log!("folder", "showOpenDialog: {:?}", Args);
25
26 let Options = Args.iter().rev().find(|V| V.is_object()).cloned().unwrap_or(Value::Null);
31
32 let Properties:Vec<String> = Options
33 .get("properties")
34 .and_then(Value::as_array)
35 .map(|Array| Array.iter().filter_map(|V| V.as_str().map(str::to_string)).collect())
36 .unwrap_or_default();
37
38 let IsFolder = Properties.iter().any(|P| P == "openDirectory");
39
40 let IsMultiple = Properties.iter().any(|P| P == "multiSelections");
41
42 let Title = Options
43 .get("title")
44 .and_then(Value::as_str)
45 .unwrap_or(if IsFolder { "Open Folder" } else { "Open File" })
46 .to_string();
47
48 let DefaultPath = Options.get("defaultPath").and_then(Value::as_str).map(str::to_string);
49
50 let Filters = ParseDialogFilters(&Options);
51
52 let Handle = ApplicationHandle.clone();
53
54 let FiltersForThread = Filters.clone();
55
56 let Selected = tokio::task::spawn_blocking(move || -> Vec<String> {
57 let mut Builder = Handle.dialog().file().set_title(&Title);
58
59 if let Some(Path) = DefaultPath.as_deref() {
60 Builder = Builder.set_directory(Path);
61 }
62
63 if !IsFolder {
66 for Filter in &FiltersForThread {
67 let ExtRefs:Vec<&str> = Filter.Extensions.iter().map(String::as_str).collect();
68
69 Builder = Builder.add_filter(&Filter.Name, &ExtRefs);
70 }
71 }
72
73 if IsFolder {
74 if IsMultiple {
75 Builder
76 .blocking_pick_folders()
77 .unwrap_or_default()
78 .into_iter()
79 .map(|P| P.to_string())
80 .collect()
81 } else {
82 Builder.blocking_pick_folder().map(|P| vec![P.to_string()]).unwrap_or_default()
83 }
84 } else if IsMultiple {
85 Builder
86 .blocking_pick_files()
87 .unwrap_or_default()
88 .into_iter()
89 .map(|P| P.to_string())
90 .collect()
91 } else {
92 Builder.blocking_pick_file().map(|P| vec![P.to_string()]).unwrap_or_default()
93 }
94 })
95 .await
96 .map_err(|Error| format!("showOpenDialog join error: {}", Error))?;
97
98 if Selected.is_empty() {
99 dev_log!("folder", "showOpenDialog cancelled by user");
100
101 Ok(json!({ "canceled": true, "filePaths": [] }))
102 } else {
103 dev_log!(
104 "folder",
105 "showOpenDialog selected {} path(s) (folder={}, multi={}, filters={})",
106 Selected.len(),
107 IsFolder,
108 IsMultiple,
109 Filters.len()
110 );
111
112 Ok(json!({ "canceled": false, "filePaths": Selected }))
113 }
114}