198 lines
6.2 KiB
JavaScript
198 lines
6.2 KiB
JavaScript
|
|
import { invoke } from '@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 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 invoke('plugin:dialog|save', { options });
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* 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;
|
||
|
|
return invoke('plugin:dialog|message', {
|
||
|
|
message: message.toString(),
|
||
|
|
title: opts?.title?.toString(),
|
||
|
|
kind: opts?.kind,
|
||
|
|
okButtonLabel: opts?.okLabel?.toString(),
|
||
|
|
buttons: buttonsToRust(opts?.buttons)
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Shows a question dialog with `Yes` and `No` buttons.
|
||
|
|
* @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;
|
||
|
|
return await invoke('plugin:dialog|ask', {
|
||
|
|
message: message.toString(),
|
||
|
|
title: opts?.title?.toString(),
|
||
|
|
kind: opts?.kind,
|
||
|
|
yesButtonLabel: opts?.okLabel?.toString(),
|
||
|
|
noButtonLabel: opts?.cancelLabel?.toString()
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Shows a question dialog with `Ok` and `Cancel` buttons.
|
||
|
|
* @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;
|
||
|
|
return await invoke('plugin:dialog|confirm', {
|
||
|
|
message: message.toString(),
|
||
|
|
title: opts?.title?.toString(),
|
||
|
|
kind: opts?.kind,
|
||
|
|
okButtonLabel: opts?.okLabel?.toString(),
|
||
|
|
cancelButtonLabel: opts?.cancelLabel?.toString()
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export { ask, confirm, message, open, save };
|