Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(dialog)!: use enum instead of label for buttons #1842

Merged
merged 6 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/native-dialog-button-text.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"dialog": patch:breaking
---

Changed `MessageDialogBuilder::ok_button_label` and `MessageDialogBuilder::cancel_button_label` to `MessageDialogBuilder::buttons` which takes an enum now
47 changes: 30 additions & 17 deletions plugins/dialog/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use serde::{Deserialize, Serialize};
use tauri::{command, Manager, Runtime, State, Window};
use tauri_plugin_fs::FsExt;

use crate::{Dialog, FileDialogBuilder, FilePath, MessageDialogKind, Result};
use crate::{
Dialog, FileDialogBuilder, FilePath, MessageDialogButtons, MessageDialogKind, Result, CANCEL,
OK,
};

#[derive(Serialize)]
#[serde(untagged)]
Expand Down Expand Up @@ -244,11 +247,12 @@ fn message_dialog<R: Runtime>(
title: Option<String>,
message: String,
kind: Option<MessageDialogKind>,
ok_button_label: Option<String>,
cancel_button_label: Option<String>,
buttons: MessageDialogButtons,
) -> bool {
let mut builder = dialog.message(message);

builder = builder.buttons(buttons);

if let Some(title) = title {
builder = builder.title(title);
}
Expand All @@ -262,14 +266,6 @@ fn message_dialog<R: Runtime>(
builder = builder.kind(kind);
}

if let Some(ok) = ok_button_label {
builder = builder.ok_button_label(ok);
}

if let Some(cancel) = cancel_button_label {
builder = builder.cancel_button_label(cancel);
}

builder.blocking_show()
}

Expand All @@ -288,8 +284,11 @@ pub(crate) async fn message<R: Runtime>(
title,
message,
kind,
ok_button_label,
None,
if let Some(ok_button_label) = ok_button_label {
MessageDialogButtons::OkCustom(ok_button_label)
} else {
MessageDialogButtons::Ok
},
))
}

Expand All @@ -309,8 +308,7 @@ pub(crate) async fn ask<R: Runtime>(
title,
message,
kind,
Some(ok_button_label.unwrap_or_else(|| "Yes".into())),
Some(cancel_button_label.unwrap_or_else(|| "No".into())),
get_ok_cancel_type(ok_button_label, cancel_button_label),
))
}

Expand All @@ -330,7 +328,22 @@ pub(crate) async fn confirm<R: Runtime>(
title,
message,
kind,
Some(ok_button_label.unwrap_or_else(|| "Ok".into())),
Some(cancel_button_label.unwrap_or_else(|| "Cancel".into())),
get_ok_cancel_type(ok_button_label, cancel_button_label),
))
}

fn get_ok_cancel_type(
ok_button_label: Option<String>,
cancel_button_label: Option<String>,
) -> MessageDialogButtons {
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
}
}
34 changes: 19 additions & 15 deletions plugins/dialog/src/desktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ use rfd::{AsyncFileDialog, AsyncMessageDialog};
use serde::de::DeserializeOwned;
use tauri::{plugin::PluginApi, AppHandle, Runtime};

use crate::{models::*, FileDialogBuilder, FilePath, MessageDialogBuilder};

const OK: &str = "Ok";
use crate::{models::*, FileDialogBuilder, FilePath, MessageDialogBuilder, OK};

pub fn init<R: Runtime, C: DeserializeOwned>(
app: &AppHandle<R>,
Expand Down Expand Up @@ -109,22 +107,24 @@ impl<R: Runtime> From<FileDialogBuilder<R>> for AsyncFileDialog {
}
}

impl From<MessageDialogButtons> for rfd::MessageButtons {
fn from(value: MessageDialogButtons) -> Self {
match value {
MessageDialogButtons::Ok => Self::Ok,
MessageDialogButtons::OkCancel => Self::OkCancel,
MessageDialogButtons::OkCustom(ok) => Self::OkCustom(ok),
MessageDialogButtons::OkCancelCustom(ok, cancel) => Self::OkCancelCustom(ok, cancel),
}
}
}

