From 24154472a6710a690173df0a121125d1f1b871e8 Mon Sep 17 00:00:00 2001 From: Tony <68118705+Legend-Master@users.noreply.github.com> Date: Sun, 1 Mar 2026 10:55:33 +0800 Subject: [PATCH] refactor(dialog): reuse `message` command for confirm (#3287) * chore(dialog): reuse `message` command for confirm * Add change file * Remove ask and confirm from default permissions * Format * Remove extra `toString` * Point `allow-confirm` to `allow-message` --- .changes/re-use-message-dialog-command.md | 6 ++ examples/api/src-tauri/capabilities/base.json | 6 +- plugins/dialog/api-iife.js | 2 +- plugins/dialog/build.rs | 2 +- plugins/dialog/guest-js/index.ts | 61 ++++++++++------- plugins/dialog/permissions/ask.toml | 11 ++++ .../autogenerated/commands/ask.toml | 13 ---- .../autogenerated/commands/confirm.toml | 13 ---- .../permissions/autogenerated/reference.md | 58 ++++++++--------- plugins/dialog/permissions/confirm.toml | 11 ++++ plugins/dialog/permissions/default.toml | 8 +-- .../dialog/permissions/schemas/schema.json | 36 +++++----- plugins/dialog/src/commands.rs | 65 +------------------ plugins/dialog/src/lib.rs | 5 +- 14 files changed, 121 insertions(+), 176 deletions(-) create mode 100644 .changes/re-use-message-dialog-command.md create mode 100644 plugins/dialog/permissions/ask.toml delete mode 100644 plugins/dialog/permissions/autogenerated/commands/ask.toml delete mode 100644 plugins/dialog/permissions/autogenerated/commands/confirm.toml create mode 100644 plugins/dialog/permissions/confirm.toml diff --git a/.changes/re-use-message-dialog-command.md b/.changes/re-use-message-dialog-command.md new file mode 100644 index 00000000..72c8584a --- /dev/null +++ b/.changes/re-use-message-dialog-command.md @@ -0,0 +1,6 @@ +--- +"dialog": minor +"dialog-js": minor +--- + +Re-use `message` command in Rust side for `ask` and `confirm` commands, `allow-ask` and `allow-confirm` permissions are now aliases to `allow-message` diff --git a/examples/api/src-tauri/capabilities/base.json b/examples/api/src-tauri/capabilities/base.json index 09d028da..f7fd7dff 100644 --- a/examples/api/src-tauri/capabilities/base.json +++ b/examples/api/src-tauri/capabilities/base.json @@ -23,11 +23,7 @@ "core:window:allow-start-dragging", "notification:default", "os:allow-platform", - "dialog:allow-open", - "dialog:allow-ask", - "dialog:allow-save", - "dialog:allow-confirm", - "dialog:allow-message", + "dialog:default", { "identifier": "shell:allow-spawn", "allow": [ diff --git a/plugins/dialog/api-iife.js b/plugins/dialog/api-iife.js index a357f2c0..30bc8c91 100644 --- a/plugins/dialog/api-iife.js +++ b/plugins/dialog/api-iife.js @@ -1 +1 @@ -if("__TAURI__"in window){var __TAURI_PLUGIN_DIALOG__=function(t){"use strict";async function n(t,n={},e){return window.__TAURI_INTERNALS__.invoke(t,n,e)}function e(t){if(void 0!==t)return"string"==typeof t?t:"ok"in t&&"cancel"in t?{OkCancelCustom:[t.ok,t.cancel]}:"yes"in t&&"no"in t&&"cancel"in t?{YesNoCancelCustom:[t.yes,t.no,t.cancel]}:"ok"in t?{OkCustom:t.ok}:void 0}return"function"==typeof SuppressedError&&SuppressedError,t.ask=async function(t,e){const o="string"==typeof e?{title:e}:e;return await n("plugin:dialog|ask",{message:t.toString(),title:o?.title?.toString(),kind:o?.kind,yesButtonLabel:o?.okLabel?.toString(),noButtonLabel:o?.cancelLabel?.toString()})},t.confirm=async function(t,e){const o="string"==typeof e?{title:e}:e;return await n("plugin:dialog|confirm",{message:t.toString(),title:o?.title?.toString(),kind:o?.kind,okButtonLabel:o?.okLabel?.toString(),cancelButtonLabel:o?.cancelLabel?.toString()})},t.message=async function(t,o){const i="string"==typeof o?{title:o}:o;return n("plugin:dialog|message",{message:t.toString(),title:i?.title?.toString(),kind:i?.kind,okButtonLabel:i?.okLabel?.toString(),buttons:e(i?.buttons)})},t.open=async function(t={}){return"object"==typeof t&&Object.freeze(t),await n("plugin:dialog|open",{options:t})},t.save=async function(t={}){return"object"==typeof t&&Object.freeze(t),await n("plugin:dialog|save",{options:t})},t}({});Object.defineProperty(window.__TAURI__,"dialog",{value:__TAURI_PLUGIN_DIALOG__})} +if("__TAURI__"in window){var __TAURI_PLUGIN_DIALOG__=function(n){"use strict";async function e(n,e={},t){return window.__TAURI_INTERNALS__.invoke(n,e,t)}function t(n){if(void 0!==n)return"string"==typeof n?n:"ok"in n&&"cancel"in n?{OkCancelCustom:[n.ok,n.cancel]}:"yes"in n&&"no"in n&&"cancel"in n?{YesNoCancelCustom:[n.yes,n.no,n.cancel]}:"ok"in n?{OkCustom:n.ok}:void 0}async function o(n,o){return await e("plugin:dialog|message",{message:n,title:o?.title,kind:o?.kind,okButtonLabel:o?.okLabel,buttons:t(o?.buttons)})}return"function"==typeof SuppressedError&&SuppressedError,n.ask=async function(n,e){const t="string"==typeof e?{title:e}:e,i=t?.okLabel||t?.cancelLabel,a=t?.okLabel??"Yes";return await o(n,{title:t?.title,kind:t?.kind,buttons:i?{ok:a,cancel:t.cancelLabel??"No"}:"YesNo"})===a},n.confirm=async function(n,e){const t="string"==typeof e?{title:e}:e,i=t?.okLabel||t?.cancelLabel,a=t?.okLabel??"Ok";return await o(n,{title:t?.title,kind:t?.kind,buttons:i?{ok:a,cancel:t.cancelLabel??"Cancel"}:"OkCancel"})===a},n.message=async function(n,e){return o(n,"string"==typeof e?{title:e}:e)},n.open=async function(n={}){return"object"==typeof n&&Object.freeze(n),await e("plugin:dialog|open",{options:n})},n.save=async function(n={}){return"object"==typeof n&&Object.freeze(n),await e("plugin:dialog|save",{options:n})},n}({});Object.defineProperty(window.__TAURI__,"dialog",{value:__TAURI_PLUGIN_DIALOG__})} diff --git a/plugins/dialog/build.rs b/plugins/dialog/build.rs index 4b3bb871..a94f61ac 100644 --- a/plugins/dialog/build.rs +++ b/plugins/dialog/build.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -const COMMANDS: &[&str] = &["open", "save", "message", "ask", "confirm"]; +const COMMANDS: &[&str] = &["open", "save", "message"]; fn main() { let result = tauri_plugin::Builder::new(COMMANDS) diff --git a/plugins/dialog/guest-js/index.ts b/plugins/dialog/guest-js/index.ts index df7d7b1c..f51a4f9f 100644 --- a/plugins/dialog/guest-js/index.ts +++ b/plugins/dialog/guest-js/index.ts @@ -405,6 +405,16 @@ async function save(options: SaveDialogOptions = {}): Promise { */ export type MessageDialogResult = 'Yes' | 'No' | 'Ok' | 'Cancel' | (string & {}) +async function messageCommand(message: string, options?: MessageDialogOptions) { + return await invoke('plugin:dialog|message', { + message, + title: options?.title, + kind: options?.kind, + okButtonLabel: options?.okLabel, + buttons: buttonsToRust(options?.buttons) + }) +} + /** * Shows a message dialog with an `Ok` button. * @example @@ -427,18 +437,14 @@ async function message( options?: string | MessageDialogOptions ): Promise { const opts = typeof options === 'string' ? { title: options } : options - - return invoke('plugin:dialog|message', { - message: message.toString(), - title: opts?.title?.toString(), - kind: opts?.kind, - okButtonLabel: opts?.okLabel?.toString(), - buttons: buttonsToRust(opts?.buttons) - }) + return messageCommand(message, opts) } /** * Shows a question dialog with `Yes` and `No` buttons. + * + * Convenient wrapper for `await message('msg', { buttons: 'YesNo' }) === 'Yes'` + * * @example * ```typescript * import { ask } from '@tauri-apps/plugin-dialog'; @@ -458,17 +464,24 @@ async function ask( options?: string | ConfirmDialogOptions ): Promise { const opts = typeof options === 'string' ? { title: options } : options - return await invoke('plugin:dialog|ask', { - message: message.toString(), - title: opts?.title?.toString(), - kind: opts?.kind, - yesButtonLabel: opts?.okLabel?.toString(), - noButtonLabel: opts?.cancelLabel?.toString() - }) + const customButtons = opts?.okLabel || opts?.cancelLabel + const okLabel = opts?.okLabel ?? 'Yes' + return ( + (await messageCommand(message, { + title: opts?.title, + kind: opts?.kind, + buttons: customButtons + ? { ok: okLabel, cancel: opts.cancelLabel ?? 'No' } + : 'YesNo' + })) === okLabel + ) } /** * Shows a question dialog with `Ok` and `Cancel` buttons. + * + * Convenient wrapper for `await message('msg', { buttons: 'OkCancel' }) === 'Ok'` + * * @example * ```typescript * import { confirm } from '@tauri-apps/plugin-dialog'; @@ -488,13 +501,17 @@ async function confirm( options?: string | ConfirmDialogOptions ): Promise { const opts = typeof options === 'string' ? { title: options } : options - return await invoke('plugin:dialog|confirm', { - message: message.toString(), - title: opts?.title?.toString(), - kind: opts?.kind, - okButtonLabel: opts?.okLabel?.toString(), - cancelButtonLabel: opts?.cancelLabel?.toString() - }) + const customButtons = opts?.okLabel || opts?.cancelLabel + const okLabel = opts?.okLabel ?? 'Ok' + return ( + (await messageCommand(message, { + title: opts?.title, + kind: opts?.kind, + buttons: customButtons + ? { ok: okLabel, cancel: opts.cancelLabel ?? 'Cancel' } + : 'OkCancel' + })) === okLabel + ) } export type { diff --git a/plugins/dialog/permissions/ask.toml b/plugins/dialog/permissions/ask.toml new file mode 100644 index 00000000..7f79e84b --- /dev/null +++ b/plugins/dialog/permissions/ask.toml @@ -0,0 +1,11 @@ +"$schema" = "schemas/schema.json" + +[[permission]] +identifier = "allow-ask" +description = "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)" +commands.allow = ["message"] + +[[permission]] +identifier = "deny-ask" +description = "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)" +commands.deny = ["message"] diff --git a/plugins/dialog/permissions/autogenerated/commands/ask.toml b/plugins/dialog/permissions/autogenerated/commands/ask.toml deleted file mode 100644 index 4142c59f..00000000 --- a/plugins/dialog/permissions/autogenerated/commands/ask.toml +++ /dev/null @@ -1,13 +0,0 @@ -# Automatically generated - DO NOT EDIT! - -"$schema" = "../../schemas/schema.json" - -[[permission]] -identifier = "allow-ask" -description = "Enables the ask command without any pre-configured scope." -commands.allow = ["ask"] - -[[permission]] -identifier = "deny-ask" -description = "Denies the ask command without any pre-configured scope." -commands.deny = ["ask"] diff --git a/plugins/dialog/permissions/autogenerated/commands/confirm.toml b/plugins/dialog/permissions/autogenerated/commands/confirm.toml deleted file mode 100644 index a297d075..00000000 --- a/plugins/dialog/permissions/autogenerated/commands/confirm.toml +++ /dev/null @@ -1,13 +0,0 @@ -# Automatically generated - DO NOT EDIT! - -"$schema" = "../../schemas/schema.json" - -[[permission]] -identifier = "allow-confirm" -description = "Enables the confirm command without any pre-configured scope." -commands.allow = ["confirm"] - -[[permission]] -identifier = "deny-confirm" -description = "Denies the confirm command without any pre-configured scope." -commands.deny = ["confirm"] diff --git a/plugins/dialog/permissions/autogenerated/reference.md b/plugins/dialog/permissions/autogenerated/reference.md index 3bbd265b..b49897dc 100644 --- a/plugins/dialog/permissions/autogenerated/reference.md +++ b/plugins/dialog/permissions/autogenerated/reference.md @@ -9,8 +9,6 @@ All dialog types are enabled. #### This default permission set includes the following: -- `allow-ask` -- `allow-confirm` - `allow-message` - `allow-save` - `allow-open` @@ -32,7 +30,7 @@ All dialog types are enabled. -Enables the ask command without any pre-configured scope. +Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3) @@ -45,33 +43,7 @@ Enables the ask command without any pre-configured scope. -Denies the ask command without any pre-configured scope. - - - - - - - -`dialog:allow-confirm` - - - - -Enables the confirm command without any pre-configured scope. - - - - - - - -`dialog:deny-confirm` - - - - -Denies the confirm command without any pre-configured scope. +Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3) @@ -151,6 +123,32 @@ Enables the save command without any pre-configured scope. Denies the save command without any pre-configured scope. + + + + + + +`dialog:allow-confirm` + + + + +Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3) + + + + + + + +`dialog:deny-confirm` + + + + +Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3) + diff --git a/plugins/dialog/permissions/confirm.toml b/plugins/dialog/permissions/confirm.toml new file mode 100644 index 00000000..b03a59b4 --- /dev/null +++ b/plugins/dialog/permissions/confirm.toml @@ -0,0 +1,11 @@ +"$schema" = "schemas/schema.json" + +[[permission]] +identifier = "allow-confirm" +description = "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)" +commands.allow = ["message"] + +[[permission]] +identifier = "deny-confirm" +description = "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)" +commands.deny = ["message"] diff --git a/plugins/dialog/permissions/default.toml b/plugins/dialog/permissions/default.toml index cc936d90..181e81d0 100644 --- a/plugins/dialog/permissions/default.toml +++ b/plugins/dialog/permissions/default.toml @@ -11,10 +11,4 @@ All dialog types are enabled. """ -permissions = [ - "allow-ask", - "allow-confirm", - "allow-message", - "allow-save", - "allow-open", -] +permissions = ["allow-message", "allow-save", "allow-open"] diff --git a/plugins/dialog/permissions/schemas/schema.json b/plugins/dialog/permissions/schemas/schema.json index b47417ec..75d98d0e 100644 --- a/plugins/dialog/permissions/schemas/schema.json +++ b/plugins/dialog/permissions/schemas/schema.json @@ -295,28 +295,16 @@ "type": "string", "oneOf": [ { - "description": "Enables the ask command without any pre-configured scope.", + "description": "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)", "type": "string", "const": "allow-ask", - "markdownDescription": "Enables the ask command without any pre-configured scope." + "markdownDescription": "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)" }, { - "description": "Denies the ask command without any pre-configured scope.", + "description": "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)", "type": "string", "const": "deny-ask", - "markdownDescription": "Denies the ask command without any pre-configured scope." - }, - { - "description": "Enables the confirm command without any pre-configured scope.", - "type": "string", - "const": "allow-confirm", - "markdownDescription": "Enables the confirm command without any pre-configured scope." - }, - { - "description": "Denies the confirm command without any pre-configured scope.", - "type": "string", - "const": "deny-confirm", - "markdownDescription": "Denies the confirm command without any pre-configured scope." + "markdownDescription": "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)" }, { "description": "Enables the message command without any pre-configured scope.", @@ -355,10 +343,22 @@ "markdownDescription": "Denies the save command without any pre-configured scope." }, { - "description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-ask`\n- `allow-confirm`\n- `allow-message`\n- `allow-save`\n- `allow-open`", + "description": "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)", + "type": "string", + "const": "allow-confirm", + "markdownDescription": "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)" + }, + { + "description": "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)", + "type": "string", + "const": "deny-confirm", + "markdownDescription": "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)" + }, + { + "description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-message`\n- `allow-save`\n- `allow-open`", "type": "string", "const": "default", - "markdownDescription": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-ask`\n- `allow-confirm`\n- `allow-message`\n- `allow-save`\n- `allow-open`" + "markdownDescription": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-message`\n- `allow-save`\n- `allow-open`" } ] } diff --git a/plugins/dialog/src/commands.rs b/plugins/dialog/src/commands.rs index f0286325..eb2932a4 100644 --- a/plugins/dialog/src/commands.rs +++ b/plugins/dialog/src/commands.rs @@ -10,8 +10,7 @@ use tauri_plugin_fs::FsExt; use crate::{ Dialog, FileAccessMode, FileDialogBuilder, FilePath, MessageDialogBuilder, - MessageDialogButtons, MessageDialogKind, MessageDialogResult, PickerMode, Result, CANCEL, NO, - OK, YES, + MessageDialogButtons, MessageDialogKind, MessageDialogResult, PickerMode, Result, }; #[derive(Serialize)] @@ -305,65 +304,3 @@ pub(crate) async fn message( Ok(message_dialog(window, dialog, title, message, kind, buttons).blocking_show_with_result()) } - -#[command] -pub(crate) async fn ask( - window: Window, - dialog: State<'_, Dialog>, - title: Option, - message: String, - kind: Option, - yes_button_label: Option, - no_button_label: Option, -) -> Result { - let dialog = message_dialog( - window, - dialog, - title, - message, - kind, - if let Some(yes_button_label) = yes_button_label { - MessageDialogButtons::OkCancelCustom( - yes_button_label, - no_button_label.unwrap_or(NO.to_string()), - ) - } else if let Some(no_button_label) = no_button_label { - MessageDialogButtons::OkCancelCustom(YES.to_string(), no_button_label) - } else { - MessageDialogButtons::YesNo - }, - ); - - Ok(dialog.blocking_show()) -} - -#[command] -pub(crate) async fn confirm( - window: Window, - dialog: State<'_, Dialog>, - title: Option, - message: String, - kind: Option, - ok_button_label: Option, - cancel_button_label: Option, -) -> Result { - let dialog = message_dialog( - window, - dialog, - title, - message, - kind, - if let Some(ok_button_label) = ok_button_label { - MessageDialogButtons::OkCancelCustom( - ok_button_label, - cancel_button_label.unwrap_or(CANCEL.to_string()), - ) - } else if let Some(cancel_button_label) = cancel_button_label { - MessageDialogButtons::OkCancelCustom(OK.to_string(), cancel_button_label) - } else { - MessageDialogButtons::OkCancel - }, - ); - - Ok(dialog.blocking_show()) -} diff --git a/plugins/dialog/src/lib.rs b/plugins/dialog/src/lib.rs index 29b818d3..7f8a9d57 100644 --- a/plugins/dialog/src/lib.rs +++ b/plugins/dialog/src/lib.rs @@ -61,8 +61,11 @@ pub enum FileAccessMode { } pub(crate) const OK: &str = "Ok"; +#[cfg(mobile)] pub(crate) const CANCEL: &str = "Cancel"; +#[cfg(mobile)] pub(crate) const YES: &str = "Yes"; +#[cfg(mobile)] pub(crate) const NO: &str = "No"; macro_rules! blocking_fn { @@ -197,8 +200,6 @@ pub fn init() -> TauriPlugin { commands::open, commands::save, commands::message, - commands::ask, - commands::confirm, ]) .setup(|app, api| { #[cfg(mobile)]