mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-09-11 07:55:34 +03:00
feat: customize button texts of message dialog (#4383)
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
parent
7a8d570db7
commit
00e1efaa9b
2
.cargo/config
Normal file
2
.cargo/config
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[env]
|
||||||
|
__TAURI_WORKSPACE__ = "true"
|
5
.changes/custom-buttons-api.md
Normal file
5
.changes/custom-buttons-api.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"api": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Allow setting the text of the dialog buttons.
|
5
.changes/custom-buttons.md
Normal file
5
.changes/custom-buttons.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"tauri": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Added `OkWithLabel` and `OkCancelWithLabels` variants to the `api::dialog::MessageDialogButtons` enum to set the text of the dialog buttons.
|
@ -87,7 +87,7 @@ ico = { version = "0.2.0", optional = true }
|
|||||||
encoding_rs = "0.8.31"
|
encoding_rs = "0.8.31"
|
||||||
|
|
||||||
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
||||||
rfd = { version = "0.10", optional = true }
|
rfd = { version = "0.10", optional = true, features=["gtk3", "common-controls-v6"] }
|
||||||
notify-rust = { version = "4.5", default-features = false, features = [ "d" ], optional = true }
|
notify-rust = { version = "4.5", default-features = false, features = [ "d" ], optional = true }
|
||||||
|
|
||||||
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
||||||
|
14
core/tauri/Windows Manifest.xml
Normal file
14
core/tauri/Windows Manifest.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||||
|
<dependency>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity
|
||||||
|
type="win32"
|
||||||
|
name="Microsoft.Windows.Common-Controls"
|
||||||
|
version="6.0.0.0"
|
||||||
|
processorArchitecture="*"
|
||||||
|
publicKeyToken="6595b64144ccf1df"
|
||||||
|
language="*"
|
||||||
|
/>
|
||||||
|
</dependentAssembly>
|
||||||
|
</dependency>
|
||||||
|
</assembly>
|
@ -141,6 +141,18 @@ fn main() {
|
|||||||
CHECKED_FEATURES.get().unwrap().lock().unwrap().join(","),
|
CHECKED_FEATURES.get().unwrap().lock().unwrap().join(","),
|
||||||
)
|
)
|
||||||
.expect("failed to write checked_features file");
|
.expect("failed to write checked_features file");
|
||||||
|
|
||||||
|
// workaround needed to preven `STATUS_ENTRYPOINT_NOT_FOUND` error
|
||||||
|
// see https://github.com/tauri-apps/tauri/pull/4383#issuecomment-1212221864
|
||||||
|
let target_os = std::env::var("CARGO_CFG_TARGET_OS");
|
||||||
|
let target_env = std::env::var("CARGO_CFG_TARGET_ENV");
|
||||||
|
let is_tauri_workspace = std::env::var("__TAURI_WORKSPACE__").map_or(false, |v| v == "true");
|
||||||
|
if is_tauri_workspace
|
||||||
|
&& Ok("windows") == target_os.as_deref()
|
||||||
|
&& Ok("msvc") == target_env.as_deref()
|
||||||
|
{
|
||||||
|
add_manifest();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create aliases for the given module with its apis.
|
// create aliases for the given module with its apis.
|
||||||
@ -170,3 +182,20 @@ fn alias_module(module: &str, apis: &[&str], api_all: bool) {
|
|||||||
|
|
||||||
alias(&format!("{}_any", AsSnakeCase(module)), any);
|
alias(&format!("{}_any", AsSnakeCase(module)), any);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_manifest() {
|
||||||
|
static WINDOWS_MANIFEST_FILE: &str = "Windows Manifest.xml";
|
||||||
|
|
||||||
|
let mut manifest = std::env::current_dir().unwrap();
|
||||||
|
manifest.push(WINDOWS_MANIFEST_FILE);
|
||||||
|
|
||||||
|
println!("cargo:rerun-if-changed={}", WINDOWS_MANIFEST_FILE);
|
||||||
|
// Embed the Windows application manifest file.
|
||||||
|
println!("cargo:rustc-link-arg=/MANIFEST:EMBED");
|
||||||
|
println!(
|
||||||
|
"cargo:rustc-link-arg=/MANIFESTINPUT:{}",
|
||||||
|
manifest.to_str().unwrap()
|
||||||
|
);
|
||||||
|
// Turn linker warnings into errors.
|
||||||
|
println!("cargo:rustc-link-arg=/WX");
|
||||||
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
1
core/tauri/scripts/bundle.js
Normal file
1
core/tauri/scripts/bundle.js
Normal file
File diff suppressed because one or more lines are too long
@ -171,7 +171,7 @@ macro_rules! message_dialog_builder {
|
|||||||
|
|
||||||
/// Options for action buttons on message dialogs.
|
/// Options for action buttons on message dialogs.
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum MessageDialogButtons {
|
pub enum MessageDialogButtons {
|
||||||
/// Ok button.
|
/// Ok button.
|
||||||
Ok,
|
Ok,
|
||||||
@ -179,6 +179,10 @@ pub enum MessageDialogButtons {
|
|||||||
OkCancel,
|
OkCancel,
|
||||||
/// Yes and No buttons.
|
/// Yes and No buttons.
|
||||||
YesNo,
|
YesNo,
|
||||||
|
/// OK button with customized text.
|
||||||
|
OkWithLabel(String),
|
||||||
|
/// Ok and Cancel buttons with customized text.
|
||||||
|
OkCancelWithLabels(String, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MessageDialogButtons> for rfd::MessageButtons {
|
impl From<MessageDialogButtons> for rfd::MessageButtons {
|
||||||
@ -187,6 +191,10 @@ impl From<MessageDialogButtons> for rfd::MessageButtons {
|
|||||||
MessageDialogButtons::Ok => Self::Ok,
|
MessageDialogButtons::Ok => Self::Ok,
|
||||||
MessageDialogButtons::OkCancel => Self::OkCancel,
|
MessageDialogButtons::OkCancel => Self::OkCancel,
|
||||||
MessageDialogButtons::YesNo => Self::YesNo,
|
MessageDialogButtons::YesNo => Self::YesNo,
|
||||||
|
MessageDialogButtons::OkWithLabel(ok_text) => Self::OkCustom(ok_text),
|
||||||
|
MessageDialogButtons::OkCancelWithLabels(ok_text, cancel_text) => {
|
||||||
|
Self::OkCancelCustom(ok_text, cancel_text)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,19 +14,21 @@ use tauri_macros::{command_enum, module_command_handler, CommandModule};
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
macro_rules! message_dialog {
|
macro_rules! message_dialog {
|
||||||
($fn_name: ident, $allowlist: ident, $buttons: expr) => {
|
($fn_name: ident, $allowlist: ident, $button_labels_type: ty, $buttons: expr) => {
|
||||||
#[module_command_handler($allowlist)]
|
#[module_command_handler($allowlist)]
|
||||||
fn $fn_name<R: Runtime>(
|
fn $fn_name<R: Runtime>(
|
||||||
context: InvokeContext<R>,
|
context: InvokeContext<R>,
|
||||||
title: Option<String>,
|
title: Option<String>,
|
||||||
message: String,
|
message: String,
|
||||||
level: Option<MessageDialogType>,
|
level: Option<MessageDialogType>,
|
||||||
|
button_labels: $button_labels_type,
|
||||||
) -> super::Result<bool> {
|
) -> super::Result<bool> {
|
||||||
|
let determine_button = $buttons;
|
||||||
let mut builder = crate::api::dialog::blocking::MessageDialogBuilder::new(
|
let mut builder = crate::api::dialog::blocking::MessageDialogBuilder::new(
|
||||||
title.unwrap_or_else(|| context.window.app_handle.package_info().name.clone()),
|
title.unwrap_or_else(|| context.window.app_handle.package_info().name.clone()),
|
||||||
message,
|
message,
|
||||||
)
|
)
|
||||||
.buttons($buttons);
|
.buttons(determine_button(button_labels));
|
||||||
#[cfg(any(windows, target_os = "macos"))]
|
#[cfg(any(windows, target_os = "macos"))]
|
||||||
{
|
{
|
||||||
builder = builder.parent(&context.window);
|
builder = builder.parent(&context.window);
|
||||||
@ -139,6 +141,8 @@ pub enum Cmd {
|
|||||||
message: String,
|
message: String,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
level: Option<MessageDialogType>,
|
level: Option<MessageDialogType>,
|
||||||
|
#[serde(rename = "buttonLabel")]
|
||||||
|
button_label: Option<String>,
|
||||||
},
|
},
|
||||||
#[cmd(dialog_ask, "dialog > ask")]
|
#[cmd(dialog_ask, "dialog > ask")]
|
||||||
AskDialog {
|
AskDialog {
|
||||||
@ -146,6 +150,8 @@ pub enum Cmd {
|
|||||||
message: String,
|
message: String,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
level: Option<MessageDialogType>,
|
level: Option<MessageDialogType>,
|
||||||
|
#[serde(rename = "buttonLabels")]
|
||||||
|
button_label: Option<(String, String)>,
|
||||||
},
|
},
|
||||||
#[cmd(dialog_confirm, "dialog > confirm")]
|
#[cmd(dialog_confirm, "dialog > confirm")]
|
||||||
ConfirmDialog {
|
ConfirmDialog {
|
||||||
@ -153,6 +159,8 @@ pub enum Cmd {
|
|||||||
message: String,
|
message: String,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
level: Option<MessageDialogType>,
|
level: Option<MessageDialogType>,
|
||||||
|
#[serde(rename = "buttonLabels")]
|
||||||
|
button_labels: Option<(String, String)>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,19 +263,36 @@ impl Cmd {
|
|||||||
message_dialog!(
|
message_dialog!(
|
||||||
message_dialog,
|
message_dialog,
|
||||||
dialog_message,
|
dialog_message,
|
||||||
crate::api::dialog::MessageDialogButtons::Ok
|
Option<String>,
|
||||||
|
|label: Option<String>| {
|
||||||
|
label
|
||||||
|
.map(crate::api::dialog::MessageDialogButtons::OkWithLabel)
|
||||||
|
.unwrap_or(crate::api::dialog::MessageDialogButtons::Ok)
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
message_dialog!(
|
message_dialog!(
|
||||||
ask_dialog,
|
ask_dialog,
|
||||||
dialog_ask,
|
dialog_ask,
|
||||||
crate::api::dialog::MessageDialogButtons::YesNo
|
Option<(String, String)>,
|
||||||
|
|labels: Option<(String, String)>| {
|
||||||
|
labels
|
||||||
|
.map(|(yes, no)| crate::api::dialog::MessageDialogButtons::OkCancelWithLabels(yes, no))
|
||||||
|
.unwrap_or(crate::api::dialog::MessageDialogButtons::YesNo)
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
message_dialog!(
|
message_dialog!(
|
||||||
confirm_dialog,
|
confirm_dialog,
|
||||||
dialog_confirm,
|
dialog_confirm,
|
||||||
crate::api::dialog::MessageDialogButtons::OkCancel
|
Option<(String, String)>,
|
||||||
|
|labels: Option<(String, String)>| {
|
||||||
|
labels
|
||||||
|
.map(|(ok, cancel)| {
|
||||||
|
crate::api::dialog::MessageDialogButtons::OkCancelWithLabels(ok, cancel)
|
||||||
|
})
|
||||||
|
.unwrap_or(crate::api::dialog::MessageDialogButtons::OkCancel)
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
32
examples/api/dist/assets/index.js
vendored
32
examples/api/dist/assets/index.js
vendored
File diff suppressed because one or more lines are too long
@ -1,7 +1,11 @@
|
|||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use tauri::{
|
use tauri::{
|
||||||
api::dialog::ask, CustomMenuItem, GlobalShortcutManager, Manager, RunEvent, SystemTray,
|
api::{
|
||||||
SystemTrayEvent, SystemTrayMenu, WindowBuilder, WindowEvent, WindowUrl,
|
dialog::{ask, MessageDialogBuilder, MessageDialogButtons},
|
||||||
|
shell,
|
||||||
|
},
|
||||||
|
CustomMenuItem, GlobalShortcutManager, Manager, RunEvent, SystemTray, SystemTrayEvent,
|
||||||
|
SystemTrayMenu, WindowBuilder, WindowEvent, WindowUrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
@ -71,6 +75,7 @@ fn create_tray(app: &tauri::App) -> tauri::Result<()> {
|
|||||||
|
|
||||||
tray_menu1 = tray_menu1
|
tray_menu1 = tray_menu1
|
||||||
.add_item(CustomMenuItem::new("switch_menu", "Switch Menu"))
|
.add_item(CustomMenuItem::new("switch_menu", "Switch Menu"))
|
||||||
|
.add_item(CustomMenuItem::new("about", "About"))
|
||||||
.add_item(CustomMenuItem::new("exit_app", "Quit"))
|
.add_item(CustomMenuItem::new("exit_app", "Quit"))
|
||||||
.add_item(CustomMenuItem::new("destroy", "Destroy"));
|
.add_item(CustomMenuItem::new("destroy", "Destroy"));
|
||||||
|
|
||||||
@ -78,6 +83,7 @@ fn create_tray(app: &tauri::App) -> tauri::Result<()> {
|
|||||||
.add_item(CustomMenuItem::new("toggle", "Toggle"))
|
.add_item(CustomMenuItem::new("toggle", "Toggle"))
|
||||||
.add_item(CustomMenuItem::new("new", "New window"))
|
.add_item(CustomMenuItem::new("new", "New window"))
|
||||||
.add_item(CustomMenuItem::new("switch_menu", "Switch Menu"))
|
.add_item(CustomMenuItem::new("switch_menu", "Switch Menu"))
|
||||||
|
.add_item(CustomMenuItem::new("about", "About"))
|
||||||
.add_item(CustomMenuItem::new("exit_app", "Quit"))
|
.add_item(CustomMenuItem::new("exit_app", "Quit"))
|
||||||
.add_item(CustomMenuItem::new("destroy", "Destroy"));
|
.add_item(CustomMenuItem::new("destroy", "Destroy"));
|
||||||
let is_menu1 = AtomicBool::new(true);
|
let is_menu1 = AtomicBool::new(true);
|
||||||
@ -161,6 +167,20 @@ fn create_tray(app: &tauri::App) -> tauri::Result<()> {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
is_menu1.store(!flag, Ordering::Relaxed);
|
is_menu1.store(!flag, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
"about" => {
|
||||||
|
let window = handle.get_window("main").unwrap();
|
||||||
|
MessageDialogBuilder::new("About app", "Tauri demo app")
|
||||||
|
.parent(&window)
|
||||||
|
.buttons(MessageDialogButtons::OkCancelCustom(
|
||||||
|
"Homepage".into(),
|
||||||
|
"know it".into(),
|
||||||
|
))
|
||||||
|
.show(move |ok| {
|
||||||
|
if ok {
|
||||||
|
shell::open(&window.shell_scope(), "https://tauri.app/", None).unwrap();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,19 @@ interface MessageDialogOptions {
|
|||||||
title?: string
|
title?: string
|
||||||
/** The type of the dialog. Defaults to `info`. */
|
/** The type of the dialog. Defaults to `info`. */
|
||||||
type?: 'info' | 'warning' | 'error'
|
type?: 'info' | 'warning' | 'error'
|
||||||
|
/** The label of the confirm button. */
|
||||||
|
okLabel?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ConfirmDialogOptions {
|
||||||
|
/** The title of the dialog. Defaults to the app name. */
|
||||||
|
title?: string
|
||||||
|
/** The type of the dialog. Defaults to `info`. */
|
||||||
|
type?: 'info' | 'warning' | 'error'
|
||||||
|
/** The label of the confirm button. */
|
||||||
|
okLabel?: string
|
||||||
|
/** The label of the cancel button. */
|
||||||
|
cancelLabel?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -233,7 +246,8 @@ async function message(
|
|||||||
cmd: 'messageDialog',
|
cmd: 'messageDialog',
|
||||||
message: message.toString(),
|
message: message.toString(),
|
||||||
title: opts?.title?.toString(),
|
title: opts?.title?.toString(),
|
||||||
type: opts?.type
|
type: opts?.type,
|
||||||
|
buttonLabel: opts?.okLabel?.toString()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -256,7 +270,7 @@ async function message(
|
|||||||
*/
|
*/
|
||||||
async function ask(
|
async function ask(
|
||||||
message: string,
|
message: string,
|
||||||
options?: string | MessageDialogOptions
|
options?: string | ConfirmDialogOptions
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const opts = typeof options === 'string' ? { title: options } : options
|
const opts = typeof options === 'string' ? { title: options } : options
|
||||||
return invokeTauriCommand({
|
return invokeTauriCommand({
|
||||||
@ -265,7 +279,11 @@ async function ask(
|
|||||||
cmd: 'askDialog',
|
cmd: 'askDialog',
|
||||||
message: message.toString(),
|
message: message.toString(),
|
||||||
title: opts?.title?.toString(),
|
title: opts?.title?.toString(),
|
||||||
type: opts?.type
|
type: opts?.type,
|
||||||
|
buttonLabels: [
|
||||||
|
opts?.okLabel?.toString() ?? 'Yes',
|
||||||
|
opts?.cancelLabel?.toString() ?? 'No'
|
||||||
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -288,7 +306,7 @@ async function ask(
|
|||||||
*/
|
*/
|
||||||
async function confirm(
|
async function confirm(
|
||||||
message: string,
|
message: string,
|
||||||
options?: string | MessageDialogOptions
|
options?: string | ConfirmDialogOptions
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const opts = typeof options === 'string' ? { title: options } : options
|
const opts = typeof options === 'string' ? { title: options } : options
|
||||||
return invokeTauriCommand({
|
return invokeTauriCommand({
|
||||||
@ -297,7 +315,11 @@ async function confirm(
|
|||||||
cmd: 'confirmDialog',
|
cmd: 'confirmDialog',
|
||||||
message: message.toString(),
|
message: message.toString(),
|
||||||
title: opts?.title?.toString(),
|
title: opts?.title?.toString(),
|
||||||
type: opts?.type
|
type: opts?.type,
|
||||||
|
buttonLabels: [
|
||||||
|
opts?.okLabel?.toString() ?? 'Ok',
|
||||||
|
opts?.cancelLabel?.toString() ?? 'Cancel'
|
||||||
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -306,7 +328,8 @@ export type {
|
|||||||
DialogFilter,
|
DialogFilter,
|
||||||
OpenDialogOptions,
|
OpenDialogOptions,
|
||||||
SaveDialogOptions,
|
SaveDialogOptions,
|
||||||
MessageDialogOptions
|
MessageDialogOptions,
|
||||||
|
ConfirmDialogOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
export { open, save, message, ask, confirm }
|
export { open, save, message, ask, confirm }
|
||||||
|
Loading…
Reference in New Issue
Block a user