'use strict'; var core = require('@tauri-apps/api/core'); // Copyright 2019-2023 Tauri Programme within The Commons Conservancy // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT /** * Internal function to convert the buttons to the Rust type. */ function buttonsToRust(buttons) { if (buttons === undefined) { return undefined; } if (typeof buttons === 'string') { return buttons; } else if ('ok' in buttons && 'cancel' in buttons) { return { OkCancelCustom: [buttons.ok, buttons.cancel] }; } else if ('yes' in buttons && 'no' in buttons && 'cancel' in buttons) { return { YesNoCancelCustom: [buttons.yes, buttons.no, buttons.cancel] }; } else if ('ok' in buttons) { return { OkCustom: buttons.ok }; } return undefined; } /** * Open a file/directory selection dialog. * * The selected paths are added to the filesystem and asset protocol scopes. * When security is more important than the easy of use of this API, * prefer writing a dedicated command instead. * * Note that the scope change is not persisted, so the values are cleared when the application is restarted. * You can save it to the filesystem using [tauri-plugin-persisted-scope](https://github.com/tauri-apps/tauri-plugin-persisted-scope). * @example * ```typescript * import { open } from '@tauri-apps/plugin-dialog'; * // Open a selection dialog for image files * const selected = await open({ * multiple: true, * filters: [{ * name: 'Image', * extensions: ['png', 'jpeg'] * }] * }); * if (Array.isArray(selected)) { * // user selected multiple files * } else if (selected === null) { * // user cancelled the selection * } else { * // user selected a single file * } * ``` * * @example * ```typescript * import { open } from '@tauri-apps/plugin-dialog'; * import { appDir } from '@tauri-apps/api/path'; * // Open a selection dialog for directories * const selected = await open({ * directory: true, * multiple: true, * defaultPath: await appDir(), * }); * if (Array.isArray(selected)) { * // user selected multiple directories * } else if (selected === null) { * // user cancelled the selection * } else { * // user selected a single directory * } * ``` * * @returns A promise resolving to the selected path(s) * * @since 2.0.0 */ async function open(options = {}) { if (typeof options === 'object') { Object.freeze(options); } return await core.invoke('plugin:dialog|open', { options }); } /** * Open a file/directory save dialog. * * The selected path is added to the filesystem and asset protocol scopes. * When security is more important than the easy of use of this API, * prefer writing a dedicated command instead. * * Note that the scope change is not persisted, so the values are cleared when the application is restarted. * You can save it to the filesystem using [tauri-plugin-persisted-scope](https://github.com/tauri-apps/tauri-plugin-persisted-scope). * @example * ```typescript * import { save } from '@tauri-apps/plugin-dialog'; * const filePath = await save({ * filters: [{ * name: 'Image', * extensions: ['png', 'jpeg'] * }] * }); * ``` * * @returns A promise resolving to the selected path. * * @since 2.0.0 */ async function save(options = {}) { if (typeof options === 'object') { Object.freeze(options); } return await core.invoke('plugin:dialog|save', { options }); } async function messageCommand(message, options) { return await core.invoke('plugin:dialog|message', { message, title: options?.title, kind: options?.kind, buttons: buttonsToRust(options?.buttons) }); } /** * Shows a message dialog with an `Ok` button. * @example * ```typescript * import { message } from '@tauri-apps/plugin-dialog'; * await message('Tauri is awesome', 'Tauri'); * await message('File not found', { title: 'Tauri', kind: 'error' }); * ``` * * @param message The message to show. * @param options The dialog's options. If a string, it represents the dialog title. * * @returns A promise indicating the success or failure of the operation. * * @since 2.0.0 * */ async function message(message, options) { const opts = typeof options === 'string' ? { title: options } : options; if (opts && !opts.buttons && opts.okLabel) { opts.buttons = { ok: opts.okLabel }; } 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'; * const yes = await ask('Are you sure?', 'Tauri'); * const yes2 = await ask('This action cannot be reverted. Are you sure?', { title: 'Tauri', kind: 'warning' }); * ``` * * @param message The message to show. * @param options The dialog's options. If a string, it represents the dialog title. * * @returns A promise resolving to a boolean indicating whether `Yes` was clicked or not. * * @since 2.0.0 */ async function ask(message, options) { const opts = typeof options === 'string' ? { title: options } : options; 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'; * const confirmed = await confirm('Are you sure?', 'Tauri'); * const confirmed2 = await confirm('This action cannot be reverted. Are you sure?', { title: 'Tauri', kind: 'warning' }); * ``` * * @param message The message to show. * @param options The dialog's options. If a string, it represents the dialog title. * * @returns A promise resolving to a boolean indicating whether `Ok` was clicked or not. * * @since 2.0.0 */ async function confirm(message, options) { const opts = typeof options === 'string' ? { title: options } : options; 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); } exports.ask = ask; exports.confirm = confirm; exports.message = message; exports.open = open; exports.save = save;