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