feat(display): support prompt dialogs via webview fallback
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run

This commit is contained in:
Virgil 2026-04-02 20:08:42 +00:00
parent a23e265cc6
commit b50149af5d
2 changed files with 54 additions and 3 deletions

View file

@ -143,7 +143,7 @@ This document tracks the implementation of display server features that enable A
- [x] `dialog_open_directory` - Show directory picker
- [x] `dialog_message` - Show message dialog (info/warning/error) (via notification_show)
- [x] `dialog_confirm` - Show confirmation dialog
- [~] `dialog_prompt` - Show input prompt dialog (not supported natively in Wails v3)
- [x] `dialog_prompt` - Show input prompt dialog with a webview fallback when native support is unavailable
### Theme & Appearance
- [x] `theme_get` - Get current theme (dark/light)

View file

@ -2018,9 +2018,20 @@ func (s *Service) ConfirmDialog(title, message string) (bool, error) {
return button == "Yes" || button == "OK", nil
}
// PromptDialog shows a prompt-style dialog and returns the selected button.
// Use: button, accepted, err := svc.PromptDialog("Rename file", "Enter a new name")
// PromptDialog shows a prompt-style dialog and returns entered text when the webview
// prompt path is available, otherwise it falls back to a button-based message dialog.
// Use: value, accepted, err := svc.PromptDialog("Rename file", "Enter a new name")
func (s *Service) PromptDialog(title, message string) (string, bool, error) {
if text, ok, err := s.promptViaWebView(title, message); err == nil {
if ok {
return text, true, nil
}
return "", false, nil
}
// Fall back to the native message dialog path when no webview prompt is available.
// The returned error is intentionally ignored unless the fallback also fails.
result, handled, err := s.Core().PERFORM(dialog.TaskMessageDialog{
Opts: dialog.MessageDialogOptions{
Type: dialog.DialogInfo,
@ -2039,6 +2050,46 @@ func (s *Service) PromptDialog(title, message string) (string, bool, error) {
return button, button == "OK", nil
}
func (s *Service) promptViaWebView(title, message string) (string, bool, error) {
windowName := s.GetFocusedWindow()
if windowName == "" {
infos := s.ListWindowInfos()
if len(infos) > 0 {
windowName = infos[0].Name
}
}
if windowName == "" {
return "", false, fmt.Errorf("no webview window available")
}
encodedTitle, err := json.Marshal(title)
if err != nil {
return "", false, err
}
encodedMessage, err := json.Marshal(message)
if err != nil {
return "", false, err
}
result, handled, err := s.Core().PERFORM(webview.TaskEvaluate{
Window: windowName,
Script: "window.prompt(" + string(encodedTitle) + "," + string(encodedMessage) + ")",
})
if err != nil {
return "", false, err
}
if !handled {
return "", false, fmt.Errorf("webview service not available")
}
if result == nil {
return "", false, nil
}
if text, ok := result.(string); ok {
return text, true, nil
}
return fmt.Sprint(result), true, nil
}
// DialogMessage shows an informational, warning, or error message via the notification pipeline.
// Use: _ = svc.DialogMessage("warning", "Build failed", "Check the log output")
func (s *Service) DialogMessage(kind, title, message string) error {