impl<R: Runtime> From<MessageDialogBuilder<R>> for AsyncMessageDialog {
fn from(d: MessageDialogBuilder<R>) -> Self {
let mut dialog = AsyncMessageDialog::new()
.set_title(&d.title)
.set_description(&d.message)
.set_level(d.kind.into());

let buttons = match (d.ok_button_label, d.cancel_button_label) {
(Some(ok), Some(cancel)) => Some(rfd::MessageButtons::OkCancelCustom(ok, cancel)),
(Some(ok), None) => Some(rfd::MessageButtons::OkCustom(ok)),
(None, Some(cancel)) => Some(rfd::MessageButtons::OkCancelCustom(OK.into(), cancel)),
(None, None) => None,
};
if let Some(buttons) = buttons {
dialog = dialog.set_buttons(buttons);
}
.set_level(d.kind.into())
.set_buttons(d.buttons.into());

if let Some(parent) = d.parent {
dialog = dialog.set_parent(&parent);
Expand Down Expand Up @@ -213,7 +213,11 @@ pub fn show_message_dialog<R: Runtime, F: FnOnce(bool) + Send + 'static>(
) {
use rfd::MessageDialogResult;

let ok_label = dialog.ok_button_label.clone();
let ok_label = match &dialog.buttons {
MessageDialogButtons::OkCustom(ok) => Some(ok.clone()),
MessageDialogButtons::OkCancelCustom(ok, _) => Some(ok.clone()),
_ => None,
};
let f = move |res| {
f(match res {
MessageDialogResult::Ok | MessageDialogResult::Yes => true,
Expand Down
51 changes: 26 additions & 25 deletions plugins/dialog/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ use desktop::*;
#[cfg(mobile)]
use mobile::*;

pub(crate) const OK: &str = "Ok";
pub(crate) const CANCEL: &str = "Cancel";

macro_rules! blocking_fn {
($self:ident, $fn:ident) => {{
let (tx, rx) = sync_channel(0);
Expand Down Expand Up @@ -89,14 +92,13 @@ impl<R: Runtime> Dialog<R> {
/// - Ask dialog:
///
/// ```
/// use tauri_plugin_dialog::DialogExt;
/// use tauri_plugin_dialog::{DialogExt, MessageDialogButtons};
///
/// tauri::Builder::default()
/// .setup(|app| {
/// app.dialog()
/// .message("Are you sure?")
/// .ok_button_label("Yes")
/// .cancel_button_label("No")
/// .buttons(MessageDialogButtons::OkCancelCustom("Yes", "No"))
/// .show(|yes| {
/// println!("user said {}", if yes { "yes" } else { "no" });
/// });
Expand All @@ -107,13 +109,13 @@ impl<R: Runtime> Dialog<R> {
/// - Message dialog with OK button:
///
/// ```
/// use tauri_plugin_dialog::DialogExt;
/// use tauri_plugin_dialog::{DialogExt, MessageDialogButtons};
///
/// tauri::Builder::default()
/// .setup(|app| {
/// app.dialog()
/// .message("Job completed successfully")
/// .ok_button_label("Ok")
/// .buttons(MessageDialogButtons::Ok)
/// .show(|_| {
/// println!("dialog closed");
/// });
Expand All @@ -129,16 +131,15 @@ impl<R: Runtime> Dialog<R> {
/// but note that it cannot be executed on the main thread as it will freeze your application.
///
/// ```
/// use tauri_plugin_dialog::DialogExt;
/// use tauri_plugin_dialog::{DialogExt, MessageDialogButtons};
///
/// tauri::Builder::default()
/// .setup(|app| {
/// let handle = app.handle().clone();
/// std::thread::spawn(move || {
/// let yes = handle.dialog()
/// .message("Are you sure?")
/// .ok_button_label("Yes")
/// .cancel_button_label("No")
/// .buttons(MessageDialogButtons::OkCancelCustom("Yes", "No"))
/// .blocking_show();
/// });
///
Expand Down Expand Up @@ -196,8 +197,7 @@ pub struct MessageDialogBuilder<R: Runtime> {
pub(crate) title: String,
pub(crate) message: String,
pub(crate) kind: MessageDialogKind,
pub(crate) ok_button_label: Option<String>,
pub(crate) cancel_button_label: Option<String>,
pub(crate) buttons: MessageDialogButtons,
#[cfg(desktop)]
pub(crate) parent: Option<crate::desktop::WindowHandle>,
}
Expand All @@ -210,8 +210,8 @@ pub(crate) struct MessageDialogPayload<'a> {
title: &'a String,
message: &'a String,
kind: &'a MessageDialogKind,
ok_button_label: &'a Option<String>,
cancel_button_label: &'a Option<String>,
ok_button_label: Option<&'a str>,
cancel_button_label: Option<&'a str>,
}

// raw window handle :(
Expand All @@ -225,21 +225,28 @@ impl<R: Runtime> MessageDialogBuilder<R> {
title: title.into(),
message: message.into(),
kind: Default::default(),
ok_button_label: None,
cancel_button_label: None,
buttons: Default::default(),
#[cfg(desktop)]
parent: None,
}
}

#[cfg(mobile)]
pub(crate) fn payload(&self) -> MessageDialogPayload<'_> {
let (ok_button_label, cancel_button_label) = match &self.buttons {
MessageDialogButtons::Ok => (Some(OK), None),
MessageDialogButtons::OkCancel => (Some(OK), Some(CANCEL)),
MessageDialogButtons::OkCustom(ok) => (Some(ok.as_str()), Some(CANCEL)),
MessageDialogButtons::OkCancelCustom(ok, cancel) => {
(Some(ok.as_str()), Some(cancel.as_str()))
}
};
MessageDialogPayload {
title: &self.title,
message: &self.message,
kind: &self.kind,
ok_button_label: &self.ok_button_label,
cancel_button_label: &self.cancel_button_label,
ok_button_label,
cancel_button_label,
}
}

Expand All @@ -266,15 +273,9 @@ impl<R: Runtime> MessageDialogBuilder<R> {
self
}

/// Sets the label for the OK button.
pub fn ok_button_label(mut self, label: impl Into<String>) -> Self {
self.ok_button_label.replace(label.into());
self
}

/// Sets the label for the Cancel button.
pub fn cancel_button_label(mut self, label: impl Into<String>) -> Self {
self.cancel_button_label.replace(label.into());
/// Sets the dialog buttons.
pub fn buttons(mut self, buttons: MessageDialogButtons) -> Self {
self.buttons = buttons;
self
}

Expand Down
15 changes: 15 additions & 0 deletions plugins/dialog/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,18 @@ impl Serialize for MessageDialogKind {
}
}
}

/// Set of button that will be displayed on the dialog
#[non_exhaustive]
#[derive(Debug, Default, Clone)]
pub enum MessageDialogButtons {
#[default]
/// A single `Ok` button with OS default dialog text
Ok,
/// 2 buttons `Ok` and `Cancel` with OS default dialog texts
OkCancel,
/// A single `Ok` button with custom text
OkCustom(String),
/// 2 buttons `Ok` and `Cancel` with custom texts
OkCancelCustom(String, String),
}
Loading