diff --git a/.changes/dialog-can-create-directories.md b/.changes/dialog-can-create-directories.md new file mode 100644 index 0000000000..9b62fbdb63 --- /dev/null +++ b/.changes/dialog-can-create-directories.md @@ -0,0 +1,6 @@ +--- +"dialog": "patch" +"dialog-js": "patch" +--- + +Allow configuring `canCreateDirectories` for open and save dialogs on macOS, if not configured, it will be set to `true` by default. diff --git a/Cargo.lock b/Cargo.lock index 14cdd89b98..13b1616970 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -230,7 +230,7 @@ checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" [[package]] name = "api" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "log", "serde", @@ -6416,7 +6416,7 @@ dependencies = [ [[package]] name = "tauri-plugin-authenticator" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "authenticator", "base64 0.21.7", @@ -6438,7 +6438,7 @@ dependencies = [ [[package]] name = "tauri-plugin-autostart" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "auto-launch", "log", @@ -6451,7 +6451,7 @@ dependencies = [ [[package]] name = "tauri-plugin-barcode-scanner" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "log", "serde", @@ -6463,7 +6463,7 @@ dependencies = [ [[package]] name = "tauri-plugin-biometric" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "log", "serde", @@ -6476,7 +6476,7 @@ dependencies = [ [[package]] name = "tauri-plugin-cli" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "clap", "log", @@ -6489,7 +6489,7 @@ dependencies = [ [[package]] name = "tauri-plugin-clipboard-manager" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "arboard", "log", @@ -6502,7 +6502,7 @@ dependencies = [ [[package]] name = "tauri-plugin-deep-link" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "log", "serde", @@ -6515,7 +6515,7 @@ dependencies = [ [[package]] name = "tauri-plugin-dialog" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "glib 0.16.9", "log", @@ -6531,7 +6531,7 @@ dependencies = [ [[package]] name = "tauri-plugin-fs" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "anyhow", "glob", @@ -6550,7 +6550,7 @@ dependencies = [ [[package]] name = "tauri-plugin-global-shortcut" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "global-hotkey", "log", @@ -6563,7 +6563,7 @@ dependencies = [ [[package]] name = "tauri-plugin-http" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "data-url", "glob", @@ -6581,7 +6581,7 @@ dependencies = [ [[package]] name = "tauri-plugin-localhost" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "http 1.0.0", "log", @@ -6594,7 +6594,7 @@ dependencies = [ [[package]] name = "tauri-plugin-log" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "android_logger", "byte-unit", @@ -6613,7 +6613,7 @@ dependencies = [ [[package]] name = "tauri-plugin-nfc" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "log", "serde", @@ -6626,7 +6626,7 @@ dependencies = [ [[package]] name = "tauri-plugin-notification" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "chrono", "color-backtrace", @@ -6654,7 +6654,7 @@ dependencies = [ [[package]] name = "tauri-plugin-os" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "gethostname", "log", @@ -6670,7 +6670,7 @@ dependencies = [ [[package]] name = "tauri-plugin-persisted-scope" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "aho-corasick", "bincode", @@ -6684,7 +6684,7 @@ dependencies = [ [[package]] name = "tauri-plugin-positioner" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "log", "serde", @@ -6697,7 +6697,7 @@ dependencies = [ [[package]] name = "tauri-plugin-process" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "tauri", "tauri-plugin", @@ -6705,7 +6705,7 @@ dependencies = [ [[package]] name = "tauri-plugin-shell" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "encoding_rs", "log", @@ -6723,7 +6723,7 @@ dependencies = [ [[package]] name = "tauri-plugin-single-instance" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "log", "serde", @@ -6736,7 +6736,7 @@ dependencies = [ [[package]] name = "tauri-plugin-sql" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "futures-core", "log", @@ -6752,7 +6752,7 @@ dependencies = [ [[package]] name = "tauri-plugin-store" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "log", "serde", @@ -6764,7 +6764,7 @@ dependencies = [ [[package]] name = "tauri-plugin-stronghold" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "hex", "iota-crypto 0.23.1", @@ -6785,7 +6785,7 @@ dependencies = [ [[package]] name = "tauri-plugin-updater" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "base64 0.21.7", "dirs-next", @@ -6812,7 +6812,7 @@ dependencies = [ [[package]] name = "tauri-plugin-upload" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "futures-util", "log", @@ -6829,7 +6829,7 @@ dependencies = [ [[package]] name = "tauri-plugin-websocket" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "futures-util", "http 1.0.0", @@ -6846,7 +6846,7 @@ dependencies = [ [[package]] name = "tauri-plugin-window-state" -version = "2.0.0-beta.0" +version = "2.0.0-beta.1" dependencies = [ "bincode", "bitflags 2.4.2", diff --git a/plugins/deep-link/src/api-iife.js b/plugins/deep-link/src/api-iife.js index d46ebd7d19..6a37d74812 100644 --- a/plugins/deep-link/src/api-iife.js +++ b/plugins/deep-link/src/api-iife.js @@ -1 +1 @@ -if("__TAURI__"in window){var __TAURI_PLUGIN_DEEPLINK__=function(e){"use strict";function n(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}async function t(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}var r;async function i(e,r,i){const _="string"==typeof i?.target?{kind:"AnyLabel",label:i.target}:i?.target??{kind:"Any"};return t("plugin:event|listen",{event:e,target:_,handler:n(r)}).then((n=>async()=>async function(e,n){await t("plugin:event|unlisten",{event:e,eventId:n})}(e,n)))}async function _(){return await t("plugin:deep-link|get_current")}return"function"==typeof SuppressedError&&SuppressedError,function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WEBVIEW_CREATED="tauri://webview-created",e.FILE_DROP="tauri://file-drop",e.FILE_DROP_HOVER="tauri://file-drop-hover",e.FILE_DROP_CANCELLED="tauri://file-drop-cancelled"}(r||(r={})),e.getCurrent=_,e.onOpenUrl=async function(e){const n=await _();return null!=n&&e(n),await i("deep-link://new-url",(n=>e(n.payload)))},e}({});Object.defineProperty(window.__TAURI__,"deepLink",{value:__TAURI_PLUGIN_DEEPLINK__})} +if("__TAURI__"in window){var __TAURI_PLUGIN_DEEPLINK__=function(e){"use strict";function n(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}async function t(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}var r;async function _(e,r,_){const i="string"==typeof _?.target?{kind:"AnyLabel",label:_.target}:_?.target??{kind:"Any"};return t("plugin:event|listen",{event:e,target:i,handler:n(r)}).then((n=>async()=>async function(e,n){await t("plugin:event|unlisten",{event:e,eventId:n})}(e,n)))}async function i(){return await t("plugin:deep-link|get_current")}return"function"==typeof SuppressedError&&SuppressedError,function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WEBVIEW_CREATED="tauri://webview-created",e.WEBVIEW_FILE_DROP="tauri://file-drop",e.WEBVIEW_FILE_DROP_HOVER="tauri://file-drop-hover",e.WEBVIEW_FILE_DROP_CANCELLED="tauri://file-drop-cancelled"}(r||(r={})),e.getCurrent=i,e.onOpenUrl=async function(e){const n=await i();return null!=n&&e(n),await _("deep-link://new-url",(n=>e(n.payload)))},e}({});Object.defineProperty(window.__TAURI__,"deepLink",{value:__TAURI_PLUGIN_DEEPLINK__})} diff --git a/plugins/dialog/guest-js/index.ts b/plugins/dialog/guest-js/index.ts index 28dc2529c7..5aa440a675 100644 --- a/plugins/dialog/guest-js/index.ts +++ b/plugins/dialog/guest-js/index.ts @@ -55,6 +55,8 @@ interface OpenDialogOptions { * Defines whether subdirectories will be allowed on the scope or not. */ recursive?: boolean; + /** Whether to allow creating directories in the dialog. Enabled by default. **macOS Only** */ + canCreateDirectories?: boolean; } /** @@ -73,6 +75,8 @@ interface SaveDialogOptions { * If it's not an existing directory, the file name will be set to the dialog's file name input and the dialog will be set to the parent folder. */ defaultPath?: string; + /** Whether to allow creating directories in the dialog. Enabled by default. **macOS Only** */ + canCreateDirectories?: boolean; } /** diff --git a/plugins/dialog/src/commands.rs b/plugins/dialog/src/commands.rs index 1a525df0a1..f0dfb092e3 100644 --- a/plugins/dialog/src/commands.rs +++ b/plugins/dialog/src/commands.rs @@ -51,6 +51,8 @@ pub struct OpenDialogOptions { #[serde(default)] #[cfg_attr(mobile, allow(dead_code))] recursive: bool, + /// Whether to allow creating directories in the dialog **macOS Only** + can_create_directories: Option, } /// The options for the save dialog API. @@ -65,6 +67,8 @@ pub struct SaveDialogOptions { filters: Vec, /// The initial path of the dialog. default_path: Option, + /// Whether to allow creating directories in the dialog **macOS Only** + can_create_directories: Option, } fn set_default_path( @@ -105,6 +109,9 @@ pub(crate) async fn open( if let Some(default_path) = options.default_path { dialog_builder = set_default_path(dialog_builder, default_path); } + if let Some(can) = options.can_create_directories { + dialog_builder = dialog_builder.set_can_create_directories(can); + } for filter in options.filters { let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect(); dialog_builder = dialog_builder.add_filter(filter.name, &extensions); @@ -185,6 +192,9 @@ pub(crate) async fn save( if let Some(default_path) = options.default_path { dialog_builder = set_default_path(dialog_builder, default_path); } + if let Some(can) = options.can_create_directories { + dialog_builder = dialog_builder.set_can_create_directories(can); + } for filter in options.filters { let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect(); dialog_builder = dialog_builder.add_filter(filter.name, &extensions); diff --git a/plugins/dialog/src/desktop.rs b/plugins/dialog/src/desktop.rs index 82bb3fe689..7843f3b5ab 100644 --- a/plugins/dialog/src/desktop.rs +++ b/plugins/dialog/src/desktop.rs @@ -127,6 +127,8 @@ impl From> for FileDialog { builder = builder.set_parent(&WindowHandle(parent)); } + builder = builder.set_can_create_directories(d.can_create_directories.unwrap_or(true)); + builder } } diff --git a/plugins/dialog/src/lib.rs b/plugins/dialog/src/lib.rs index 62563731ba..0e9aa9dbd4 100644 --- a/plugins/dialog/src/lib.rs +++ b/plugins/dialog/src/lib.rs @@ -267,6 +267,7 @@ pub struct FileDialogBuilder { pub(crate) starting_directory: Option, pub(crate) file_name: Option, pub(crate) title: Option, + pub(crate) can_create_directories: Option, #[cfg(desktop)] pub(crate) parent: Option, } @@ -291,6 +292,7 @@ impl FileDialogBuilder { starting_directory: None, file_name: None, title: None, + can_create_directories: None, #[cfg(desktop)] parent: None, } @@ -345,6 +347,12 @@ impl FileDialogBuilder { self } + /// Set whether it should be possible to create new directories in the dialog. Enabled by default. **macOS only**. + pub fn set_can_create_directories(mut self, can: bool) -> Self { + self.can_create_directories.replace(can); + self + } + /// Shows the dialog to select a single file. /// This is not a blocking operation, /// and should be used when running on the main thread to avoid deadlocks with the event loop.