Skip to content

Commit 3ca0dae

Browse files
committed
feat: support message dialogs with 3 buttons
1 parent c5b0f51 commit 3ca0dae

File tree

10 files changed

+319
-88
lines changed

10 files changed

+319
-88
lines changed

examples/api/src/views/Dialog.svelte

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@
4444
await message("Tauri is awesome!");
4545
}
4646
47+
async function msgCustom(result) {
48+
const buttons = { yes: "awesome", no: "amazing", cancel: "stunning" };
49+
await message(`Tauri is: `, { buttons })
50+
.then((res) => onMessage(`Tauri is ${res}`))
51+
.catch(onMessage);
52+
}
53+
4754
function openDialog() {
4855
open({
4956
title: "My wonderful open dialog",
@@ -136,12 +143,17 @@
136143
<label for="dialog-directory">Directory</label>
137144
</div>
138145
<br />
139-
<button class="btn" id="open-dialog" on:click={openDialog}>Open dialog</button>
140-
<button class="btn" id="save-dialog" on:click={saveDialog}
141-
>Open save dialog</button
142-
>
143-
<button class="btn" id="prompt-dialog" on:click={prompt}>Prompt</button>
144-
<button class="btn" id="custom-prompt-dialog" on:click={promptCustom}
145-
>Prompt (custom)</button
146-
>
147-
<button class="btn" id="message-dialog" on:click={msg}>Message</button>
146+
147+
<div class="flex flex-wrap flex-col md:flex-row gap-2 children:flex-shrink-0">
148+
<button class="btn" id="open-dialog" on:click={openDialog}>Open dialog</button>
149+
<button class="btn" id="save-dialog" on:click={saveDialog}
150+
>Open save dialog</button
151+
>
152+
<button class="btn" id="prompt-dialog" on:click={prompt}>Prompt</button>
153+
<button class="btn" id="custom-prompt-dialog" on:click={promptCustom}
154+
>Prompt (custom)</button
155+
>
156+
<button class="btn" id="message-dialog" on:click={msg}>Message</button>
157+
<button class="btn" id="message-dialog" on:click={msgCustom}>Message (custom)</button>
158+
159+
</div>

plugins/dialog/android/src/main/java/DialogPlugin.kt

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class MessageOptions {
3838
var title: String? = null
3939
lateinit var message: String
4040
var okButtonLabel: String? = null
41+
var noButtonLabel: String? = null
4142
var cancelButtonLabel: String? = null
4243
}
4344

@@ -169,9 +170,8 @@ class DialogPlugin(private val activity: Activity): Plugin(activity) {
169170
return
170171
}
171172

172-
val handler = { cancelled: Boolean, value: Boolean ->
173+
val handler = { value: String ->
173174
val ret = JSObject()
174-
ret.put("cancelled", cancelled)
175175
ret.put("value", value)
176176
invoke.resolve(ret)
177177
}
@@ -183,24 +183,34 @@ class DialogPlugin(private val activity: Activity): Plugin(activity) {
183183
if (args.title != null) {
184184
builder.setTitle(args.title)
185185
}
186+
187+
val okButtonLabel = args.okButtonLabel ?: "Ok"
188+
186189
builder
187190
.setMessage(args.message)
188-
.setPositiveButton(
189-
args.okButtonLabel ?: "OK"
190-
) { dialog, _ ->
191+
.setPositiveButton(okButtonLabel) { dialog, _ ->
191192
dialog.dismiss()
192-
handler(false, true)
193+
handler(okButtonLabel)
193194
}
194195
.setOnCancelListener { dialog ->
195196
dialog.dismiss()
196-
handler(true, false)
197+
handler(args.cancelButtonLabel ?: "Cancel")
198+
}
199+
200+
if (args.noButtonLabel != null) {
201+
builder.setNeutralButton(args.noButtonLabel) { dialog, _ ->
202+
dialog.dismiss()
203+
handler(args.noButtonLabel!!)
197204
}
205+
}
206+
198207
if (args.cancelButtonLabel != null) {
199208
builder.setNegativeButton( args.cancelButtonLabel) { dialog, _ ->
200209
dialog.dismiss()
201-
handler(false, false)
210+
handler(args.cancelButtonLabel!!)
202211
}
203212
}
213+
204214
val dialog = builder.create()
205215
dialog.show()
206216
}

plugins/dialog/api-iife.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/dialog/guest-js/index.ts

Lines changed: 129 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,68 @@ interface SaveDialogOptions {
7777
canCreateDirectories?: boolean
7878
}
7979

80+
/**
81+
* Default buttons for a message dialog.
82+
*
83+
* @since 2.3.0
84+
*/
85+
export type MessageDialogDefaultButtons = 'Ok' | 'OkCancel' | 'YesNo'
86+
87+
/**
88+
* The Yes, No and Cancel buttons of a message dialog.
89+
*
90+
* @since 2.3.0
91+
*/
92+
export type MessageDialogButtonsYesNoCancel = {
93+
/** The Yes button. */
94+
yes?: string
95+
/** The No button. */
96+
no?: string
97+
/** The Cancel button. */
98+
cancel?: string
99+
}
100+
101+
/**
102+
* The Ok and Cancel buttons of a message dialog.
103+
*
104+
* @since 2.3.0
105+
*/
106+
export type MessageDialogButtonsOkCancel = {
107+
/** The Ok button. */
108+
ok?: string
109+
/** The Cancel button. */
110+
cancel?: string
111+
}
112+
113+
/**
114+
* The Ok button of a message dialog.
115+
*
116+
* @since 2.3.0
117+
*/
118+
export type MessageDialogButtonsOk = {
119+
/** The Ok button. */
120+
ok?: string
121+
}
122+
123+
/**
124+
* Custom buttons for a message dialog.
125+
*
126+
* @since 2.3.0
127+
*/
128+
export type MessageDialogCustomButtons =
129+
| MessageDialogButtonsYesNoCancel
130+
| MessageDialogButtonsOkCancel
131+
| MessageDialogButtonsOk
132+
133+
/**
134+
* The buttons of a message dialog.
135+
*
136+
* @since 2.3.0
137+
*/
138+
export type MessageDialogButtons =
139+
| MessageDialogDefaultButtons
140+
| MessageDialogCustomButtons
141+
80142
/**
81143
* @since 2.0.0
82144
*/
@@ -85,8 +147,41 @@ interface MessageDialogOptions {
85147
title?: string
86148
/** The kind of the dialog. Defaults to `info`. */
87149
kind?: 'info' | 'warning' | 'error'
88-
/** The label of the confirm button. */
150+
/**
151+
* The label of the Ok button.
152+
*
153+
* @deprecated Use {@linkcode MessageDialogOptions.buttons} instead.
154+
*/
89155
okLabel?: string
156+
/**
157+
* The buttons of the dialog.
158+
*
159+
* @since 2.3.0
160+
*/
161+
buttons?: MessageDialogButtons
162+
}
163+
164+
/**
165+
* Internal function to convert the buttons to the Rust type.
166+
*/
167+
function buttonsToRust(buttons: MessageDialogButtons | undefined) {
168+
if (buttons === undefined) {
169+
return undefined
170+
}
171+
172+
if (typeof buttons === 'string') {
173+
return buttons
174+
} else if ('ok' in buttons && 'cancel' in buttons) {
175+
return { OkCancelCustom: [buttons.ok, buttons.cancel] }
176+
} else if ('yes' in buttons && 'no' in buttons && 'cancel' in buttons) {
177+
return {
178+
YesNoCancelCustom: [buttons.yes, buttons.no, buttons.cancel]
179+
}
180+
} else if ('ok' in buttons) {
181+
return { OkCustom: buttons.ok }
182+
}
183+
184+
return undefined
90185
}
91186

92187
interface ConfirmDialogOptions {
@@ -202,6 +297,32 @@ async function save(options: SaveDialogOptions = {}): Promise<string | null> {
202297
return await invoke('plugin:dialog|save', { options })
203298
}
204299

300+
/**
301+
* The result of a message dialog.
302+
*
303+
* The result is a string if the dialog has custom buttons,
304+
* otherwise it is one of the default buttons.
305+
*
306+
* @since 2.3.0
307+
*/
308+
export type MessageDialogResult = 'Yes' | 'No' | 'Ok' | 'Cancel' | (string & {})
309+
310+
type MessageDialogResultRust =
311+
| 'Yes'
312+
| 'No'
313+
| 'Ok'
314+
| 'Cancel'
315+
| { Custom: string }
316+
317+
/** Internal function to convert the result to JS. */
318+
function resultToJS(res: MessageDialogResultRust): MessageDialogResult {
319+
if (typeof res === 'string') {
320+
return res
321+
} else {
322+
return res.Custom
323+
}
324+
}
325+
205326
/**
206327
* Shows a message dialog with an `Ok` button.
207328
* @example
@@ -222,14 +343,18 @@ async function save(options: SaveDialogOptions = {}): Promise<string | null> {
222343
async function message(
223344
message: string,
224345
options?: string | MessageDialogOptions
225-
): Promise<void> {
346+
): Promise<MessageDialogResult> {
226347
const opts = typeof options === 'string' ? { title: options } : options
227-
await invoke('plugin:dialog|message', {
348+
349+
const res = await invoke<MessageDialogResultRust>('plugin:dialog|message', {
228350
message: message.toString(),
229351
title: opts?.title?.toString(),
230352
kind: opts?.kind,
231-
okButtonLabel: opts?.okLabel?.toString()
353+
okButtonLabel: opts?.okLabel?.toString(),
354+
buttons: buttonsToRust(opts?.buttons)
232355
})
356+
357+
return resultToJS(res)
233358
}
234359

235360
/**

plugins/dialog/ios/Sources/DialogPlugin.swift

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ struct MessageDialogOptions: Decodable {
2020
var title: String?
2121
let message: String
2222
var okButtonLabel: String?
23+
var noButtonLabel: String?
2324
var cancelButtonLabel: String?
2425
}
2526

@@ -200,36 +201,38 @@ class DialogPlugin: Plugin {
200201
let alert = UIAlertController(
201202
title: args.title, message: args.message, preferredStyle: UIAlertController.Style.alert)
202203

203-
let cancelButtonLabel = args.cancelButtonLabel ?? ""
204-
if !cancelButtonLabel.isEmpty {
204+
if let cancelButtonLabel = args.cancelButtonLabel {
205205
alert.addAction(
206206
UIAlertAction(
207207
title: cancelButtonLabel, style: UIAlertAction.Style.default,
208208
handler: { (_) -> Void in
209-
Logger.error("cancel")
210-
211-
invoke.resolve([
212-
"value": false,
213-
"cancelled": false,
214-
])
215-
}))
209+
invoke.resolve(["value": cancelButtonLabel])
210+
}
211+
)
212+
)
216213
}
217214

218-
let okButtonLabel = args.okButtonLabel ?? (cancelButtonLabel.isEmpty ? "OK" : "")
219-
if !okButtonLabel.isEmpty {
215+
if let noButtonLabel = args.noButtonLabel {
220216
alert.addAction(
221217
UIAlertAction(
222-
title: okButtonLabel, style: UIAlertAction.Style.default,
218+
title: noButtonLabel, style: UIAlertAction.Style.default,
223219
handler: { (_) -> Void in
224-
Logger.error("ok")
225-
226-
invoke.resolve([
227-
"value": true,
228-
"cancelled": false,
229-
])
230-
}))
220+
invoke.resolve(["value": noButtonLabel])
221+
}
222+
)
223+
)
231224
}
232225

226+
let okButtonLabel = args.okButtonLabel ?? "Ok"
227+
alert.addAction(
228+
UIAlertAction(
229+
title: okButtonLabel, style: UIAlertAction.Style.default,
230+
handler: { (_) -> Void in
231+
invoke.resolve(["value": okButtonLabel])
232+
}
233+
)
234+
)
235+
233236
manager.viewController?.present(alert, animated: true, completion: nil)
234237
}
235238
}

0 commit comments

Comments
 (0)