[v2] [broken - WIP] Major refactor of runtime in progress
@ -1,14 +1,13 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// App struct
|
// App struct
|
||||||
type App struct {
|
type App struct {
|
||||||
runtime *wails.Runtime
|
runtime context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewApp creates a new App application struct
|
// NewApp creates a new App application struct
|
||||||
@ -17,10 +16,12 @@ func NewApp() *App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// startup is called at application startup
|
// startup is called at application startup
|
||||||
func (b *App) startup(runtime *wails.Runtime) {
|
func (b *App) startup(ctx context.Context) {
|
||||||
// Perform your setup here
|
// Perform your setup here
|
||||||
b.runtime = runtime
|
//TODO: move to new runtime layout
|
||||||
runtime.Window.SetTitle("{{.ProjectName}}")
|
|
||||||
|
//b.runtime = runtime
|
||||||
|
//runtime.Window.SetTitle("{{.ProjectName}}")
|
||||||
}
|
}
|
||||||
|
|
||||||
// shutdown is called at application termination
|
// shutdown is called at application termination
|
||||||
|
@ -51,7 +51,7 @@ type App struct {
|
|||||||
appconfigStore *runtime.Store
|
appconfigStore *runtime.Store
|
||||||
|
|
||||||
// Startup/Shutdown
|
// Startup/Shutdown
|
||||||
startupCallback func(*runtime.Runtime)
|
startupCallback func(ctx context.Context)
|
||||||
shutdownCallback func()
|
shutdownCallback func()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package bridge
|
package bridge
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
"github.com/wailsapp/wails/v2/pkg/runtime/dialog"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BridgeClient struct {
|
type BridgeClient struct {
|
||||||
@ -34,23 +34,23 @@ func (b BridgeClient) CallResult(message string) {
|
|||||||
b.session.sendMessage("c" + message)
|
b.session.sendMessage("c" + message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BridgeClient) OpenFileDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
func (b BridgeClient) OpenFileDialog(dialogOptions dialog.OpenDialogOptions, callbackID string) {
|
||||||
// Handled by dialog_client
|
// Handled by dialog_client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BridgeClient) OpenMultipleFilesDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
func (b BridgeClient) OpenMultipleFilesDialog(dialogOptions dialog.OpenDialogOptions, callbackID string) {
|
||||||
// Handled by dialog_client
|
// Handled by dialog_client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BridgeClient) OpenDirectoryDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
func (b BridgeClient) OpenDirectoryDialog(dialogOptions dialog.OpenDialogOptions, callbackID string) {
|
||||||
// Handled by dialog_client
|
// Handled by dialog_client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BridgeClient) SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string) {
|
func (b BridgeClient) SaveDialog(dialogOptions dialog.SaveDialogOptions, callbackID string) {
|
||||||
// Handled by dialog_client
|
// Handled by dialog_client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BridgeClient) MessageDialog(dialogOptions *dialog.MessageDialog, callbackID string) {
|
func (b BridgeClient) MessageDialog(dialogOptions dialog.MessageDialogOptions, callbackID string) {
|
||||||
// Handled by dialog_client
|
// Handled by dialog_client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
"github.com/wailsapp/wails/v2/internal/logger"
|
"github.com/wailsapp/wails/v2/internal/logger"
|
||||||
|
|
||||||
"github.com/leaanthony/slicer"
|
"github.com/leaanthony/slicer"
|
||||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
"github.com/wailsapp/wails/v2/pkg/runtime/dialog"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DialogClient struct {
|
type DialogClient struct {
|
||||||
@ -37,17 +37,17 @@ func (d *DialogClient) NotifyEvent(message string) {
|
|||||||
func (d *DialogClient) CallResult(message string) {
|
func (d *DialogClient) CallResult(message string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DialogClient) OpenDirectoryDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
func (d *DialogClient) OpenDirectoryDialog(options dialog.OpenDialogOptions, callbackID string) {
|
||||||
}
|
}
|
||||||
func (d *DialogClient) OpenFileDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
func (d *DialogClient) OpenFileDialog(options dialog.OpenDialogOptions, callbackID string) {
|
||||||
}
|
}
|
||||||
func (d *DialogClient) OpenMultipleFilesDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
func (d *DialogClient) OpenMultipleFilesDialog(options dialog.OpenDialogOptions, callbackID string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DialogClient) SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string) {
|
func (d *DialogClient) SaveDialog(options dialog.SaveDialogOptions, callbackID string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DialogClient) MessageDialog(dialogOptions *dialog.MessageDialog, callbackID string) {
|
func (d *DialogClient) MessageDialog(options dialog.MessageDialogOptions, callbackID string) {
|
||||||
|
|
||||||
osa, err := exec.LookPath("osascript")
|
osa, err := exec.LookPath("osascript")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -58,23 +58,23 @@ func (d *DialogClient) MessageDialog(dialogOptions *dialog.MessageDialog, callba
|
|||||||
var btns slicer.StringSlicer
|
var btns slicer.StringSlicer
|
||||||
defaultButton := ""
|
defaultButton := ""
|
||||||
cancelButton := ""
|
cancelButton := ""
|
||||||
for index, btn := range dialogOptions.Buttons {
|
for index, btn := range options.Buttons {
|
||||||
btns.Add(strconv.Quote(btn))
|
btns.Add(strconv.Quote(btn))
|
||||||
if btn == dialogOptions.DefaultButton {
|
if btn == options.DefaultButton {
|
||||||
defaultButton = fmt.Sprintf("default button %d", index+1)
|
defaultButton = fmt.Sprintf("default button %d", index+1)
|
||||||
}
|
}
|
||||||
if btn == dialogOptions.CancelButton {
|
if btn == options.CancelButton {
|
||||||
cancelButton = fmt.Sprintf("cancel button %d", index+1)
|
cancelButton = fmt.Sprintf("cancel button %d", index+1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buttons := "{" + btns.Join(",") + "}"
|
buttons := "{" + btns.Join(",") + "}"
|
||||||
script := fmt.Sprintf("display dialog \"%s\" buttons %s %s %s with title \"%s\"", dialogOptions.Message, buttons, defaultButton, cancelButton, dialogOptions.Title)
|
script := fmt.Sprintf("display dialog \"%s\" buttons %s %s %s with title \"%s\"", options.Message, buttons, defaultButton, cancelButton, options.Title)
|
||||||
go func() {
|
go func() {
|
||||||
out, err := exec.Command(osa, "-e", script).Output()
|
out, err := exec.Command(osa, "-e", script).Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Assume user has pressed cancel button
|
// Assume user has pressed cancel button
|
||||||
if dialogOptions.CancelButton != "" {
|
if options.CancelButton != "" {
|
||||||
d.dispatcher.DispatchMessage("DM" + callbackID + "|" + dialogOptions.CancelButton)
|
d.dispatcher.DispatchMessage("DM" + callbackID + "|" + options.CancelButton)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
d.log.Error("Dialog had bad exit code. If this was a Cancel button, add 'CancelButton' to the dialog.MessageDialog struct. Error: %s", err.Error())
|
d.log.Error("Dialog had bad exit code. If this was a Cancel button, add 'CancelButton' to the dialog.MessageDialog struct. Error: %s", err.Error())
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
"github.com/wailsapp/wails/v2/pkg/runtime/dialog"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2/internal/logger"
|
"github.com/wailsapp/wails/v2/internal/logger"
|
||||||
)
|
)
|
||||||
@ -127,7 +127,7 @@ func (c *Client) WindowSetColour(colour int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OpenFileDialog will open a dialog with the given title and filter
|
// OpenFileDialog will open a dialog with the given title and filter
|
||||||
func (c *Client) OpenFileDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
func (c *Client) OpenFileDialog(dialogOptions dialog.OpenDialogOptions, callbackID string) {
|
||||||
filters := []string{}
|
filters := []string{}
|
||||||
if runtime.GOOS == "darwin" {
|
if runtime.GOOS == "darwin" {
|
||||||
for _, filter := range dialogOptions.Filters {
|
for _, filter := range dialogOptions.Filters {
|
||||||
@ -150,9 +150,8 @@ func (c *Client) OpenFileDialog(dialogOptions *dialog.OpenDialog, callbackID str
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// OpenDirectoryDialog will open a dialog with the given title and filter
|
// OpenDirectoryDialog will open a dialog with the given title and filter
|
||||||
func (c *Client) OpenDirectoryDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
func (c *Client) OpenDirectoryDialog(dialogOptions dialog.OpenDialogOptions, callbackID string) {
|
||||||
filters := []string{}
|
filters := []string{}
|
||||||
if runtime.GOOS == "darwin" {
|
if runtime.GOOS == "darwin" {
|
||||||
for _, filter := range dialogOptions.Filters {
|
for _, filter := range dialogOptions.Filters {
|
||||||
@ -166,7 +165,7 @@ func (c *Client) OpenDirectoryDialog(dialogOptions *dialog.OpenDialog, callbackI
|
|||||||
c.app.string2CString(dialogOptions.DefaultFilename),
|
c.app.string2CString(dialogOptions.DefaultFilename),
|
||||||
c.app.string2CString(dialogOptions.DefaultDirectory),
|
c.app.string2CString(dialogOptions.DefaultDirectory),
|
||||||
c.app.bool2Cint(false), // Files
|
c.app.bool2Cint(false), // Files
|
||||||
c.app.bool2Cint(true), // Directories
|
c.app.bool2Cint(true), // Directories
|
||||||
c.app.bool2Cint(false), // Multiple
|
c.app.bool2Cint(false), // Multiple
|
||||||
c.app.bool2Cint(dialogOptions.ShowHiddenFiles),
|
c.app.bool2Cint(dialogOptions.ShowHiddenFiles),
|
||||||
c.app.bool2Cint(dialogOptions.CanCreateDirectories),
|
c.app.bool2Cint(dialogOptions.CanCreateDirectories),
|
||||||
@ -176,7 +175,7 @@ func (c *Client) OpenDirectoryDialog(dialogOptions *dialog.OpenDialog, callbackI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OpenMultipleFilesDialog will open a dialog with the given title and filter
|
// OpenMultipleFilesDialog will open a dialog with the given title and filter
|
||||||
func (c *Client) OpenMultipleFilesDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
func (c *Client) OpenMultipleFilesDialog(dialogOptions dialog.OpenDialogOptions, callbackID string) {
|
||||||
filters := []string{}
|
filters := []string{}
|
||||||
if runtime.GOOS == "darwin" {
|
if runtime.GOOS == "darwin" {
|
||||||
for _, filter := range dialogOptions.Filters {
|
for _, filter := range dialogOptions.Filters {
|
||||||
@ -220,7 +219,7 @@ func (c *Client) SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MessageDialog will open a message dialog with the given options
|
// MessageDialog will open a message dialog with the given options
|
||||||
func (c *Client) MessageDialog(dialogOptions *dialog.MessageDialog, callbackID string) {
|
func (c *Client) MessageDialog(dialogOptions dialog.MessageDialogOptions, callbackID string) {
|
||||||
|
|
||||||
// Sanity check button length
|
// Sanity check button length
|
||||||
if len(dialogOptions.Buttons) > 4 {
|
if len(dialogOptions.Buttons) > 4 {
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
"github.com/wailsapp/wails/v2/pkg/runtime/dialog"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2/internal/logger"
|
"github.com/wailsapp/wails/v2/internal/logger"
|
||||||
)
|
)
|
||||||
@ -140,7 +140,7 @@ func convertFilters(filters []dialog.FileFilter) []cfd.FileFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OpenFileDialog will open a dialog with the given title and filter
|
// OpenFileDialog will open a dialog with the given title and filter
|
||||||
func (c *Client) OpenFileDialog(options *dialog.OpenDialog, callbackID string) {
|
func (c *Client) OpenFileDialog(options dialog.OpenDialogOptions, callbackID string) {
|
||||||
config := cfd.DialogConfig{
|
config := cfd.DialogConfig{
|
||||||
Folder: options.DefaultDirectory,
|
Folder: options.DefaultDirectory,
|
||||||
FileFilters: convertFilters(options.Filters),
|
FileFilters: convertFilters(options.Filters),
|
||||||
@ -166,7 +166,7 @@ func (c *Client) OpenFileDialog(options *dialog.OpenDialog, callbackID string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OpenDirectoryDialog will open a dialog with the given title and filter
|
// OpenDirectoryDialog will open a dialog with the given title and filter
|
||||||
func (c *Client) OpenDirectoryDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
func (c *Client) OpenDirectoryDialog(dialogOptions dialog.OpenDialogOptions, callbackID string) {
|
||||||
config := cfd.DialogConfig{
|
config := cfd.DialogConfig{
|
||||||
Title: dialogOptions.Title,
|
Title: dialogOptions.Title,
|
||||||
Role: "PickFolder",
|
Role: "PickFolder",
|
||||||
@ -191,7 +191,7 @@ func (c *Client) OpenDirectoryDialog(dialogOptions *dialog.OpenDialog, callbackI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OpenMultipleFilesDialog will open a dialog with the given title and filter
|
// OpenMultipleFilesDialog will open a dialog with the given title and filter
|
||||||
func (c *Client) OpenMultipleFilesDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
func (c *Client) OpenMultipleFilesDialog(dialogOptions dialog.OpenDialogOptions, callbackID string) {
|
||||||
config := cfd.DialogConfig{
|
config := cfd.DialogConfig{
|
||||||
Title: dialogOptions.Title,
|
Title: dialogOptions.Title,
|
||||||
Role: "OpenMultipleFiles",
|
Role: "OpenMultipleFiles",
|
||||||
@ -222,7 +222,7 @@ func (c *Client) OpenMultipleFilesDialog(dialogOptions *dialog.OpenDialog, callb
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SaveDialog will open a dialog with the given title and filter
|
// SaveDialog will open a dialog with the given title and filter
|
||||||
func (c *Client) SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string) {
|
func (c *Client) SaveDialog(dialogOptions dialog.SaveDialogOptions, callbackID string) {
|
||||||
saveDialog, err := cfd.NewSaveFileDialog(cfd.DialogConfig{
|
saveDialog, err := cfd.NewSaveFileDialog(cfd.DialogConfig{
|
||||||
Title: dialogOptions.Title,
|
Title: dialogOptions.Title,
|
||||||
Role: "SaveFile",
|
Role: "SaveFile",
|
||||||
@ -246,7 +246,7 @@ func (c *Client) SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MessageDialog will open a message dialog with the given options
|
// MessageDialog will open a message dialog with the given options
|
||||||
func (c *Client) MessageDialog(options *dialog.MessageDialog, callbackID string) {
|
func (c *Client) MessageDialog(options dialog.MessageDialogOptions, callbackID string) {
|
||||||
|
|
||||||
title, err := syscall.UTF16PtrFromString(options.Title)
|
title, err := syscall.UTF16PtrFromString(options.Title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"github.com/wailsapp/wails/v2/internal/logger"
|
"github.com/wailsapp/wails/v2/internal/logger"
|
||||||
"github.com/wailsapp/wails/v2/internal/messagedispatcher/message"
|
"github.com/wailsapp/wails/v2/internal/messagedispatcher/message"
|
||||||
"github.com/wailsapp/wails/v2/internal/servicebus"
|
"github.com/wailsapp/wails/v2/internal/servicebus"
|
||||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
"github.com/wailsapp/wails/v2/pkg/runtime/dialog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Client defines what a frontend client can do
|
// Client defines what a frontend client can do
|
||||||
@ -14,11 +14,11 @@ type Client interface {
|
|||||||
Quit()
|
Quit()
|
||||||
NotifyEvent(message string)
|
NotifyEvent(message string)
|
||||||
CallResult(message string)
|
CallResult(message string)
|
||||||
OpenFileDialog(dialogOptions *dialog.OpenDialog, callbackID string)
|
OpenFileDialog(dialogOptions dialog.OpenDialogOptions, callbackID string)
|
||||||
OpenMultipleFilesDialog(dialogOptions *dialog.OpenDialog, callbackID string)
|
OpenMultipleFilesDialog(dialogOptions dialog.OpenDialogOptions, callbackID string)
|
||||||
OpenDirectoryDialog(dialogOptions *dialog.OpenDialog, callbackID string)
|
OpenDirectoryDialog(dialogOptions dialog.OpenDialogOptions, callbackID string)
|
||||||
SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string)
|
SaveDialog(dialogOptions dialog.SaveDialogOptions, callbackID string)
|
||||||
MessageDialog(dialogOptions *dialog.MessageDialog, callbackID string)
|
MessageDialog(dialogOptions dialog.MessageDialogOptions, callbackID string)
|
||||||
WindowSetTitle(title string)
|
WindowSetTitle(title string)
|
||||||
WindowShow()
|
WindowShow()
|
||||||
WindowHide()
|
WindowHide()
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
"github.com/wailsapp/wails/v2/pkg/runtime/dialog"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2/internal/crypto"
|
"github.com/wailsapp/wails/v2/internal/crypto"
|
||||||
"github.com/wailsapp/wails/v2/internal/logger"
|
"github.com/wailsapp/wails/v2/internal/logger"
|
||||||
@ -411,7 +411,7 @@ func (d *Dispatcher) processDialogMessage(result *servicebus.Message) {
|
|||||||
dialogType := splitTopic[2]
|
dialogType := splitTopic[2]
|
||||||
switch dialogType {
|
switch dialogType {
|
||||||
case "open":
|
case "open":
|
||||||
dialogOptions, ok := result.Data().(*dialog.OpenDialog)
|
dialogOptions, ok := result.Data().(dialog.OpenDialogOptions)
|
||||||
if !ok {
|
if !ok {
|
||||||
d.logger.Error("Invalid data for 'dialog:select:open' : %#v", result.Data())
|
d.logger.Error("Invalid data for 'dialog:select:open' : %#v", result.Data())
|
||||||
return
|
return
|
||||||
@ -425,7 +425,7 @@ func (d *Dispatcher) processDialogMessage(result *servicebus.Message) {
|
|||||||
client.frontend.OpenFileDialog(dialogOptions, callbackID)
|
client.frontend.OpenFileDialog(dialogOptions, callbackID)
|
||||||
}
|
}
|
||||||
case "openmultiple":
|
case "openmultiple":
|
||||||
dialogOptions, ok := result.Data().(*dialog.OpenDialog)
|
dialogOptions, ok := result.Data().(dialog.OpenDialogOptions)
|
||||||
if !ok {
|
if !ok {
|
||||||
d.logger.Error("Invalid data for 'dialog:select:openmultiple' : %#v", result.Data())
|
d.logger.Error("Invalid data for 'dialog:select:openmultiple' : %#v", result.Data())
|
||||||
return
|
return
|
||||||
@ -439,7 +439,7 @@ func (d *Dispatcher) processDialogMessage(result *servicebus.Message) {
|
|||||||
client.frontend.OpenMultipleFilesDialog(dialogOptions, callbackID)
|
client.frontend.OpenMultipleFilesDialog(dialogOptions, callbackID)
|
||||||
}
|
}
|
||||||
case "directory":
|
case "directory":
|
||||||
dialogOptions, ok := result.Data().(*dialog.OpenDialog)
|
dialogOptions, ok := result.Data().(dialog.OpenDialogOptions)
|
||||||
if !ok {
|
if !ok {
|
||||||
d.logger.Error("Invalid data for 'dialog:select:directory' : %#v", result.Data())
|
d.logger.Error("Invalid data for 'dialog:select:directory' : %#v", result.Data())
|
||||||
return
|
return
|
||||||
@ -453,7 +453,7 @@ func (d *Dispatcher) processDialogMessage(result *servicebus.Message) {
|
|||||||
client.frontend.OpenDirectoryDialog(dialogOptions, callbackID)
|
client.frontend.OpenDirectoryDialog(dialogOptions, callbackID)
|
||||||
}
|
}
|
||||||
case "save":
|
case "save":
|
||||||
dialogOptions, ok := result.Data().(*dialog.SaveDialog)
|
dialogOptions, ok := result.Data().(dialog.SaveDialogOptions)
|
||||||
if !ok {
|
if !ok {
|
||||||
d.logger.Error("Invalid data for 'dialog:select:save' : %#v", result.Data())
|
d.logger.Error("Invalid data for 'dialog:select:save' : %#v", result.Data())
|
||||||
return
|
return
|
||||||
@ -467,7 +467,7 @@ func (d *Dispatcher) processDialogMessage(result *servicebus.Message) {
|
|||||||
client.frontend.SaveDialog(dialogOptions, callbackID)
|
client.frontend.SaveDialog(dialogOptions, callbackID)
|
||||||
}
|
}
|
||||||
case "message":
|
case "message":
|
||||||
dialogOptions, ok := result.Data().(*dialog.MessageDialog)
|
dialogOptions, ok := result.Data().(dialog.MessageDialogOptions)
|
||||||
if !ok {
|
if !ok {
|
||||||
d.logger.Error("Invalid data for 'dialog:select:message' : %#v", result.Data())
|
d.logger.Error("Invalid data for 'dialog:select:message' : %#v", result.Data())
|
||||||
return
|
return
|
||||||
|
@ -1,172 +1,172 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import (
|
//
|
||||||
"fmt"
|
//import (
|
||||||
|
// "fmt"
|
||||||
"github.com/wailsapp/wails/v2/internal/crypto"
|
// "github.com/wailsapp/wails/v2/internal/crypto"
|
||||||
"github.com/wailsapp/wails/v2/internal/servicebus"
|
// "github.com/wailsapp/wails/v2/internal/servicebus"
|
||||||
dialogoptions "github.com/wailsapp/wails/v2/pkg/options/dialog"
|
// d "github.com/wailsapp/wails/v2/pkg/runtime/dialog"
|
||||||
)
|
//)
|
||||||
|
//
|
||||||
// Dialog defines all Dialog related operations
|
//// Dialog defines all Dialog related operations
|
||||||
type Dialog interface {
|
//type Dialog interface {
|
||||||
OpenFile(dialogOptions *dialogoptions.OpenDialog) (string, error)
|
// OpenFile(options d.OpenDialogOptions) (string, error)
|
||||||
OpenMultipleFiles(dialogOptions *dialogoptions.OpenDialog) ([]string, error)
|
// OpenMultipleFiles(options d.OpenDialogOptions) ([]string, error)
|
||||||
OpenDirectory(dialogOptions *dialogoptions.OpenDialog) (string, error)
|
// OpenDirectory(options d.OpenDialogOptions) (string, error)
|
||||||
SaveFile(dialogOptions *dialogoptions.SaveDialog) (string, error)
|
// SaveFile(options d.SaveDialogOptions) (string, error)
|
||||||
Message(dialogOptions *dialogoptions.MessageDialog) (string, error)
|
// Message(options d.MessageDialogOptions) (string, error)
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// dialog exposes the Dialog interface
|
//// dialog exposes the Dialog interface
|
||||||
type dialog struct {
|
//type dialog struct {
|
||||||
bus *servicebus.ServiceBus
|
// bus *servicebus.ServiceBus
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// newDialogs creates a new Dialogs struct
|
//// newDialogs creates a new Dialogs struct
|
||||||
func newDialog(bus *servicebus.ServiceBus) Dialog {
|
//func newDialog(bus *servicebus.ServiceBus) *dialog {
|
||||||
return &dialog{
|
// return &dialog{
|
||||||
bus: bus,
|
// bus: bus,
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// processTitleAndFilter return the title and filter from the given params.
|
//// processTitleAndFilter return the title and filter from the given params.
|
||||||
// title is the first string, filter is the second
|
//// title is the first string, filter is the second
|
||||||
func (r *dialog) processTitleAndFilter(params ...string) (string, string) {
|
//func (r *dialog) processTitleAndFilter(params ...string) (string, string) {
|
||||||
|
//
|
||||||
var title, filter string
|
// var title, filter string
|
||||||
|
//
|
||||||
if len(params) > 0 {
|
// if len(params) > 0 {
|
||||||
title = params[0]
|
// title = params[0]
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if len(params) > 1 {
|
// if len(params) > 1 {
|
||||||
filter = params[1]
|
// filter = params[1]
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return title, filter
|
// return title, filter
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// OpenDirectory prompts the user to select a directory
|
//// OpenDirectory prompts the user to select a directory
|
||||||
func (r *dialog) OpenDirectory(dialogOptions *dialogoptions.OpenDialog) (string, error) {
|
//func (r *dialog) OpenDirectory(dialogOptions d.OpenDialogOptions) (string, error) {
|
||||||
|
//
|
||||||
// Create unique dialog callback
|
// // Create unique dialog callback
|
||||||
uniqueCallback := crypto.RandomID()
|
// uniqueCallback := crypto.RandomID()
|
||||||
|
//
|
||||||
// Subscribe to the respose channel
|
// // Subscribe to the respose channel
|
||||||
responseTopic := "dialog:opendirectoryselected:" + uniqueCallback
|
// responseTopic := "dialog:opendirectoryselected:" + uniqueCallback
|
||||||
dialogResponseChannel, err := r.bus.Subscribe(responseTopic)
|
// dialogResponseChannel, err := r.bus.Subscribe(responseTopic)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return "", fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
// return "", fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
message := "dialog:select:directory:" + uniqueCallback
|
// message := "dialog:select:directory:" + uniqueCallback
|
||||||
r.bus.Publish(message, dialogOptions)
|
// r.bus.Publish(message, dialogOptions)
|
||||||
|
//
|
||||||
// Wait for result
|
// // Wait for result
|
||||||
var result = <-dialogResponseChannel
|
// var result = <-dialogResponseChannel
|
||||||
|
//
|
||||||
// Delete subscription to response topic
|
// // Delete subscription to response topic
|
||||||
r.bus.UnSubscribe(responseTopic)
|
// r.bus.UnSubscribe(responseTopic)
|
||||||
|
//
|
||||||
return result.Data().(string), nil
|
// return result.Data().(string), nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// OpenFile prompts the user to select a file
|
//// OpenFile prompts the user to select a file
|
||||||
func (r *dialog) OpenFile(dialogOptions *dialogoptions.OpenDialog) (string, error) {
|
//func (r *dialog) OpenFile(dialogOptions d.OpenDialogOptions) (string, error) {
|
||||||
|
//
|
||||||
// Create unique dialog callback
|
// // Create unique dialog callback
|
||||||
uniqueCallback := crypto.RandomID()
|
// uniqueCallback := crypto.RandomID()
|
||||||
|
//
|
||||||
// Subscribe to the respose channel
|
// // Subscribe to the respose channel
|
||||||
responseTopic := "dialog:openselected:" + uniqueCallback
|
// responseTopic := "dialog:openselected:" + uniqueCallback
|
||||||
dialogResponseChannel, err := r.bus.Subscribe(responseTopic)
|
// dialogResponseChannel, err := r.bus.Subscribe(responseTopic)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return "", fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
// return "", fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
message := "dialog:select:open:" + uniqueCallback
|
// message := "dialog:select:open:" + uniqueCallback
|
||||||
r.bus.Publish(message, dialogOptions)
|
// r.bus.Publish(message, dialogOptions)
|
||||||
|
//
|
||||||
// Wait for result
|
// // Wait for result
|
||||||
var result = <-dialogResponseChannel
|
// var result = <-dialogResponseChannel
|
||||||
|
//
|
||||||
// Delete subscription to response topic
|
// // Delete subscription to response topic
|
||||||
r.bus.UnSubscribe(responseTopic)
|
// r.bus.UnSubscribe(responseTopic)
|
||||||
|
//
|
||||||
return result.Data().(string), nil
|
// return result.Data().(string), nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// OpenMultipleFiles prompts the user to select a file
|
//// OpenMultipleFiles prompts the user to select a file
|
||||||
func (r *dialog) OpenMultipleFiles(dialogOptions *dialogoptions.OpenDialog) ([]string, error) {
|
//func (r *dialog) OpenMultipleFiles(dialogOptions d.OpenDialogOptions) ([]string, error) {
|
||||||
|
//
|
||||||
// Create unique dialog callback
|
// // Create unique dialog callback
|
||||||
uniqueCallback := crypto.RandomID()
|
// uniqueCallback := crypto.RandomID()
|
||||||
|
//
|
||||||
// Subscribe to the respose channel
|
// // Subscribe to the respose channel
|
||||||
responseTopic := "dialog:openmultipleselected:" + uniqueCallback
|
// responseTopic := "dialog:openmultipleselected:" + uniqueCallback
|
||||||
dialogResponseChannel, err := r.bus.Subscribe(responseTopic)
|
// dialogResponseChannel, err := r.bus.Subscribe(responseTopic)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
// return nil, fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
message := "dialog:select:openmultiple:" + uniqueCallback
|
// message := "dialog:select:openmultiple:" + uniqueCallback
|
||||||
r.bus.Publish(message, dialogOptions)
|
// r.bus.Publish(message, dialogOptions)
|
||||||
|
//
|
||||||
// Wait for result
|
// // Wait for result
|
||||||
var result = <-dialogResponseChannel
|
// var result = <-dialogResponseChannel
|
||||||
|
//
|
||||||
// Delete subscription to response topic
|
// // Delete subscription to response topic
|
||||||
r.bus.UnSubscribe(responseTopic)
|
// r.bus.UnSubscribe(responseTopic)
|
||||||
|
//
|
||||||
return result.Data().([]string), nil
|
// return result.Data().([]string), nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// SaveFile prompts the user to select a file
|
//// SaveFile prompts the user to select a file
|
||||||
func (r *dialog) SaveFile(dialogOptions *dialogoptions.SaveDialog) (string, error) {
|
//func (r *dialog) SaveFile(dialogOptions d.SaveDialogOptions) (string, error) {
|
||||||
|
//
|
||||||
// Create unique dialog callback
|
// // Create unique dialog callback
|
||||||
uniqueCallback := crypto.RandomID()
|
// uniqueCallback := crypto.RandomID()
|
||||||
|
//
|
||||||
// Subscribe to the respose channel
|
// // Subscribe to the respose channel
|
||||||
responseTopic := "dialog:saveselected:" + uniqueCallback
|
// responseTopic := "dialog:saveselected:" + uniqueCallback
|
||||||
dialogResponseChannel, err := r.bus.Subscribe(responseTopic)
|
// dialogResponseChannel, err := r.bus.Subscribe(responseTopic)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return "", fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
// return "", fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
message := "dialog:select:save:" + uniqueCallback
|
// message := "dialog:select:save:" + uniqueCallback
|
||||||
r.bus.Publish(message, dialogOptions)
|
// r.bus.Publish(message, dialogOptions)
|
||||||
|
//
|
||||||
// Wait for result
|
// // Wait for result
|
||||||
var result = <-dialogResponseChannel
|
// var result = <-dialogResponseChannel
|
||||||
|
//
|
||||||
// Delete subscription to response topic
|
// // Delete subscription to response topic
|
||||||
r.bus.UnSubscribe(responseTopic)
|
// r.bus.UnSubscribe(responseTopic)
|
||||||
|
//
|
||||||
return result.Data().(string), nil
|
// return result.Data().(string), nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// Message show a message to the user
|
//// Message show a message to the user
|
||||||
func (r *dialog) Message(dialogOptions *dialogoptions.MessageDialog) (string, error) {
|
//func (r *dialog) Message(dialogOptions d.MessageDialogOptions) (string, error) {
|
||||||
|
//
|
||||||
// Create unique dialog callback
|
// // Create unique dialog callback
|
||||||
uniqueCallback := crypto.RandomID()
|
// uniqueCallback := crypto.RandomID()
|
||||||
|
//
|
||||||
// Subscribe to the respose channel
|
// // Subscribe to the respose channel
|
||||||
responseTopic := "dialog:messageselected:" + uniqueCallback
|
// responseTopic := "dialog:messageselected:" + uniqueCallback
|
||||||
dialogResponseChannel, err := r.bus.Subscribe(responseTopic)
|
// dialogResponseChannel, err := r.bus.Subscribe(responseTopic)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return "", fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
// return "", fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
message := "dialog:select:message:" + uniqueCallback
|
// message := "dialog:select:message:" + uniqueCallback
|
||||||
r.bus.Publish(message, dialogOptions)
|
// r.bus.Publish(message, dialogOptions)
|
||||||
|
//
|
||||||
// Wait for result
|
// // Wait for result
|
||||||
var result = <-dialogResponseChannel
|
// var result = <-dialogResponseChannel
|
||||||
|
//
|
||||||
// Delete subscription to response topic
|
// // Delete subscription to response topic
|
||||||
r.bus.UnSubscribe(responseTopic)
|
// r.bus.UnSubscribe(responseTopic)
|
||||||
|
//
|
||||||
return result.Data().(string), nil
|
// return result.Data().(string), nil
|
||||||
}
|
//}
|
||||||
|
@ -9,7 +9,6 @@ type Runtime struct {
|
|||||||
Browser Browser
|
Browser Browser
|
||||||
Events Events
|
Events Events
|
||||||
Window Window
|
Window Window
|
||||||
Dialog Dialog
|
|
||||||
System System
|
System System
|
||||||
Menu Menu
|
Menu Menu
|
||||||
Store *StoreProvider
|
Store *StoreProvider
|
||||||
@ -23,7 +22,6 @@ func New(serviceBus *servicebus.ServiceBus) *Runtime {
|
|||||||
Browser: newBrowser(),
|
Browser: newBrowser(),
|
||||||
Events: newEvents(serviceBus),
|
Events: newEvents(serviceBus),
|
||||||
Window: newWindow(serviceBus),
|
Window: newWindow(serviceBus),
|
||||||
Dialog: newDialog(serviceBus),
|
|
||||||
System: newSystem(serviceBus),
|
System: newSystem(serviceBus),
|
||||||
Menu: newMenu(serviceBus),
|
Menu: newMenu(serviceBus),
|
||||||
Log: newLog(serviceBus),
|
Log: newLog(serviceBus),
|
||||||
|
@ -4,11 +4,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/wailsapp/wails/v2/pkg/runtime/dialog"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2/internal/binding"
|
"github.com/wailsapp/wails/v2/internal/binding"
|
||||||
"github.com/wailsapp/wails/v2/internal/logger"
|
"github.com/wailsapp/wails/v2/internal/logger"
|
||||||
"github.com/wailsapp/wails/v2/internal/messagedispatcher/message"
|
"github.com/wailsapp/wails/v2/internal/messagedispatcher/message"
|
||||||
@ -135,34 +134,34 @@ func (c *Call) processSystemCall(payload *message.CallMessage, clientID string)
|
|||||||
darkModeEnabled := c.runtime.System.IsDarkMode()
|
darkModeEnabled := c.runtime.System.IsDarkMode()
|
||||||
c.sendResult(darkModeEnabled, payload, clientID)
|
c.sendResult(darkModeEnabled, payload, clientID)
|
||||||
case "Dialog.Open":
|
case "Dialog.Open":
|
||||||
dialogOptions := new(dialog.OpenDialog)
|
var dialogOptions dialog.OpenDialogOptions
|
||||||
err := json.Unmarshal(payload.Args[0], dialogOptions)
|
err := json.Unmarshal(payload.Args[0], dialogOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Error("Error decoding: %s", err)
|
c.logger.Error("Error decoding: %s", err)
|
||||||
}
|
}
|
||||||
result, err := c.runtime.Dialog.OpenFile(dialogOptions)
|
result, err := dialog.OpenFile(c.ctx, dialogOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Error("Error: %s", err)
|
c.logger.Error("Error: %s", err)
|
||||||
}
|
}
|
||||||
c.sendResult(result, payload, clientID)
|
c.sendResult(result, payload, clientID)
|
||||||
case "Dialog.Save":
|
case "Dialog.Save":
|
||||||
dialogOptions := new(dialog.SaveDialog)
|
var dialogOptions dialog.SaveDialogOptions
|
||||||
err := json.Unmarshal(payload.Args[0], dialogOptions)
|
err := json.Unmarshal(payload.Args[0], dialogOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Error("Error decoding: %s", err)
|
c.logger.Error("Error decoding: %s", err)
|
||||||
}
|
}
|
||||||
result, err := c.runtime.Dialog.SaveFile(dialogOptions)
|
result, err := dialog.SaveFile(c.ctx, dialogOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Error("Error: %s", err)
|
c.logger.Error("Error: %s", err)
|
||||||
}
|
}
|
||||||
c.sendResult(result, payload, clientID)
|
c.sendResult(result, payload, clientID)
|
||||||
case "Dialog.Message":
|
case "Dialog.Message":
|
||||||
dialogOptions := new(dialog.MessageDialog)
|
var dialogOptions dialog.MessageDialogOptions
|
||||||
err := json.Unmarshal(payload.Args[0], dialogOptions)
|
err := json.Unmarshal(payload.Args[0], dialogOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Error("Error decoding: %s", err)
|
c.logger.Error("Error decoding: %s", err)
|
||||||
}
|
}
|
||||||
result, err := c.runtime.Dialog.Message(dialogOptions)
|
result, err := dialog.Message(c.ctx, dialogOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Error("Error: %s", err)
|
c.logger.Error("Error: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ type Runtime struct {
|
|||||||
|
|
||||||
// The hooks channel allows us to hook into frontend startup
|
// The hooks channel allows us to hook into frontend startup
|
||||||
hooksChannel <-chan *servicebus.Message
|
hooksChannel <-chan *servicebus.Message
|
||||||
startupCallback func(*runtime.Runtime)
|
startupCallback func(ctx context.Context)
|
||||||
shutdownCallback func()
|
shutdownCallback func()
|
||||||
|
|
||||||
// quit flag
|
// quit flag
|
||||||
@ -39,7 +39,7 @@ type Runtime struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewRuntime creates a new runtime subsystem
|
// NewRuntime creates a new runtime subsystem
|
||||||
func NewRuntime(ctx context.Context, bus *servicebus.ServiceBus, logger *logger.Logger, startupCallback func(*runtime.Runtime)) (*Runtime, error) {
|
func NewRuntime(ctx context.Context, bus *servicebus.ServiceBus, logger *logger.Logger, startupCallback func(context.Context)) (*Runtime, error) {
|
||||||
|
|
||||||
// Subscribe to log messages
|
// Subscribe to log messages
|
||||||
runtimeChannel, err := bus.Subscribe("runtime:")
|
runtimeChannel, err := bus.Subscribe("runtime:")
|
||||||
@ -59,9 +59,9 @@ func NewRuntime(ctx context.Context, bus *servicebus.ServiceBus, logger *logger.
|
|||||||
logger: logger.CustomLogger("Runtime Subsystem"),
|
logger: logger.CustomLogger("Runtime Subsystem"),
|
||||||
runtime: runtime.New(bus),
|
runtime: runtime.New(bus),
|
||||||
startupCallback: startupCallback,
|
startupCallback: startupCallback,
|
||||||
ctx: ctx,
|
|
||||||
bus: bus,
|
bus: bus,
|
||||||
}
|
}
|
||||||
|
result.ctx = context.WithValue(ctx, "bus", bus)
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
@ -83,8 +83,7 @@ func (r *Runtime) Start() error {
|
|||||||
if r.startupCallback != nil {
|
if r.startupCallback != nil {
|
||||||
r.startupOnce.Do(func() {
|
r.startupOnce.Do(func() {
|
||||||
go func() {
|
go func() {
|
||||||
r.startupCallback(r.runtime)
|
r.startupCallback(r.ctx)
|
||||||
|
|
||||||
// If we got a url, publish it now startup completed
|
// If we got a url, publish it now startup completed
|
||||||
url, ok := hooksMessage.Data().(string)
|
url, ok := hooksMessage.Data().(string)
|
||||||
if ok && len(url) > 0 {
|
if ok && len(url) > 0 {
|
||||||
|
@ -3,7 +3,7 @@ package webserver
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
"github.com/wailsapp/wails/v2/pkg/runtime/dialog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -20,6 +20,18 @@ type WebClient struct {
|
|||||||
running bool
|
running bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (wc *WebClient) WindowSetMinSize(width int, height int) {
|
||||||
|
wc.logger.Info("Not implemented in server build")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wc *WebClient) WindowSetMaxSize(width int, height int) {
|
||||||
|
wc.logger.Info("Not implemented in server build")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wc *WebClient) DeleteTrayMenuByID(id string) {
|
||||||
|
wc.logger.Info("Not implemented in server build")
|
||||||
|
}
|
||||||
|
|
||||||
func (wc *WebClient) SetTrayMenu(trayMenuJSON string) {
|
func (wc *WebClient) SetTrayMenu(trayMenuJSON string) {
|
||||||
wc.logger.Info("Not implemented in server build")
|
wc.logger.Info("Not implemented in server build")
|
||||||
}
|
}
|
||||||
@ -28,7 +40,7 @@ func (wc *WebClient) UpdateTrayMenuLabel(trayMenuJSON string) {
|
|||||||
wc.logger.Info("Not implemented in server build")
|
wc.logger.Info("Not implemented in server build")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wc *WebClient) MessageDialog(dialogOptions *dialog.MessageDialog, callbackID string) {
|
func (wc *WebClient) MessageDialog(dialogOptions dialog.MessageDialogOptions, callbackID string) {
|
||||||
wc.logger.Info("Not implemented in server build")
|
wc.logger.Info("Not implemented in server build")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,11 +56,19 @@ func (wc *WebClient) UpdateContextMenu(contextMenuJSON string) {
|
|||||||
wc.logger.Info("Not implemented in server build")
|
wc.logger.Info("Not implemented in server build")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wc *WebClient) OpenDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
func (wc *WebClient) OpenFileDialog(dialogOptions dialog.OpenDialogOptions, callbackID string) {
|
||||||
wc.logger.Info("Not implemented in server build")
|
wc.logger.Info("Not implemented in server build")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wc *WebClient) SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string) {
|
func (wc *WebClient) OpenMultipleFilesDialog(dialogOptions dialog.OpenDialogOptions, callbackID string) {
|
||||||
|
wc.logger.Info("Not implemented in server build")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wc *WebClient) OpenDirectoryDialog(dialogOptions dialog.OpenDialogOptions, callbackID string) {
|
||||||
|
wc.logger.Info("Not implemented in server build")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wc *WebClient) SaveDialog(dialogOptions dialog.SaveDialogOptions, callbackID string) {
|
||||||
wc.logger.Info("Not implemented in server build")
|
wc.logger.Info("Not implemented in server build")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
package dialog
|
|
||||||
|
|
||||||
// FileFilter defines a filter for dialog boxes
|
|
||||||
type FileFilter struct {
|
|
||||||
DisplayName string // Filter information EG: "Image Files (*.jpg, *.png)"
|
|
||||||
Pattern string // semi-colon separated list of extensions, EG: "*.jpg;*.png"
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenDialog contains the options for the OpenDialog runtime method
|
|
||||||
type OpenDialog struct {
|
|
||||||
DefaultDirectory string
|
|
||||||
DefaultFilename string
|
|
||||||
Title string
|
|
||||||
Filters []FileFilter
|
|
||||||
AllowFiles bool
|
|
||||||
AllowDirectories bool
|
|
||||||
ShowHiddenFiles bool
|
|
||||||
CanCreateDirectories bool
|
|
||||||
ResolvesAliases bool
|
|
||||||
TreatPackagesAsDirectories bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// SaveDialog contains the options for the SaveDialog runtime method
|
|
||||||
type SaveDialog struct {
|
|
||||||
DefaultDirectory string
|
|
||||||
DefaultFilename string
|
|
||||||
Title string
|
|
||||||
Filters []FileFilter
|
|
||||||
ShowHiddenFiles bool
|
|
||||||
CanCreateDirectories bool
|
|
||||||
TreatPackagesAsDirectories bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type DialogType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
InfoDialog DialogType = "info"
|
|
||||||
WarningDialog DialogType = "warning"
|
|
||||||
ErrorDialog DialogType = "error"
|
|
||||||
QuestionDialog DialogType = "question"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MessageDialog contains the options for the Message dialogs, EG Info, Warning, etc runtime methods
|
|
||||||
type MessageDialog struct {
|
|
||||||
Type DialogType
|
|
||||||
Title string
|
|
||||||
Message string
|
|
||||||
Buttons []string
|
|
||||||
DefaultButton string
|
|
||||||
CancelButton string
|
|
||||||
Icon string
|
|
||||||
}
|
|
@ -1,12 +1,12 @@
|
|||||||
package options
|
package options
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"log"
|
"log"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/options/windows"
|
"github.com/wailsapp/wails/v2/pkg/options/windows"
|
||||||
|
|
||||||
wailsruntime "github.com/wailsapp/wails/v2/internal/runtime"
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||||
|
|
||||||
"github.com/imdario/mergo"
|
"github.com/imdario/mergo"
|
||||||
@ -37,8 +37,8 @@ type App struct {
|
|||||||
Mac *mac.Options
|
Mac *mac.Options
|
||||||
Logger logger.Logger `json:"-"`
|
Logger logger.Logger `json:"-"`
|
||||||
LogLevel logger.LogLevel
|
LogLevel logger.LogLevel
|
||||||
Startup func(*wailsruntime.Runtime) `json:"-"`
|
Startup func(ctx context.Context) `json:"-"`
|
||||||
Shutdown func() `json:"-"`
|
Shutdown func() `json:"-"`
|
||||||
Bind []interface{}
|
Bind []interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
235
v2/pkg/runtime/dialog/dialog.go
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
package dialog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/wailsapp/wails/v2/internal/crypto"
|
||||||
|
"github.com/wailsapp/wails/v2/internal/servicebus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FileFilter defines a filter for dialog boxes
|
||||||
|
type FileFilter struct {
|
||||||
|
DisplayName string // Filter information EG: "Image Files (*.jpg, *.png)"
|
||||||
|
Pattern string // semi-colon separated list of extensions, EG: "*.jpg;*.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenDialogOptions contains the options for the OpenDialogOptions runtime method
|
||||||
|
type OpenDialogOptions struct {
|
||||||
|
DefaultDirectory string
|
||||||
|
DefaultFilename string
|
||||||
|
Title string
|
||||||
|
Filters []FileFilter
|
||||||
|
AllowFiles bool
|
||||||
|
AllowDirectories bool
|
||||||
|
ShowHiddenFiles bool
|
||||||
|
CanCreateDirectories bool
|
||||||
|
ResolvesAliases bool
|
||||||
|
TreatPackagesAsDirectories bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveDialogOptions contains the options for the SaveDialog runtime method
|
||||||
|
type SaveDialogOptions struct {
|
||||||
|
DefaultDirectory string
|
||||||
|
DefaultFilename string
|
||||||
|
Title string
|
||||||
|
Filters []FileFilter
|
||||||
|
ShowHiddenFiles bool
|
||||||
|
CanCreateDirectories bool
|
||||||
|
TreatPackagesAsDirectories bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type DialogType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
InfoDialog DialogType = "info"
|
||||||
|
WarningDialog DialogType = "warning"
|
||||||
|
ErrorDialog DialogType = "error"
|
||||||
|
QuestionDialog DialogType = "question"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MessageDialogOptions contains the options for the Message dialogs, EG Info, Warning, etc runtime methods
|
||||||
|
type MessageDialogOptions struct {
|
||||||
|
Type DialogType
|
||||||
|
Title string
|
||||||
|
Message string
|
||||||
|
Buttons []string
|
||||||
|
DefaultButton string
|
||||||
|
CancelButton string
|
||||||
|
Icon string
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractBus(ctx context.Context) (*servicebus.ServiceBus, error) {
|
||||||
|
bus := ctx.Value("bus")
|
||||||
|
if bus == nil {
|
||||||
|
return nil, errors.New("wails runtime has not been initialised correctly")
|
||||||
|
}
|
||||||
|
return bus.(*servicebus.ServiceBus), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// processTitleAndFilter return the title and filter from the given params.
|
||||||
|
// title is the first string, filter is the second
|
||||||
|
func processTitleAndFilter(params ...string) (string, string) {
|
||||||
|
|
||||||
|
var title, filter string
|
||||||
|
|
||||||
|
if len(params) > 0 {
|
||||||
|
title = params[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(params) > 1 {
|
||||||
|
filter = params[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
return title, filter
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenDirectory prompts the user to select a directory
|
||||||
|
func OpenDirectory(ctx context.Context, dialogOptions OpenDialogOptions) (string, error) {
|
||||||
|
|
||||||
|
bus, err := extractBus(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "OpenDirectory")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create unique dialog callback
|
||||||
|
uniqueCallback := crypto.RandomID()
|
||||||
|
|
||||||
|
// Subscribe to the respose channel
|
||||||
|
responseTopic := "dialog:opendirectoryselected:" + uniqueCallback
|
||||||
|
dialogResponseChannel, err := bus.Subscribe(responseTopic)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
message := "dialog:select:directory:" + uniqueCallback
|
||||||
|
bus.Publish(message, dialogOptions)
|
||||||
|
|
||||||
|
// Wait for result
|
||||||
|
var result = <-dialogResponseChannel
|
||||||
|
|
||||||
|
// Delete subscription to response topic
|
||||||
|
bus.UnSubscribe(responseTopic)
|
||||||
|
|
||||||
|
return result.Data().(string), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenFile prompts the user to select a file
|
||||||
|
func OpenFile(ctx context.Context, dialogOptions OpenDialogOptions) (string, error) {
|
||||||
|
|
||||||
|
bus, err := extractBus(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "OpenFile")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create unique dialog callback
|
||||||
|
uniqueCallback := crypto.RandomID()
|
||||||
|
|
||||||
|
// Subscribe to the respose channel
|
||||||
|
responseTopic := "dialog:openselected:" + uniqueCallback
|
||||||
|
dialogResponseChannel, err := bus.Subscribe(responseTopic)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
message := "dialog:select:open:" + uniqueCallback
|
||||||
|
bus.Publish(message, dialogOptions)
|
||||||
|
|
||||||
|
// Wait for result
|
||||||
|
var result = <-dialogResponseChannel
|
||||||
|
|
||||||
|
// Delete subscription to response topic
|
||||||
|
bus.UnSubscribe(responseTopic)
|
||||||
|
|
||||||
|
return result.Data().(string), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenMultipleFiles prompts the user to select a file
|
||||||
|
func OpenMultipleFiles(ctx context.Context, dialogOptions OpenDialogOptions) ([]string, error) {
|
||||||
|
|
||||||
|
bus, err := extractBus(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "OpenMultipleFiles")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create unique dialog callback
|
||||||
|
uniqueCallback := crypto.RandomID()
|
||||||
|
|
||||||
|
// Subscribe to the respose channel
|
||||||
|
responseTopic := "dialog:openmultipleselected:" + uniqueCallback
|
||||||
|
dialogResponseChannel, err := bus.Subscribe(responseTopic)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
message := "dialog:select:openmultiple:" + uniqueCallback
|
||||||
|
bus.Publish(message, dialogOptions)
|
||||||
|
|
||||||
|
// Wait for result
|
||||||
|
var result = <-dialogResponseChannel
|
||||||
|
|
||||||
|
// Delete subscription to response topic
|
||||||
|
bus.UnSubscribe(responseTopic)
|
||||||
|
|
||||||
|
return result.Data().([]string), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveFile prompts the user to select a file
|
||||||
|
func SaveFile(ctx context.Context, dialogOptions SaveDialogOptions) (string, error) {
|
||||||
|
|
||||||
|
bus, err := extractBus(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "SaveFile")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create unique dialog callback
|
||||||
|
uniqueCallback := crypto.RandomID()
|
||||||
|
|
||||||
|
// Subscribe to the respose channel
|
||||||
|
responseTopic := "dialog:saveselected:" + uniqueCallback
|
||||||
|
dialogResponseChannel, err := bus.Subscribe(responseTopic)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
message := "dialog:select:save:" + uniqueCallback
|
||||||
|
bus.Publish(message, dialogOptions)
|
||||||
|
|
||||||
|
// Wait for result
|
||||||
|
var result = <-dialogResponseChannel
|
||||||
|
|
||||||
|
// Delete subscription to response topic
|
||||||
|
bus.UnSubscribe(responseTopic)
|
||||||
|
|
||||||
|
return result.Data().(string), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message show a message to the user
|
||||||
|
func Message(ctx context.Context, dialogOptions MessageDialogOptions) (string, error) {
|
||||||
|
|
||||||
|
bus, err := extractBus(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "Message")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create unique dialog callback
|
||||||
|
uniqueCallback := crypto.RandomID()
|
||||||
|
|
||||||
|
// Subscribe to the respose channel
|
||||||
|
responseTopic := "dialog:messageselected:" + uniqueCallback
|
||||||
|
dialogResponseChannel, err := bus.Subscribe(responseTopic)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("ERROR: Cannot subscribe to bus topic: %+v\n", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
message := "dialog:select:message:" + uniqueCallback
|
||||||
|
bus.Publish(message, dialogOptions)
|
||||||
|
|
||||||
|
// Wait for result
|
||||||
|
var result = <-dialogResponseChannel
|
||||||
|
|
||||||
|
// Delete subscription to response topic
|
||||||
|
bus.UnSubscribe(responseTopic)
|
||||||
|
|
||||||
|
return result.Data().(string), nil
|
||||||
|
}
|
@ -1,35 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Basic application struct
|
|
||||||
type Basic struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
}
|
|
||||||
|
|
||||||
// newBasic creates a new Basic application struct
|
|
||||||
func newBasic() *Basic {
|
|
||||||
return &Basic{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WailsInit is called at application startup
|
|
||||||
func (b *Basic) WailsInit(runtime *wails.Runtime) error {
|
|
||||||
// Perform your setup here
|
|
||||||
b.runtime = runtime
|
|
||||||
runtime.Window.SetTitle("minmax")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WailsShutdown is called at application termination
|
|
||||||
func (b *Basic) WailsShutdown() {
|
|
||||||
// Perform your teardown here
|
|
||||||
}
|
|
||||||
|
|
||||||
// Greet returns a greeting for the given name
|
|
||||||
func (b *Basic) Greet(name string) string {
|
|
||||||
return fmt.Sprintf("Hello %s!", name)
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="/main.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="logo"></div>
|
|
||||||
<div id="input">
|
|
||||||
<input id="name" type="text"></input>
|
|
||||||
<button onclick="greet()">Greet</button>
|
|
||||||
</div>
|
|
||||||
<div id="result"></div>
|
|
||||||
|
|
||||||
<script src="/main.js"></script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,16 +0,0 @@
|
|||||||
// Get input + focus
|
|
||||||
var nameElement = document.getElementById("name");
|
|
||||||
nameElement.focus();
|
|
||||||
|
|
||||||
// Stup the greet function
|
|
||||||
window.greet = function () {
|
|
||||||
|
|
||||||
// Get name
|
|
||||||
var name = nameElement.value;
|
|
||||||
|
|
||||||
// Call Basic.Greet(name)
|
|
||||||
window.backend.main.Basic.Greet(name).then((result) => {
|
|
||||||
// Update result with data back from Basic.Greet()
|
|
||||||
document.getElementById("result").innerText = result;
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/options"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
// Create application with options
|
|
||||||
app := wails.CreateAppWithOptions(&options.App{
|
|
||||||
Title: "disable resize",
|
|
||||||
Width: 1024,
|
|
||||||
Height: 768,
|
|
||||||
DisableResize: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
app.Bind(newBasic())
|
|
||||||
|
|
||||||
app.Run()
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "disable-resize",
|
|
||||||
"outputfilename": "disable-resize",
|
|
||||||
"html": "frontend/index.html"
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
//goland:noinspection GoRedundantImportAlias
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Basic application struct
|
|
||||||
type Basic struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
}
|
|
||||||
|
|
||||||
// newBasic creates a new Basic application struct
|
|
||||||
func newBasic() *Basic {
|
|
||||||
return &Basic{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WailsInit is called at application startup
|
|
||||||
func (b *Basic) WailsInit(runtime *wails.Runtime) error {
|
|
||||||
// Perform your setup here
|
|
||||||
b.runtime = runtime
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WailsShutdown is called at application termination
|
|
||||||
func (b *Basic) WailsShutdown() {
|
|
||||||
// Perform your teardown here
|
|
||||||
}
|
|
||||||
|
|
||||||
// Greet returns a greeting for the given name
|
|
||||||
func (b *Basic) Greet(name string) string {
|
|
||||||
return fmt.Sprintf("Hello %s!", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close shuts down the application
|
|
||||||
func (b *Basic) Close() {
|
|
||||||
b.runtime.Quit()
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="/main.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body data-wails-drag>
|
|
||||||
<div id="logo"></div>
|
|
||||||
<div id="input" data-wails-no-drag>
|
|
||||||
<a id="close" onclick="closeme()">X</a>
|
|
||||||
<input id="name" type="text"></input>
|
|
||||||
<button onclick="greet()">Greet</button>
|
|
||||||
</div>
|
|
||||||
<div id="result"></div>
|
|
||||||
|
|
||||||
<script src="/main.js"></script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,21 +0,0 @@
|
|||||||
// Get input + focus
|
|
||||||
var nameElement = document.getElementById("name");
|
|
||||||
nameElement.focus();
|
|
||||||
|
|
||||||
// Stup the greet function
|
|
||||||
window.greet = function () {
|
|
||||||
|
|
||||||
// Get name
|
|
||||||
var name = nameElement.value;
|
|
||||||
|
|
||||||
// Call Basic.Greet(name)
|
|
||||||
window.backend.main.Basic.Greet(name).then((result) => {
|
|
||||||
// Update result with data back from Basic.Greet()
|
|
||||||
document.getElementById("result").innerText = result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
window.closeme = function () {
|
|
||||||
console.log('here');
|
|
||||||
window.backend.main.Basic.Close();
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/options"
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/options/mac"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
// Create application with options
|
|
||||||
app := wails.CreateAppWithOptions(&options.App{
|
|
||||||
Title: "Frameless Demo",
|
|
||||||
Width: 1024,
|
|
||||||
Height: 768,
|
|
||||||
MinWidth: 800,
|
|
||||||
MinHeight: 600,
|
|
||||||
MaxWidth: 1280,
|
|
||||||
MaxHeight: 1024,
|
|
||||||
Mac: &mac.Options{
|
|
||||||
TitleBar: mac.TitleBarHidden(),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
app.Bind(newBasic())
|
|
||||||
|
|
||||||
app.Run()
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "frameless",
|
|
||||||
"outputfilename": "frameless",
|
|
||||||
"html": "frontend/index.html"
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Basic application struct
|
|
||||||
type Basic struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
}
|
|
||||||
|
|
||||||
// newBasic creates a new Basic application struct
|
|
||||||
func newBasic() *Basic {
|
|
||||||
return &Basic{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WailsInit is called at application startup
|
|
||||||
func (b *Basic) WailsInit(runtime *wails.Runtime) error {
|
|
||||||
// Perform your setup here
|
|
||||||
b.runtime = runtime
|
|
||||||
|
|
||||||
// Show window after 5 seconds
|
|
||||||
time.AfterFunc(5*time.Second, func() { b.runtime.Window.Show() })
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WailsShutdown is called at application termination
|
|
||||||
func (b *Basic) WailsShutdown() {
|
|
||||||
// Perform your teardown here
|
|
||||||
}
|
|
||||||
|
|
||||||
// Greet returns a greeting for the given name
|
|
||||||
func (b *Basic) Greet(name string) string {
|
|
||||||
return fmt.Sprintf("Hello %s!", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close shuts down the application
|
|
||||||
func (b *Basic) Close() {
|
|
||||||
b.runtime.Quit()
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="/main.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body data-wails-drag>
|
|
||||||
<div id="logo"></div>
|
|
||||||
<div id="input" data-wails-no-drag>
|
|
||||||
<a id="close" onclick="closeme()">X</a>
|
|
||||||
<input id="name" type="text"></input>
|
|
||||||
<button onclick="greet()">Greet</button>
|
|
||||||
</div>
|
|
||||||
<div id="result"></div>
|
|
||||||
|
|
||||||
<script src="/main.js"></script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,21 +0,0 @@
|
|||||||
// Get input + focus
|
|
||||||
var nameElement = document.getElementById("name");
|
|
||||||
nameElement.focus();
|
|
||||||
|
|
||||||
// Stup the greet function
|
|
||||||
window.greet = function () {
|
|
||||||
|
|
||||||
// Get name
|
|
||||||
var name = nameElement.value;
|
|
||||||
|
|
||||||
// Call Basic.Greet(name)
|
|
||||||
window.backend.main.Basic.Greet(name).then((result) => {
|
|
||||||
// Update result with data back from Basic.Greet()
|
|
||||||
document.getElementById("result").innerText = result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
window.closeme = function () {
|
|
||||||
console.log('here');
|
|
||||||
window.backend.main.Basic.Close();
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/options"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
// Create application with options
|
|
||||||
app := wails.CreateAppWithOptions(&options.App{
|
|
||||||
Title: "Hidden Demo",
|
|
||||||
Width: 1024,
|
|
||||||
Height: 768,
|
|
||||||
StartHidden: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
app.Bind(newBasic())
|
|
||||||
|
|
||||||
app.Run()
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "hidden",
|
|
||||||
"outputfilename": "hidden",
|
|
||||||
"html": "frontend/index.html"
|
|
||||||
}
|
|
1
v2/test/kitchensink/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
Info.plist
|
|
@ -1,59 +0,0 @@
|
|||||||
# Assets Directory
|
|
||||||
|
|
||||||
The assets directory is used to house all the assets of your application.
|
|
||||||
|
|
||||||
The structure is:
|
|
||||||
|
|
||||||
* dialog - Icons for dialogs
|
|
||||||
* tray - Icons for the system tray
|
|
||||||
* custom - A place for assets you wish to bundle in the application
|
|
||||||
* mac - MacOS specific files
|
|
||||||
* linux - Linux specific files
|
|
||||||
* windows - Windows specific files
|
|
||||||
|
|
||||||
## Dialog Icons
|
|
||||||
|
|
||||||
Place any PNG file in this directory to be able to use them in message dialogs.
|
|
||||||
The files should have names in the following format: `name[-(light|dark)][2x].png`
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
* `mypic.png` - Standard definition icon with ID `mypic`
|
|
||||||
* `mypic-light.png` - Standard definition icon with ID `mypic`, used when system theme is light
|
|
||||||
* `mypic-dark.png` - Standard definition icon with ID `mypic`, used when system theme is dark
|
|
||||||
* `mypic2x.png` - High definition icon with ID `mypic`
|
|
||||||
* `mypic-light2x.png` - High definition icon with ID `mypic`, used when system theme is light
|
|
||||||
* `mypic-dark2x.png` - High definition icon with ID `mypic`, used when system theme is dark
|
|
||||||
|
|
||||||
### Order of preference
|
|
||||||
|
|
||||||
Icons are selected with the following order of preference:
|
|
||||||
|
|
||||||
For High Definition displays:
|
|
||||||
* name-(theme)2x.png
|
|
||||||
* name2x.png
|
|
||||||
* name-(theme).png
|
|
||||||
* name.png
|
|
||||||
|
|
||||||
For Standard Definition displays:
|
|
||||||
* name-(theme).png
|
|
||||||
* name.png
|
|
||||||
|
|
||||||
## Tray
|
|
||||||
|
|
||||||
Place any PNG file in this directory to be able to use them as tray icons.
|
|
||||||
The name of the filename will be the ID to reference the image.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
* `mypic.png` - May be referenced using `runtime.Tray.SetIcon("mypic")`
|
|
||||||
|
|
||||||
## Custom
|
|
||||||
|
|
||||||
Any file in this directory will be embedded into the app using the Wails asset bundler.
|
|
||||||
Assets can be retrieved using the following methods:
|
|
||||||
|
|
||||||
* `wails.Assets().Read(filename string) ([]byte, error)`
|
|
||||||
* `wails.Assets().String(filename string) (string, error)`
|
|
||||||
|
|
||||||
The filename should include the path to the file relative to the `custom` directory.
|
|
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 2.0 KiB |
@ -1,23 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Browser struct
|
|
||||||
type Browser struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
}
|
|
||||||
|
|
||||||
// WailsInit is called at application startup
|
|
||||||
func (l *Browser) WailsInit(runtime *wails.Runtime) error {
|
|
||||||
// Perform your setup here
|
|
||||||
l.runtime = runtime
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open will open the default browser with the given target
|
|
||||||
func (l *Browser) Open(target string) error {
|
|
||||||
// Perform your setup here
|
|
||||||
return l.runtime.Browser.Open(target)
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ContextMenu struct
|
|
||||||
type ContextMenu struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
counter int
|
|
||||||
lock sync.Mutex
|
|
||||||
testContextMenu *menu.ContextMenu
|
|
||||||
clickedMenu *menu.MenuItem
|
|
||||||
}
|
|
||||||
|
|
||||||
// WailsInit is called at application startup
|
|
||||||
func (c *ContextMenu) WailsInit(runtime *wails.Runtime) error {
|
|
||||||
// Perform your setup here
|
|
||||||
c.runtime = runtime
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup Menu Listeners
|
|
||||||
func (c *ContextMenu) updateContextMenu(_ *menu.CallbackData) {
|
|
||||||
c.lock.Lock()
|
|
||||||
c.counter++
|
|
||||||
c.clickedMenu.Label = fmt.Sprintf("Clicked %d times", c.counter)
|
|
||||||
c.lock.Unlock()
|
|
||||||
c.runtime.Menu.UpdateContextMenu(c.testContextMenu)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ContextMenu) createContextMenus() []*menu.ContextMenu {
|
|
||||||
c.clickedMenu = menu.Text("Clicked 0 times", nil, c.updateContextMenu)
|
|
||||||
c.testContextMenu = menu.NewContextMenu("test", menu.NewMenuFromItems(
|
|
||||||
c.clickedMenu,
|
|
||||||
menu.Separator(),
|
|
||||||
menu.Checkbox("I am a checkbox", false, nil, nil),
|
|
||||||
menu.Separator(),
|
|
||||||
menu.Radio("Radio Option 1", true, nil, nil),
|
|
||||||
menu.Radio("Radio Option 2", false, nil, nil),
|
|
||||||
menu.Radio("Radio Option 3", false, nil, nil),
|
|
||||||
menu.Separator(),
|
|
||||||
menu.SubMenu("A Submenu", menu.NewMenuFromItems(
|
|
||||||
menu.Text("Hello", nil, nil),
|
|
||||||
)),
|
|
||||||
))
|
|
||||||
return []*menu.ContextMenu{
|
|
||||||
c.testContextMenu,
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Dialog struct
|
|
||||||
type Dialog struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
}
|
|
||||||
|
|
||||||
// WailsInit is called at application startup
|
|
||||||
func (l *Dialog) WailsInit(runtime *wails.Runtime) error {
|
|
||||||
// Perform your setup here
|
|
||||||
l.runtime = runtime
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open Dialog
|
|
||||||
func (l *Dialog) Open(options *dialog.OpenDialog) []string {
|
|
||||||
return l.runtime.Dialog.Open(options)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save Dialog
|
|
||||||
func (l *Dialog) Save(options *dialog.SaveDialog) string {
|
|
||||||
return l.runtime.Dialog.Save(options)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message Dialog
|
|
||||||
func (l *Dialog) Message(options *dialog.MessageDialog) string {
|
|
||||||
return l.runtime.Dialog.Message(options)
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Events struct
|
|
||||||
type Events struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
}
|
|
||||||
|
|
||||||
// WailsInit is called at application startup
|
|
||||||
func (e *Events) WailsInit(runtime *wails.Runtime) error {
|
|
||||||
// Perform your setup here
|
|
||||||
e.runtime = runtime
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// On will subscribe to the given event name
|
|
||||||
func (e *Events) On(eventName string) {
|
|
||||||
e.runtime.Events.On(eventName, func(args ...interface{}) {
|
|
||||||
type callbackData struct {
|
|
||||||
Name string
|
|
||||||
Data []interface{}
|
|
||||||
}
|
|
||||||
result := callbackData{Name: eventName, Data: args}
|
|
||||||
e.runtime.Events.Emit("event fired by go subscriber", result)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Once will subscribe to the given event name
|
|
||||||
func (e *Events) Once(eventName string) {
|
|
||||||
e.runtime.Events.Once(eventName, func(args ...interface{}) {
|
|
||||||
type callbackData struct {
|
|
||||||
Name string
|
|
||||||
Data []interface{}
|
|
||||||
}
|
|
||||||
result := callbackData{Name: eventName, Data: args}
|
|
||||||
e.runtime.Events.Emit("once event fired by go subscriber", result)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// OnMultiple will subscribe to the given event name, with a maximum
|
|
||||||
// set by maxCallbacks
|
|
||||||
func (e *Events) OnMultiple(eventName string, maxCallbacks int) {
|
|
||||||
e.runtime.Events.OnMultiple(eventName, func(args ...interface{}) {
|
|
||||||
type callbackData struct {
|
|
||||||
Name string
|
|
||||||
Data []interface{}
|
|
||||||
}
|
|
||||||
result := callbackData{Name: eventName, Data: args}
|
|
||||||
e.runtime.Events.Emit("onmultiple event fired by go subscriber", result)
|
|
||||||
}, maxCallbacks)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emit will emit
|
|
||||||
func (e *Events) Emit(eventName string, data []interface{}) {
|
|
||||||
e.runtime.Events.Emit(eventName, data...)
|
|
||||||
}
|
|
4
v2/test/kitchensink/frontend/.gitignore
vendored
@ -1,4 +0,0 @@
|
|||||||
/node_modules/
|
|
||||||
/public/build/
|
|
||||||
|
|
||||||
.DS_Store
|
|
@ -1,93 +0,0 @@
|
|||||||
*Looking for a shareable component template? Go here --> [sveltejs/component-template](https://github.com/sveltejs/component-template)*
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# svelte app
|
|
||||||
|
|
||||||
This is a project template for [Svelte](https://svelte.dev) apps. It lives at https://github.com/sveltejs/template.
|
|
||||||
|
|
||||||
To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx degit sveltejs/template svelte-app
|
|
||||||
cd svelte-app
|
|
||||||
```
|
|
||||||
|
|
||||||
*Note that you will need to have [Node.js](https://nodejs.org) installed.*
|
|
||||||
|
|
||||||
|
|
||||||
## Get started
|
|
||||||
|
|
||||||
Install the dependencies...
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd svelte-app
|
|
||||||
npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
...then start [Rollup](https://rollupjs.org):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
Navigate to [localhost:5000](http://localhost:5000). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes.
|
|
||||||
|
|
||||||
By default, the server will only respond to requests from localhost. To allow connections from other computers, edit the `sirv` commands in package.json to include the option `--host 0.0.0.0`.
|
|
||||||
|
|
||||||
|
|
||||||
## Building and running in production mode
|
|
||||||
|
|
||||||
To create an optimised version of the app:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
You can run the newly built app with `npm run start`. This uses [sirv](https://github.com/lukeed/sirv), which is included in your package.json's `dependencies` so that the app will work when you deploy to platforms like [Heroku](https://heroku.com).
|
|
||||||
|
|
||||||
|
|
||||||
## Single-page app mode
|
|
||||||
|
|
||||||
By default, sirv will only respond to requests that match files in `public`. This is to maximise compatibility with static fileservers, allowing you to deploy your app anywhere.
|
|
||||||
|
|
||||||
If you're building a single-page app (SPA) with multiple routes, sirv needs to be able to respond to requests for *any* path. You can make it so by editing the `"start"` command in package.json:
|
|
||||||
|
|
||||||
```js
|
|
||||||
"start": "sirv public --single"
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Deploying to the web
|
|
||||||
|
|
||||||
### With [now](https://zeit.co/now)
|
|
||||||
|
|
||||||
Install `now` if you haven't already:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install -g now
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, from within your project folder:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd public
|
|
||||||
now deploy --name my-project
|
|
||||||
```
|
|
||||||
|
|
||||||
As an alternative, use the [Now desktop client](https://zeit.co/download) and simply drag the unzipped project folder to the taskbar icon.
|
|
||||||
|
|
||||||
### With [surge](https://surge.sh/)
|
|
||||||
|
|
||||||
Install `surge` if you haven't already:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install -g surge
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, from within your project folder:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run build
|
|
||||||
surge public my-project.surge.sh
|
|
||||||
```
|
|
3541
v2/test/kitchensink/frontend/package-lock.json
generated
@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "svelte-app",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"scripts": {
|
|
||||||
"build": "rollup -c --failAfterWarnings",
|
|
||||||
"dev": "rollup -c -w --failAfterWarnings",
|
|
||||||
"start": "sirv public",
|
|
||||||
"start:dev": "sirv public --single --host 0.0.0.0 --dev"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@rollup/plugin-commonjs": "^11.0.0",
|
|
||||||
"@rollup/plugin-node-resolve": "^7.0.0",
|
|
||||||
"@rollup/plugin-url": "^5.0.1",
|
|
||||||
"@wails/runtime": "^1.2.22",
|
|
||||||
"focus-visible": "^5.2.0",
|
|
||||||
"halfmoon": "^1.1.1",
|
|
||||||
"postcss": "^8.2.2",
|
|
||||||
"postcss-import": "^12.0.1",
|
|
||||||
"rollup": "^2.35.1",
|
|
||||||
"rollup-plugin-livereload": "^1.0.0",
|
|
||||||
"rollup-plugin-postcss": "^3.1.8",
|
|
||||||
"rollup-plugin-string": "^3.0.0",
|
|
||||||
"rollup-plugin-svelte": "~6.1.1",
|
|
||||||
"rollup-plugin-terser": "^5.1.2",
|
|
||||||
"sirv-cli": "^0.4.4",
|
|
||||||
"svelte": "^3.31.0",
|
|
||||||
"svelte-highlight": "^0.6.2",
|
|
||||||
"svelte-preprocess": "^4.6.1"
|
|
||||||
},
|
|
||||||
"dependencies": {}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
plugins: [
|
|
||||||
require('postcss-import'),
|
|
||||||
],
|
|
||||||
}
|
|
Before Width: | Height: | Size: 7.9 KiB |
@ -1,24 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
||||||
<meta name="mobile-web-app-capable" content="yes" />
|
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
|
|
||||||
<meta name="apple-mobile-web-app-title" content="svelte-mui" />
|
|
||||||
<meta name="application-name" content="svelte-mui" />
|
|
||||||
<meta name="theme-color" content="#212121" />
|
|
||||||
|
|
||||||
<title>Svelte app</title>
|
|
||||||
|
|
||||||
<link rel='icon' type='image/png' href='/favicon.png'>
|
|
||||||
<link rel='stylesheet' href='/bundle.css'>
|
|
||||||
|
|
||||||
<script defer src='/bundle.js'></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<noscript>Please enable JavaScript.</noscript>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,110 +0,0 @@
|
|||||||
import svelte from 'rollup-plugin-svelte';
|
|
||||||
import resolve from '@rollup/plugin-node-resolve';
|
|
||||||
import commonjs from '@rollup/plugin-commonjs';
|
|
||||||
import livereload from 'rollup-plugin-livereload';
|
|
||||||
import { terser } from 'rollup-plugin-terser';
|
|
||||||
import postcss from 'rollup-plugin-postcss';
|
|
||||||
import autoPreprocess from 'svelte-preprocess';
|
|
||||||
import { string } from "rollup-plugin-string";
|
|
||||||
import url from '@rollup/plugin-url';
|
|
||||||
|
|
||||||
const production = !process.env.ROLLUP_WATCH;
|
|
||||||
|
|
||||||
export default {
|
|
||||||
input: 'src/main.js',
|
|
||||||
output: {
|
|
||||||
sourcemap: true,
|
|
||||||
format: 'iife',
|
|
||||||
name: 'app',
|
|
||||||
file: 'public/bundle.js'
|
|
||||||
},
|
|
||||||
onwarn: handleRollupWarning,
|
|
||||||
plugins: [
|
|
||||||
|
|
||||||
// Embed binary files
|
|
||||||
url({
|
|
||||||
include: ['**/*.woff', '**/*.woff2'],
|
|
||||||
limit: Infinity,
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Embed text files
|
|
||||||
string({
|
|
||||||
include: ["**/*.jsx","**/*.go", "**/*.txt"],
|
|
||||||
}),
|
|
||||||
|
|
||||||
svelte({
|
|
||||||
preprocess: autoPreprocess(),
|
|
||||||
// enable run-time checks when not in production
|
|
||||||
dev: !production,
|
|
||||||
// we'll extract any component CSS out into
|
|
||||||
// a separate file - better for performance
|
|
||||||
css: css => {
|
|
||||||
css.write('public/bundle.css');
|
|
||||||
},
|
|
||||||
emitCss: true,
|
|
||||||
}),
|
|
||||||
|
|
||||||
// If you have external dependencies installed from
|
|
||||||
// npm, you'll most likely need these plugins. In
|
|
||||||
// some cases you'll need additional configuration -
|
|
||||||
// consult the documentation for details:
|
|
||||||
// https://github.com/rollup/plugins/tree/master/packages/commonjs
|
|
||||||
resolve({
|
|
||||||
browser: true,
|
|
||||||
dedupe: ['svelte']
|
|
||||||
}),
|
|
||||||
commonjs(),
|
|
||||||
|
|
||||||
// PostCSS preprocessing
|
|
||||||
postcss({
|
|
||||||
extensions: ['.css', '.scss'],
|
|
||||||
extract: true,
|
|
||||||
minimize: false,
|
|
||||||
use: [
|
|
||||||
['sass', {
|
|
||||||
includePaths: [
|
|
||||||
'./src/theme',
|
|
||||||
'./node_modules'
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
|
|
||||||
// In dev mode, call `npm run start` once
|
|
||||||
// the bundle has been generated
|
|
||||||
!production && serve(),
|
|
||||||
|
|
||||||
// Watch the `public` directory and refresh the
|
|
||||||
// browser on changes when not in production
|
|
||||||
!production && livereload('public'),
|
|
||||||
|
|
||||||
// If we're building for production (npm run build
|
|
||||||
// instead of npm run dev), minify
|
|
||||||
production && terser()
|
|
||||||
],
|
|
||||||
watch: {
|
|
||||||
clearScreen: false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function handleRollupWarning(warning) {
|
|
||||||
console.error('ERROR: ' + warning.toString());
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function serve() {
|
|
||||||
let started = false;
|
|
||||||
|
|
||||||
return {
|
|
||||||
writeBundle() {
|
|
||||||
if (!started) {
|
|
||||||
started = true;
|
|
||||||
|
|
||||||
require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
|
|
||||||
stdio: ['ignore', 'inherit', 'inherit'],
|
|
||||||
shell: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,128 +0,0 @@
|
|||||||
|
|
||||||
:root {
|
|
||||||
--lm-base-body-bg-color: #0000;
|
|
||||||
--dm-base-body-bg-color: #0000;
|
|
||||||
--lm-sidebar-bg-color: #0000;
|
|
||||||
--dm-sidebar-bg-color: #0000;
|
|
||||||
--dm-sidebar-link-text-color: white;
|
|
||||||
--dm-sidebar-link-text-color-hover: rgb(255, 214, 0);
|
|
||||||
--lm-sidebar-link-text-color: black;
|
|
||||||
--lm-sidebar-link-text-color-hover: rgb(158, 158, 255);
|
|
||||||
|
|
||||||
--dm-sidebar-link-text-color-active: rgb(255, 214, 0);
|
|
||||||
--dm-sidebar-link-text-color-active-hover: rgb(255, 214, 0);
|
|
||||||
|
|
||||||
--sidebar-title-font-size: 1.75rem;
|
|
||||||
--sidebar-brand-font-size: 2.3rem;
|
|
||||||
|
|
||||||
--base-font-size: 1.5rem;
|
|
||||||
|
|
||||||
/* Switch */
|
|
||||||
--dm-switch-bg-color: rgb(28,173,213);
|
|
||||||
--lm-switch-bg-color: rgb(28,173,213);
|
|
||||||
--dm-switch-bg-color-checked: rgb(186,167,49);
|
|
||||||
--lm-switch-bg-color-checked: rgb(186,167,49);
|
|
||||||
--lm-switch-slider-bg-color: #FFF;
|
|
||||||
--dm-switch-slider-bg-color: #FFF;
|
|
||||||
|
|
||||||
--dm-base-text-color: white;
|
|
||||||
--lm-base-text-color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background-color: rgba(128,128,128,.25);
|
|
||||||
border: 2px solid transparent;
|
|
||||||
border-radius: 10px;
|
|
||||||
background-clip: padding-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(128,128,128,.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
|
||||||
background-color: rgba(128,128,128,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-link {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rhs {
|
|
||||||
background-color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner-content {
|
|
||||||
position: absolute;
|
|
||||||
top: 20px;
|
|
||||||
bottom: 20px;
|
|
||||||
width: 99%;
|
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-wrapper {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark-content-wrapper {
|
|
||||||
background-color: #25282c;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
.sidebar {
|
|
||||||
background-color: #0000;
|
|
||||||
} */
|
|
||||||
|
|
||||||
.sidebar-brand {
|
|
||||||
padding-top: 35px;
|
|
||||||
padding-bottom: 25px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-menu {
|
|
||||||
background-color: #0000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Credit: https://stackoverflow.com/a/4407335 */
|
|
||||||
.noselect {
|
|
||||||
cursor: default;
|
|
||||||
-webkit-touch-callout: none; /* iOS Safari */
|
|
||||||
-webkit-user-select: none; /* Safari */
|
|
||||||
-khtml-user-select: none; /* Konqueror HTML */
|
|
||||||
-moz-user-select: none; /* Old versions of Firefox */
|
|
||||||
-ms-user-select: none; /* Internet Explorer/Edge */
|
|
||||||
user-select: none; /* Non-prefixed version, currently
|
|
||||||
supported by Chrome, Edge, Opera and Firefox */
|
|
||||||
}
|
|
||||||
.allow-select {
|
|
||||||
-webkit-touch-callout: initial; /* iOS Safari */
|
|
||||||
-webkit-user-select: initial; /* Safari */
|
|
||||||
-khtml-user-select: initial; /* Konqueror HTML */
|
|
||||||
-moz-user-select: initial; /* Old versions of Firefox */
|
|
||||||
-ms-user-select: initial; /* Internet Explorer/Edge */
|
|
||||||
user-select: initial; /* Non-prefixed version, currently
|
|
||||||
supported by Chrome, Edge, Opera and Firefox */
|
|
||||||
}
|
|
||||||
|
|
||||||
.list {
|
|
||||||
margin-top: 1.5rem;
|
|
||||||
margin-left: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list li {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-header {
|
|
||||||
position: fixed;
|
|
||||||
top: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
|
||||||
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";
|
|
||||||
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import { darkMode, selectedPage } from './Store';
|
|
||||||
import MainPage from './MainPage.svelte';
|
|
||||||
import { Browser } from '@wails/runtime';
|
|
||||||
|
|
||||||
// Hightlight CSS
|
|
||||||
import { atomOneDark, atomOneLight } from "svelte-highlight/styles";
|
|
||||||
$: css = $darkMode ? atomOneDark : atomOneLight;
|
|
||||||
|
|
||||||
function linkClicked(event) {
|
|
||||||
let linkText = event.target.innerText;
|
|
||||||
selectedPage.set(linkText);
|
|
||||||
console.log(event.target.innerText);
|
|
||||||
}
|
|
||||||
|
|
||||||
function homepageClicked() {
|
|
||||||
selectedPage.set(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
function openSite(url) {
|
|
||||||
Browser.Open(url)
|
|
||||||
}
|
|
||||||
|
|
||||||
let runtimePages = [
|
|
||||||
'Logging',
|
|
||||||
'Events',
|
|
||||||
'Dialog',
|
|
||||||
'Browser',
|
|
||||||
'File System',
|
|
||||||
'Window',
|
|
||||||
'Tray',
|
|
||||||
'System'
|
|
||||||
];
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
{@html css}
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<div data-wails-drag class="page-wrapper with-sidebar" class:dark-mode="{$darkMode}" data-sidebar-type="full-height" >
|
|
||||||
<!-- Sticky alerts (toasts), empty container -->
|
|
||||||
<div class="sticky-alerts"></div>
|
|
||||||
<!-- Sidebar -->
|
|
||||||
<div class="sidebar noselect" data-wails-context-menu-id="test" data-wails-context-menu-data="hello!">
|
|
||||||
<div data-wails-no-drag class="sidebar-menu">
|
|
||||||
<!-- Sidebar brand -->
|
|
||||||
<div on:click="{ homepageClicked }" class="sidebar-brand">
|
|
||||||
Wails Kitchen Sink
|
|
||||||
</div>
|
|
||||||
<!-- Sidebar links and titles -->
|
|
||||||
<h5 class="sidebar-title">Runtime</h5>
|
|
||||||
<div class="sidebar-divider"></div>
|
|
||||||
{#each runtimePages as link}
|
|
||||||
<span on:click="{linkClicked}" class="sidebar-link" class:active="{$selectedPage === link}">{link}</span>
|
|
||||||
{/each}
|
|
||||||
<br />
|
|
||||||
<h5 class="sidebar-title">Links</h5>
|
|
||||||
<div class="sidebar-divider"></div>
|
|
||||||
<span on:click="{() => openSite('https://github.com/wailsapp/wails')}" class="sidebar-link">Github</span>
|
|
||||||
<span on:click="{() => openSite('https://wails.app')}" class="sidebar-link">Website</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Content wrapper -->
|
|
||||||
<div class="content-wrapper noselect" class:dark-content-wrapper="{$darkMode}">
|
|
||||||
<div class="inner-content">
|
|
||||||
<MainPage/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<style global>
|
|
||||||
@import 'halfmoon/css/halfmoon-variables.min.css';
|
|
||||||
/* @import './assets/fonts/roboto.css'; */
|
|
||||||
@import './App.css';
|
|
||||||
</style>
|
|
@ -1,43 +0,0 @@
|
|||||||
<script>
|
|
||||||
|
|
||||||
import {selectedPage} from './Store';
|
|
||||||
import TitlePage from './pages/TitlePage.svelte';
|
|
||||||
import Logging from './pages/Logging/Logging.svelte';
|
|
||||||
import Events from './pages/Events/Events.svelte';
|
|
||||||
import Browser from './pages/Browser/Browser.svelte';
|
|
||||||
import Dialog from './pages/Dialog/Dialog.svelte';
|
|
||||||
import System from './pages/System/System.svelte';
|
|
||||||
import Window from './pages/Window/Window.svelte';
|
|
||||||
import Tray from './pages/Tray/Tray.svelte';
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<h4 class="title">{$selectedPage || "" }</h4>
|
|
||||||
<div class="mainpage">
|
|
||||||
{#if $selectedPage == undefined} <TitlePage></TitlePage> {/if}
|
|
||||||
{#if $selectedPage == "Logging"} <Logging></Logging> {/if}
|
|
||||||
{#if $selectedPage == "Events"} <Events></Events> {/if}
|
|
||||||
{#if $selectedPage == "Browser"} <Browser></Browser> {/if}
|
|
||||||
{#if $selectedPage == "Dialog"} <Dialog></Dialog> {/if}
|
|
||||||
{#if $selectedPage == "System"} <System></System> {/if}
|
|
||||||
{#if $selectedPage == "Window"} <Window></Window> {/if}
|
|
||||||
{#if $selectedPage == "Tray"} <Tray></Tray> {/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.title {
|
|
||||||
position: fixed;
|
|
||||||
top: 50px;
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
.mainpage {
|
|
||||||
position: absolute;
|
|
||||||
top: 70px;
|
|
||||||
margin-left: 20px;
|
|
||||||
padding-right: 10px;
|
|
||||||
margin-top: 20px;
|
|
||||||
overflow-y: auto;
|
|
||||||
height: calc(100% - 100px);
|
|
||||||
width: calc(100% - 20px);
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,23 +0,0 @@
|
|||||||
import { writable } from 'svelte/store';
|
|
||||||
import runtime from '@wails/runtime';
|
|
||||||
|
|
||||||
export let selectedPage = writable();
|
|
||||||
|
|
||||||
export let darkMode = writable(runtime.System.DarkModeEnabled());
|
|
||||||
|
|
||||||
// Handle Dark/Light themes automatically
|
|
||||||
runtime.System.OnThemeChange( (isDarkMode) => {
|
|
||||||
darkMode.set(isDarkMode);
|
|
||||||
});
|
|
||||||
|
|
||||||
// LogLevel
|
|
||||||
// Create a svelte store for the logLevel and initialise with
|
|
||||||
// the loglevel stored in the Wails runtime
|
|
||||||
const defaultLogLevel = runtime.System.LogLevel.get();
|
|
||||||
export let logLevel = writable(defaultLogLevel);
|
|
||||||
|
|
||||||
// Bind updates to the Wails store to the Svelte Store
|
|
||||||
runtime.System.LogLevel.subscribe( (newValue) => {
|
|
||||||
logLevel.set(newValue);
|
|
||||||
})
|
|
||||||
|
|
@ -1,177 +0,0 @@
|
|||||||
|
|
||||||
<script>
|
|
||||||
import { darkMode } from '../Store';
|
|
||||||
|
|
||||||
import { Highlight } from "svelte-highlight";
|
|
||||||
import { go, javascript } from "svelte-highlight/languages";
|
|
||||||
|
|
||||||
// Default to Go
|
|
||||||
export let isJs = false;
|
|
||||||
|
|
||||||
export let title;
|
|
||||||
export let description;
|
|
||||||
|
|
||||||
// Calculate CSS to use
|
|
||||||
$: lang = isJs ? javascript : go;
|
|
||||||
|
|
||||||
// Calculate Code for code block
|
|
||||||
export let jsCode = "Hi from JS!";
|
|
||||||
export let goCode = "Hi from Go!";
|
|
||||||
$: code = isJs ? jsCode : goCode;
|
|
||||||
|
|
||||||
// Handle hiding example
|
|
||||||
let showCode = false;
|
|
||||||
|
|
||||||
function toggleExample() {
|
|
||||||
showCode = !showCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export let id = "toggle-" + Date.now().toString() + Math.random().toString();
|
|
||||||
|
|
||||||
// Handle hiding example
|
|
||||||
export let showRun = false;
|
|
||||||
|
|
||||||
function toggleRun() {
|
|
||||||
showRun = !showRun;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div data-wails-no-drag class={$darkMode ? "codeblock" : "codeblock-light"}>
|
|
||||||
<div class="header">
|
|
||||||
<span class="title">{title}</span>
|
|
||||||
<span class="toggle">
|
|
||||||
<span>Go</span>
|
|
||||||
<span class="custom-switch">
|
|
||||||
<input type="checkbox" {id} value="" bind:checked={isJs}>
|
|
||||||
<label for={id}>Javascript</label>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
{#if description}
|
|
||||||
<div class="description">{@html description}</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="run">
|
|
||||||
<div class="{showRun ? 'run-title-open' : 'run-title-closed'}" on:click="{toggleRun}">
|
|
||||||
<span class="arrow">{showRun?'▼':'▶'}</span>
|
|
||||||
Try Me!
|
|
||||||
</div>
|
|
||||||
{#if showRun}
|
|
||||||
<div class={$darkMode ? "run-content-dark" : "run-content-light"}>
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="example allow-select">
|
|
||||||
<div class="{showCode ? 'code-title-open' : 'code-title-closed'}" on:click="{toggleExample}" >
|
|
||||||
<span class="arrow">{showCode?'▼':'▶'}</span>
|
|
||||||
Example Code
|
|
||||||
</div>
|
|
||||||
{#if showCode}
|
|
||||||
<Highlight style="margin-bottom: 0" language="{lang}" {code}/>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
.arrow {
|
|
||||||
display: inline-block;
|
|
||||||
width: calc(var(--base-font-size));
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
border-bottom: 1px solid #5555;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: center;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
padding-left: 5px;
|
|
||||||
padding-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: calc(var(--base-font-size) * 1.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.code-title-open {
|
|
||||||
margin-top: 5px;
|
|
||||||
margin-bottom: -5px;
|
|
||||||
padding-left: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.code-title-closed {
|
|
||||||
margin-top: 5px;
|
|
||||||
padding-left: 5px;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.run-content-dark {
|
|
||||||
padding: 15px;
|
|
||||||
background-color: #282c34;
|
|
||||||
}
|
|
||||||
|
|
||||||
.run-content-light {
|
|
||||||
padding: 15px;
|
|
||||||
background-color: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.run-title-open {
|
|
||||||
margin-top: 5px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
padding-bottom: 0;
|
|
||||||
padding-left: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.run-title-closed {
|
|
||||||
margin-top: 5px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
padding-left: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggle {
|
|
||||||
float: right;
|
|
||||||
margin-top: 2px;
|
|
||||||
font-size: calc(var(--base-font-size) * 0.9);
|
|
||||||
}
|
|
||||||
|
|
||||||
.example {
|
|
||||||
border-top: 1px solid #5555;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-switch {
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codeblock {
|
|
||||||
/* background-color: #3F3F4B; */
|
|
||||||
border-radius: 5px;
|
|
||||||
border: 1px solid #555;
|
|
||||||
padding: 5px;
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codeblock-light {
|
|
||||||
/* background-color: #e5e5e5; */
|
|
||||||
border-radius: 5px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
padding: 5px;
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
border-top: 1px solid #5555;
|
|
||||||
margin-top: 10px;
|
|
||||||
padding-top: 5px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
@ -1,43 +0,0 @@
|
|||||||
|
|
||||||
<script>
|
|
||||||
import { darkMode } from '../Store';
|
|
||||||
|
|
||||||
import { Highlight } from "svelte-highlight";
|
|
||||||
import { go, javascript } from "svelte-highlight/languages";
|
|
||||||
|
|
||||||
// Default to Go
|
|
||||||
export let isJs = false;
|
|
||||||
|
|
||||||
// Calculate CSS to use
|
|
||||||
$: lang = isJs ? javascript : go;
|
|
||||||
|
|
||||||
// Calculate Code for code block
|
|
||||||
export let jsCode = "Hi from JS!";
|
|
||||||
export let goCode = "Hi from Go!";
|
|
||||||
$: code = isJs ? jsCode : goCode;
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div data-wails-no-drag class="allow-select {$darkMode ? 'codeblock' : 'codeblock-light'}">
|
|
||||||
<Highlight language="{lang}" {code} style="margin: -5px;"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
.codeblock {
|
|
||||||
background-color: #3F3F4B;
|
|
||||||
border: 1px solid #555;
|
|
||||||
padding: 5px;
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codeblock-light {
|
|
||||||
background-color: #e5e5e5;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
padding: 5px;
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
@ -1,55 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { afterUpdate } from 'svelte';
|
|
||||||
|
|
||||||
import { darkMode } from '../Store';
|
|
||||||
|
|
||||||
$: termClass = $darkMode ? 'faketerm-dark' : 'faketerm-light';
|
|
||||||
|
|
||||||
let termElement;
|
|
||||||
|
|
||||||
afterUpdate( () => {
|
|
||||||
termElement.scrollTop = termElement.scrollHeight;
|
|
||||||
});
|
|
||||||
|
|
||||||
export let text = "";
|
|
||||||
export let style = null;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div bind:this={termElement} class="common {termClass}" {style}>
|
|
||||||
<pre>
|
|
||||||
{#if text && text.length > 0}
|
|
||||||
{text}
|
|
||||||
{:else}
|
|
||||||
<slot></slot>
|
|
||||||
{/if}
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
pre {
|
|
||||||
margin: 0;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.common {
|
|
||||||
font-family: 'Courier New', Courier, monospace;
|
|
||||||
padding: 5px;
|
|
||||||
white-space: pre-line;
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
border: 1px solid #5555;
|
|
||||||
overflow-y: auto;
|
|
||||||
overflow-wrap: break-word;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.faketerm-dark {
|
|
||||||
background-color: black;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.faketerm-light {
|
|
||||||
background-color: #ddd;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,37 +0,0 @@
|
|||||||
<script>
|
|
||||||
import runtime from '@wails/runtime';
|
|
||||||
import { darkMode } from '../Store';
|
|
||||||
|
|
||||||
export let href;
|
|
||||||
|
|
||||||
$: linkclass = darkMode ? 'dark' : 'light';
|
|
||||||
|
|
||||||
function openLink() {
|
|
||||||
runtime.Browser.Open(href);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<span class="link {linkclass}" on:click="{openLink}"><slot></slot></span>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
.link {
|
|
||||||
text-decoration: underline;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link.dark:hover {
|
|
||||||
color: #ff8bfb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link.dark {
|
|
||||||
color: #ff8bfb88;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link.light {
|
|
||||||
color: #5c5cff;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
|
@ -1,10 +0,0 @@
|
|||||||
import App from './App.svelte';
|
|
||||||
|
|
||||||
const app = new App({
|
|
||||||
target: document.body,
|
|
||||||
props: {
|
|
||||||
name: 'Wails User'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default app;
|
|
@ -1,17 +0,0 @@
|
|||||||
<script>
|
|
||||||
import Link from '../../components/Link.svelte';
|
|
||||||
import Browser from './Browser/Browser.svelte';
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<div>
|
|
||||||
Sometimes it is necessary to redirect users to external websites. The Wails runtime offers this ability through the <code>runtime.Browser</code> component.
|
|
||||||
|
|
||||||
By using <code>runtime.Browser.Open</code>, it is possible to open the user's default browser to either navigate to a url (pass in a URL), or open a local file (provide a local filepath).
|
|
||||||
|
|
||||||
<Link href="https://wails.app">Here</Link> is an example.
|
|
||||||
|
|
||||||
<br/><br/>
|
|
||||||
|
|
||||||
<Browser/>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { Browser } from '@wails/runtime';
|
|
||||||
import CodeBlock from '../../../components/CodeBlock.svelte';
|
|
||||||
import CodeSnippet from '../../../components/CodeSnippet.svelte';
|
|
||||||
import jsCode from './code.jsx';
|
|
||||||
import goCode from './code.go';
|
|
||||||
|
|
||||||
var isJs = false;
|
|
||||||
$: lang = isJs ? 'Javascript' : 'Go';
|
|
||||||
var id = "Browser";
|
|
||||||
|
|
||||||
var userInput = "";
|
|
||||||
|
|
||||||
function processOpen() {
|
|
||||||
if( userInput.length > 0 ) {
|
|
||||||
if( isJs ) {
|
|
||||||
Browser.Open(userInput)
|
|
||||||
} else {
|
|
||||||
backend.main.Browser.Open(userInput)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: encodedMessage = userInput.replace(`"`, `\"`);
|
|
||||||
$: testcodeJs = "import { runtime } from '@wails/runtime';\nruntime.Browser.Open(`" + encodedMessage + "`);";
|
|
||||||
$: testcodeGo = '// runtime is given through WailsInit()\nruntime.Browser.Open("' + encodedMessage + '")';
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<CodeBlock bind:isJs={isJs} {jsCode} {goCode} title="Open" {id} showRun=true>
|
|
||||||
<div class="browser-form">
|
|
||||||
<form data-wails-no-drag class="mw-full">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="{id}-userInput" class="required">Enter Filename or URL</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-userInput" placeholder="https://www.duckduckgo.com" bind:value="{userInput}" required="required">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input class="btn btn-primary" type="button" on:click="{processOpen}" value="Open using {lang} runtime">
|
|
||||||
|
|
||||||
<CodeSnippet bind:isJs={isJs} jsCode={testcodeJs} goCode={testcodeGo}/>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</CodeBlock>
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import "github.com/wailsapp/wails/v2"
|
|
||||||
|
|
||||||
type MyStruct struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *MyStruct) ShowHelp() {
|
|
||||||
l.runtime.Browser.Open("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
import { Browser } from '@wails/runtime';
|
|
||||||
|
|
||||||
function showHelp() {
|
|
||||||
// Do some things
|
|
||||||
Browser.Open("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
<script>
|
|
||||||
import Open from './Open/Open.svelte';
|
|
||||||
import Save from './Save/Save.svelte';
|
|
||||||
import Message from "./Message/Message.svelte";
|
|
||||||
</script>
|
|
||||||
<div>
|
|
||||||
Sometimes there is a need to prompt the user for input. Dialogs are a good approach to this and Wails provides access to native dialogs. The dialog types supported are:
|
|
||||||
|
|
||||||
<ul class="list">
|
|
||||||
<li>Open - Prompts the user to select one or more files or folders</li>
|
|
||||||
<li>Save - Prompts the user to select a file or input a filename</li>
|
|
||||||
<li>Message - Prompts the user with information and optionally provides action buttons</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<br/><br/>
|
|
||||||
|
|
||||||
<Open/>
|
|
||||||
<br/>
|
|
||||||
<Save/>
|
|
||||||
<br/>
|
|
||||||
<Message/>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,159 +0,0 @@
|
|||||||
<script>
|
|
||||||
import {Dialog} from '@wails/runtime';
|
|
||||||
import CodeBlock from '../../../components/CodeBlock.svelte';
|
|
||||||
import CodeSnippet from '../../../components/CodeSnippet.svelte';
|
|
||||||
import jsCode from './code.jsx';
|
|
||||||
import goCode from './code.go';
|
|
||||||
|
|
||||||
let isJs = false;
|
|
||||||
$: lang = isJs ? 'Javascript' : 'Go';
|
|
||||||
let id = "MessageDialog";
|
|
||||||
|
|
||||||
let options = {
|
|
||||||
"Type": "info",
|
|
||||||
"Title": "",
|
|
||||||
"Message": "",
|
|
||||||
"Buttons": [],
|
|
||||||
"DefaultButton": "",
|
|
||||||
"CancelButton": "",
|
|
||||||
"Icon": "",
|
|
||||||
}
|
|
||||||
|
|
||||||
function processMessage() {
|
|
||||||
if( isJs ) {
|
|
||||||
console.log(options);
|
|
||||||
Dialog.Message(options);
|
|
||||||
} else {
|
|
||||||
backend.main.Dialog.Message(options).then( (result) => {
|
|
||||||
console.log(result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function prettyPrintArray(json) {
|
|
||||||
if (typeof json === 'string') {
|
|
||||||
json = JSON.parse(json);
|
|
||||||
}
|
|
||||||
return JSON.stringify(json, function (k, v) {
|
|
||||||
if (v instanceof Array)
|
|
||||||
return JSON.stringify(v);
|
|
||||||
return v;
|
|
||||||
}, 2).replace(/\\/g, '')
|
|
||||||
.replace(/"\[/g, '[')
|
|
||||||
.replace(/]"/g, ']')
|
|
||||||
.replace(/"{/g, '{')
|
|
||||||
.replace(/}"/g, '}');
|
|
||||||
}
|
|
||||||
|
|
||||||
let dialogTypes = ["Info", "Warning", "Error", "Question"];
|
|
||||||
let dialogTypeSelected = dialogTypes[0];
|
|
||||||
let buttonInputs = ["","","",""];
|
|
||||||
|
|
||||||
// Keep buttons in sync
|
|
||||||
$: {
|
|
||||||
options.Buttons = [];
|
|
||||||
buttonInputs.forEach( (button) => {
|
|
||||||
if ( button.length > 0 ) {
|
|
||||||
options.Buttons.push(button);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep options in sync with dialog type selected
|
|
||||||
$: options.Type = dialogTypeSelected.toLowerCase();
|
|
||||||
|
|
||||||
// Inspired by: https://stackoverflow.com/a/54931396
|
|
||||||
$: encodedJSOptions = JSON.stringify(options, function (k, v) {
|
|
||||||
if (v instanceof Array)
|
|
||||||
return JSON.stringify(v);
|
|
||||||
return v;
|
|
||||||
}, 4)
|
|
||||||
.replace(/\\/g, '')
|
|
||||||
.replace(/"\[/g, '[')
|
|
||||||
.replace(/]"/g, ']')
|
|
||||||
.replace(/"{/g, '{')
|
|
||||||
.replace(/}"/g, '}');
|
|
||||||
|
|
||||||
$: encodedGoOptions = encodedJSOptions
|
|
||||||
.replace(/ {2}"(.*)":/mg, " $1:")
|
|
||||||
.replace(/Type: "(.*)"/mg, "Type: options." + dialogTypeSelected + "Dialog")
|
|
||||||
.replace(/Buttons: \[(.*)],/mg, "Buttons: []string{$1},")
|
|
||||||
.replace(/\n}/, ",\n}");
|
|
||||||
|
|
||||||
$: testcodeJs = "import { Dialog } from '@wails/runtime';\n\nDialog.Message(" + encodedJSOptions + ");";
|
|
||||||
$: testcodeGo = '// runtime is given through WailsInit()\nimport "github.com/wailsapp/wails/v2/pkg/options"\n\nselectedFiles := runtime.Dialog.Message( &options.MessageDialog' + encodedGoOptions + ')';
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<CodeBlock bind:isJs={isJs} {jsCode} {goCode} title="Message" {id} showRun=true>
|
|
||||||
<div class="browser-form">
|
|
||||||
<form data-wails-no-drag class="mw-full">
|
|
||||||
<div class="form-row row-eq-spacing-sm">
|
|
||||||
<div class="form-group">
|
|
||||||
<div>Dialog Type</div>
|
|
||||||
{#each dialogTypes as option}
|
|
||||||
<div class="custom-radio">
|
|
||||||
<input type="radio" name="dialogType" bind:group="{dialogTypeSelected}" id="{id}-{option}" value="{option}">
|
|
||||||
<label for="{id}-{option}">{option}</label>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-row row-eq-spacing-sm">
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-Title">Title</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-Title" bind:value="{options.Title}">
|
|
||||||
<div class="form-text"> The title for the dialog </div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-Message">Message</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-Message" bind:value="{options.Message}">
|
|
||||||
<div class="form-text"> The dialog message </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-row row-eq-spacing-sm">
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-Button1">Button 1</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-Button1" bind:value="{buttonInputs[0]}">
|
|
||||||
</div>
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-Button2">Button 2</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-Button2" bind:value="{buttonInputs[1]}">
|
|
||||||
</div>
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-Button3">Button 3</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-Button3" bind:value="{buttonInputs[2]}">
|
|
||||||
</div>
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-Button4">Button 4</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-Button4" bind:value="{buttonInputs[3]}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-row row-eq-spacing-sm">
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-DefaultButton">Default Button</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-DefaultButton" bind:value="{options.DefaultButton}">
|
|
||||||
<div class="form-text"> The button that is the default option</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-CancelButton">Cancel Button</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-CancelButton" bind:value="{options.CancelButton}">
|
|
||||||
<div class="form-text"> The button that is the cancel option </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-row row-eq-spacing-sm">
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-Icon">Icon</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-Icon" bind:value="{options.Icon}">
|
|
||||||
<div class="form-text"> The icon to use in the dialog </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input class="btn btn-primary" type="button" on:click="{processMessage}" value="Show message dialog using {lang} runtime">
|
|
||||||
|
|
||||||
<CodeSnippet bind:isJs={isJs} jsCode={testcodeJs} goCode={testcodeGo}/>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</CodeBlock>
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
|
||||||
"io/ioutil"
|
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Notepad struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Notepad) WailsInit(runtime *wails.Runtime) error {
|
|
||||||
n.runtime = runtime
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SaveNotes attempts to save the given notes to disk.
|
|
||||||
// Returns false if the user cancelled the save, true on
|
|
||||||
// successful save.
|
|
||||||
func (n *Notepad) SaveNotes(notes string) (bool, error) {
|
|
||||||
|
|
||||||
selectedFile := n.runtime.Dialog.Save(&dialog.SaveDialog{
|
|
||||||
DefaultFilename: "notes.md",
|
|
||||||
Filters: "*.md",
|
|
||||||
})
|
|
||||||
|
|
||||||
// Check if the user pressed cancel
|
|
||||||
if selectedFile == "" {
|
|
||||||
// Cancelled
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save notes
|
|
||||||
err := ioutil.WriteFile(selectedFile, []byte(notes), 0700)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
import { Dialog } from '@wails/runtime';
|
|
||||||
|
|
||||||
let notes = "";
|
|
||||||
|
|
||||||
function saveNotes() {
|
|
||||||
// Prompt the user to select a single file
|
|
||||||
let filename = Dialog.Save({
|
|
||||||
"DefaultFilename": "notes.md",
|
|
||||||
"Filters": "*.md",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Do something with the file
|
|
||||||
backend.main.SaveNotes(filename, notes).then( (result) => {
|
|
||||||
if ( !result ) {
|
|
||||||
// Cancelled
|
|
||||||
return
|
|
||||||
}
|
|
||||||
showMessage('Notes saved!');
|
|
||||||
}).catch( (err) => {
|
|
||||||
// Show an alert
|
|
||||||
showAlert(err);
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,102 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { Dialog } from '@wails/runtime';
|
|
||||||
import CodeBlock from '../../../components/CodeBlock.svelte';
|
|
||||||
import CodeSnippet from '../../../components/CodeSnippet.svelte';
|
|
||||||
import jsCode from './code.jsx';
|
|
||||||
import goCode from './code.go';
|
|
||||||
|
|
||||||
var isJs = false;
|
|
||||||
$: lang = isJs ? 'Javascript' : 'Go';
|
|
||||||
var id = "OpenDialog";
|
|
||||||
|
|
||||||
let options = {
|
|
||||||
"DefaultDirectory": "",
|
|
||||||
"DefaultFilename": "",
|
|
||||||
"Title": "",
|
|
||||||
"Filters": "",
|
|
||||||
"AllowFiles": false,
|
|
||||||
"AllowDirectories": false,
|
|
||||||
"AllowMultiple": false,
|
|
||||||
"ShowHiddenFiles": false,
|
|
||||||
"CanCreateDirectories": false,
|
|
||||||
"ResolvesAliases": false,
|
|
||||||
"TreatPackagesAsDirectories": false
|
|
||||||
}
|
|
||||||
|
|
||||||
function processOpen() {
|
|
||||||
if( isJs ) {
|
|
||||||
console.log(options);
|
|
||||||
Dialog.Open(options);
|
|
||||||
} else {
|
|
||||||
backend.main.Dialog.Open(options).then( (result) => {
|
|
||||||
console.log(result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: encodedJSOptions = JSON.stringify(options, null, " ");
|
|
||||||
$: encodedGoOptions = encodedJSOptions
|
|
||||||
.replace(/\ {2}"(.*)":/mg, " $1:")
|
|
||||||
.replace(/\n}/, ",\n}");
|
|
||||||
|
|
||||||
$: testcodeJs = "import { runtime } from '@wails/runtime';\nruntime.Dialog.Open(" + encodedJSOptions + ");";
|
|
||||||
$: testcodeGo = '// runtime is given through WailsInit()\nimport "github.com/wailsapp/wails/v2/pkg/options"\n\nselectedFiles := runtime.Dialog.Open( &options.OpenDialog' + encodedGoOptions + ')';
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<CodeBlock bind:isJs={isJs} {jsCode} {goCode} title="Open" {id} showRun=true>
|
|
||||||
<div class="browser-form">
|
|
||||||
<form data-wails-no-drag class="mw-full">
|
|
||||||
<div class="form-row row-eq-spacing-sm">
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-Title">Title</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-Title" bind:value="{options.Title}">
|
|
||||||
<div class="form-text"> The title for the dialog </div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-defaultDirectory">Default Directory</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-defaultDirectory" bind:value="{options.DefaultDirectory}">
|
|
||||||
<div class="form-text"> The directory the dialog will default to </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-row row-eq-spacing-sm">
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-defaultFilename">Default Filename</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-defaultFilename" bind:value="{options.DefaultFilename}">
|
|
||||||
<div class="form-text"> The filename the dialog will suggest to use </div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-Filters">Filters</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-Filters" bind:value="{options.Filters}">
|
|
||||||
<div class="form-text"> A list of extensions eg <code>*.jpg,*.jpeg</code> </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-row row-eq-spacing-sm">
|
|
||||||
<div class="col-sm">
|
|
||||||
<input type="checkbox" id="{id}-AllowFiles" bind:checked="{options.AllowFiles}">
|
|
||||||
<label for="{id}-AllowFiles">Allow files to be selected</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm">
|
|
||||||
<input type="checkbox" id="{id}-AllowDirectories" bind:checked="{options.AllowDirectories}">
|
|
||||||
<label for="{id}-AllowDirectories">Allow directories to be selected</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-row row-eq-spacing-sm">
|
|
||||||
<div class="col-sm">
|
|
||||||
<input type="checkbox" id="{id}-AllowMultiple" bind:checked="{options.AllowMultiple}">
|
|
||||||
<label for="{id}-AllowMultiple">Allow multiple selection</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm">
|
|
||||||
<input type="checkbox" id="{id}-CanCreateDirectories" bind:checked="{options.CanCreateDirectories}">
|
|
||||||
<label for="{id}-CanCreateDirectories">Can create directories</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input class="btn btn-primary" type="button" on:click="{processOpen}" value="Open using {lang} runtime">
|
|
||||||
|
|
||||||
<CodeSnippet bind:isJs={isJs} jsCode={testcodeJs} goCode={testcodeGo}></CodeSnippet>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</CodeBlock>
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
|
||||||
"io/ioutil"
|
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Notepad struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Notepad) WailsInit(runtime *wails.Runtime) error {
|
|
||||||
n.runtime = runtime
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Notepad) LoadNotes() (string, error) {
|
|
||||||
|
|
||||||
selectedFiles := n.runtime.Dialog.Open(&dialog.OpenDialog{
|
|
||||||
DefaultFilename: "notes.md",
|
|
||||||
Filters: "*.md",
|
|
||||||
AllowFiles: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
// selectedFiles is a string slice. Get the first selection
|
|
||||||
if len(selectedFiles) == 0 {
|
|
||||||
// Cancelled
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load notes
|
|
||||||
noteData, err := ioutil.ReadFile(selectedFiles[0])
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(noteData), nil
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
import { Dialog } from '@wails/runtime';
|
|
||||||
|
|
||||||
let notes = "";
|
|
||||||
|
|
||||||
function loadNotes() {
|
|
||||||
// Prompt the user to select a single file
|
|
||||||
let filename = Dialog.Open({
|
|
||||||
"DefaultFilename": "notes.md",
|
|
||||||
"Filters": "*.md",
|
|
||||||
"AllowFiles": true,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Do something with the file
|
|
||||||
backend.main.LoadNotes(filename).then( (result) => {
|
|
||||||
if (result.length == 0) {
|
|
||||||
// Cancelled
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// We only prompted for a single file
|
|
||||||
notes = result[0];
|
|
||||||
}).catch( (err) => {
|
|
||||||
// Show an alert
|
|
||||||
showAlert(err);
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { Dialog } from '@wails/runtime';
|
|
||||||
import CodeBlock from '../../../components/CodeBlock.svelte';
|
|
||||||
import CodeSnippet from '../../../components/CodeSnippet.svelte';
|
|
||||||
import jsCode from './code.jsx';
|
|
||||||
import goCode from './code.go';
|
|
||||||
|
|
||||||
var isJs = false;
|
|
||||||
$: lang = isJs ? 'Javascript' : 'Go';
|
|
||||||
var id = "SaveDialog";
|
|
||||||
|
|
||||||
let options = {
|
|
||||||
"DefaultDirectory": "",
|
|
||||||
"DefaultFilename": "",
|
|
||||||
"Title": "",
|
|
||||||
"Filters": "",
|
|
||||||
"ShowHiddenFiles": false,
|
|
||||||
"CanCreateDirectories": false,
|
|
||||||
"TreatPackagesAsDirectories": false
|
|
||||||
}
|
|
||||||
|
|
||||||
function processSave() {
|
|
||||||
if( isJs ) {
|
|
||||||
console.log(options);
|
|
||||||
Dialog.Save(options);
|
|
||||||
} else {
|
|
||||||
backend.main.Dialog.Save(options).then( (result) => {
|
|
||||||
console.log(result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: encodedJSOptions = JSON.stringify(options, null, " ");
|
|
||||||
$: encodedGoOptions = encodedJSOptions
|
|
||||||
.replace(/\ {2}"(.*)":/mg, " $1:")
|
|
||||||
.replace(/\n}/, ",\n}");
|
|
||||||
|
|
||||||
$: testcodeJs = "import { runtime } from '@wails/runtime';\nruntime.Dialog.Save(" + encodedJSOptions + ");";
|
|
||||||
$: testcodeGo = '// runtime is given through WailsInit()\nimport "github.com/wailsapp/wails/v2/pkg/options"\n\nselectedFiles := runtime.Dialog.Save( &options.SaveDialog' + encodedGoOptions + ')';
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<CodeBlock bind:isJs={isJs} {jsCode} {goCode} title="Save" {id} showRun=true>
|
|
||||||
<div class="browser-form">
|
|
||||||
<form data-wails-no-drag class="mw-full">
|
|
||||||
<div class="form-row row-eq-spacing-sm">
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-Title">Title</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-Title" bind:value="{options.Title}">
|
|
||||||
<div class="form-text"> The title for the dialog </div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-defaultDirectory">Default Directory</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-defaultDirectory" bind:value="{options.DefaultDirectory}">
|
|
||||||
<div class="form-text"> The directory the dialog will default to </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-row row-eq-spacing-sm">
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-defaultFilename">Default Filename</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-defaultFilename" bind:value="{options.DefaultFilename}">
|
|
||||||
<div class="form-text"> The filename the dialog will suggest to use </div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm">
|
|
||||||
<label for="{id}-Filters">Filters</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-Filters" bind:value="{options.Filters}">
|
|
||||||
<div class="form-text"> A list of extensions eg <code>*.jpg,*.jpeg</code> </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-row row-eq-spacing-sm">
|
|
||||||
<div class="col-sm">
|
|
||||||
<input type="checkbox" id="{id}-CanCreateDirectories" bind:checked="{options.CanCreateDirectories}">
|
|
||||||
<label for="{id}-CanCreateDirectories">Can create directories</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input class="btn btn-primary" type="button" on:click="{processSave}" value="Save using {lang} runtime">
|
|
||||||
|
|
||||||
<CodeSnippet bind:isJs={isJs} jsCode={testcodeJs} goCode={testcodeGo}></CodeSnippet>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</CodeBlock>
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
|
||||||
"io/ioutil"
|
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Notepad struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Notepad) WailsInit(runtime *wails.Runtime) error {
|
|
||||||
n.runtime = runtime
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SaveNotes attempts to save the given notes to disk.
|
|
||||||
// Returns false if the user cancelled the save, true on
|
|
||||||
// successful save.
|
|
||||||
func (n *Notepad) SaveNotes(notes string) (bool, error) {
|
|
||||||
|
|
||||||
selectedFile := n.runtime.Dialog.Save(&dialog.SaveDialog{
|
|
||||||
DefaultFilename: "notes.md",
|
|
||||||
Filters: "*.md",
|
|
||||||
})
|
|
||||||
|
|
||||||
// Check if the user pressed cancel
|
|
||||||
if selectedFile == "" {
|
|
||||||
// Cancelled
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save notes
|
|
||||||
err := ioutil.WriteFile(selectedFile, []byte(notes), 0700)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
import { Dialog } from '@wails/runtime';
|
|
||||||
|
|
||||||
let notes = "";
|
|
||||||
|
|
||||||
function saveNotes() {
|
|
||||||
// Prompt the user to select a single file
|
|
||||||
let filename = Dialog.Save({
|
|
||||||
"DefaultFilename": "notes.md",
|
|
||||||
"Filters": "*.md",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Do something with the file
|
|
||||||
backend.main.SaveNotes(filename, notes).then( (result) => {
|
|
||||||
if ( !result ) {
|
|
||||||
// Cancelled
|
|
||||||
return
|
|
||||||
}
|
|
||||||
showMessage('Notes saved!');
|
|
||||||
}).catch( (err) => {
|
|
||||||
// Show an alert
|
|
||||||
showAlert(err);
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { Log } from '@wails/runtime';
|
|
||||||
import CodeBlock from '../../../components/CodeBlock.svelte';
|
|
||||||
import CodeSnippet from '../../../components/CodeSnippet.svelte';
|
|
||||||
import jsCode from './code.jsx';
|
|
||||||
import goCode from './code.go';
|
|
||||||
|
|
||||||
import { logLevel } from '../../../Store';
|
|
||||||
|
|
||||||
var message = '';
|
|
||||||
var isJs = false;
|
|
||||||
|
|
||||||
const loglevels = ["Trace", "Debug", "Info", "Warning", "Error", "Fatal", "Print"];
|
|
||||||
var loglevel = loglevels[0];
|
|
||||||
|
|
||||||
$: lang = isJs ? 'Javascript' : 'Go';
|
|
||||||
|
|
||||||
var id = "Logging";
|
|
||||||
|
|
||||||
function sendLogMessage() {
|
|
||||||
if( message.length > 0 ) {
|
|
||||||
if( isJs ) {
|
|
||||||
// Call JS runtime
|
|
||||||
Log[loglevel](message);
|
|
||||||
} else {
|
|
||||||
// Call Go method which calls Go Runtime
|
|
||||||
backend.main.Logger[loglevel](message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: encodedMessage = message.replace(`"`, `\"`);
|
|
||||||
$: testcodeJs = "import { runtime } from '@wails/runtime';\nruntime.Log." + loglevel + "(`" + encodedMessage + "`);";
|
|
||||||
$: testcodeGo = '// runtime is given through WailsInit()\nruntime.Log.' + loglevel + '("' + encodedMessage + '")';
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<CodeBlock bind:isJs={isJs} {jsCode} {goCode} title="Logging" {id}>
|
|
||||||
<div class="logging-form">
|
|
||||||
<form data-wails-no-drag class="mw-full">
|
|
||||||
<div class="form-group">
|
|
||||||
<div>Select Log Method</div>
|
|
||||||
{#each loglevels as option, index}
|
|
||||||
{#if (index + 1) === $logLevel}
|
|
||||||
<span style="margin-top: 5px; height: 20px; display: inline-block;"><hr style="width: 270px;display: inline-block; vertical-align: middle; margin-right: 10px"/> Current Log Level </span>
|
|
||||||
{/if}
|
|
||||||
<div class="custom-radio">
|
|
||||||
<input type="radio" name="logging" bind:group="{loglevel}" id="{id}-{option}" value="{option}">
|
|
||||||
<label for="{id}-{option}">{option}</label>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="{id}-message" class="required">Message</label>
|
|
||||||
<input type="text" class="form-control" id="{id}-message" placeholder="Hello World!" bind:value="{message}" required="required">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input class="btn btn-primary" type="button" on:click="{sendLogMessage}" value="Log using {lang} runtime">
|
|
||||||
|
|
||||||
<CodeSnippet bind:isJs={isJs} jsCode={testcodeJs} goCode={testcodeGo}/>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</CodeBlock>
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import "github.com/wailsapp/wails/v2"
|
|
||||||
|
|
||||||
type MyStruct struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *MyStruct) WailsInit(runtime *wails.Runtime) error {
|
|
||||||
|
|
||||||
message := "Hello World!"
|
|
||||||
runtime.Log.Print(message)
|
|
||||||
// runtime.Log.Trace(message)
|
|
||||||
// runtime.Log.Debug(message)
|
|
||||||
// runtime.Log.Info(message)
|
|
||||||
// runtime.Log.Warning(message)
|
|
||||||
// runtime.Log.Error(message)
|
|
||||||
// runtime.Log.Fatal(message)
|
|
||||||
|
|
||||||
l.runtime = runtime
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
import { Log } from '@wails/runtime';
|
|
||||||
|
|
||||||
function doSomeOperation() {
|
|
||||||
// Do things
|
|
||||||
let value = doSomething();
|
|
||||||
Log.Print("A raw message");
|
|
||||||
Log.Trace("I got: " + value);
|
|
||||||
Log.Debug("A debug message");
|
|
||||||
Log.Info("An Info message");
|
|
||||||
Log.Warning("A Warning message");
|
|
||||||
Log.Error("An Error message");
|
|
||||||
}
|
|
||||||
|
|
||||||
function abort() {
|
|
||||||
// Do some things
|
|
||||||
Log.Fatal("I accidentally the whole application!");
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
<script>
|
|
||||||
import FakeTerm from '../../components/FakeTerm.svelte';
|
|
||||||
import Link from '../../components/Link.svelte';
|
|
||||||
import Log from './Log/Log.svelte';
|
|
||||||
import SetLogLevel from './SetLogLevel/SetLogLevel.svelte';
|
|
||||||
|
|
||||||
const loglevels = ["Trace", "Debug", "Info", "Warning", "Error", "Fatal", "Print"];
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<div>
|
|
||||||
Logging is part of the Wails Runtime and is accessed through the <code>runtime.Log</code> object.
|
|
||||||
|
|
||||||
There are {loglevels.length} methods available:
|
|
||||||
|
|
||||||
<ol class="list">
|
|
||||||
{#each loglevels as option}
|
|
||||||
<li>{option}</li>
|
|
||||||
{/each}
|
|
||||||
</ol>
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
Logs are only output if they are above or equal to the current log level. Example: If the current log level is
|
|
||||||
<code>Info</code>, then <code>Trace</code> and <code>Debug</code> messages will be surpressed. <br/><br/>
|
|
||||||
<code>Fatal</code> will log the message and then immediately exit the program.<br/><br/>
|
|
||||||
<code>Print</code> will send a raw message to the log regardless of log level.<br/><br/>
|
|
||||||
|
|
||||||
The default logger will log messages to the console in the following format:<br/>
|
|
||||||
<FakeTerm>
|
|
||||||
TRACE | I am a Trace message
|
|
||||||
DEBUG | I am a Debug message
|
|
||||||
INFO | I am an Info message
|
|
||||||
WARN | I am a Warning message
|
|
||||||
ERROR | I am an Error message
|
|
||||||
FATAL | I am a Fatal message
|
|
||||||
I am a Print message
|
|
||||||
</FakeTerm>
|
|
||||||
<br/>
|
|
||||||
Custom loggers may be given to your Wails application. More details <Link href="https://wails.app">here</Link>.
|
|
||||||
|
|
||||||
<br/><br/>
|
|
||||||
|
|
||||||
<Log/>
|
|
||||||
<br/>
|
|
||||||
<SetLogLevel/>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
|||||||
<script>
|
|
||||||
import CodeBlock from '../../../components/CodeBlock.svelte';
|
|
||||||
import CodeSnippet from '../../../components/CodeSnippet.svelte';
|
|
||||||
import { logLevel } from '../../../Store';
|
|
||||||
|
|
||||||
import { Log } from '@wails/runtime';
|
|
||||||
|
|
||||||
import jsCode from './code.jsx';
|
|
||||||
import goCode from './code.go';
|
|
||||||
|
|
||||||
var options = ["Trace", "Debug", "Info", "Warning", "Error"];
|
|
||||||
let isJs = false;
|
|
||||||
var id = "SetLogLevel";
|
|
||||||
let loglevelText = options[$logLevel-1];
|
|
||||||
|
|
||||||
$: setLogLevelMethod = isJs ? Log.SetLogLevel : backend.main.Logger.SetLogLevel;
|
|
||||||
|
|
||||||
function setLogLevel() {
|
|
||||||
let logLevelUpper = loglevelText.toUpperCase();
|
|
||||||
let logLevelMethod = Log.Level[logLevelUpper];
|
|
||||||
setLogLevelMethod(logLevelMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
$: lang = isJs ? 'Javascript' : 'Go';
|
|
||||||
|
|
||||||
let description = `You can set the log level using Log.SetLogLevel(). It accepts a log level (number) but there are consts available which may be used. See example code for more details.`;
|
|
||||||
$: testcodeJs = "import { Log } from '@wails/runtime';\nLog.SetLogLevel(Log.Level." + loglevelText.toUpperCase() + ");";
|
|
||||||
$: testcodeGo = 'import "github.com/wailsapp/wails/v2/pkg/logger"\n\n// runtime is given through WailsInit()\nruntime.Log.SetLogLevel(logger.' + loglevelText.toUpperCase() + ')';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<CodeBlock bind:isJs={isJs} {jsCode} {goCode} title="SetLogLevel" {id} {description}>
|
|
||||||
<div class="logging-form">
|
|
||||||
<form data-wails-no-drag class="mw-full">
|
|
||||||
<!-- Radio -->
|
|
||||||
<div class="form-group">
|
|
||||||
<div>Select Logging Level</div>
|
|
||||||
{#each options as option}
|
|
||||||
<div class="custom-radio">
|
|
||||||
<input type="radio" name="logging" bind:group="{loglevelText}" id="{id}-{option}" value="{option}">
|
|
||||||
<label for="{id}-{option}">{option}</label>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
<input class="btn btn-primary" type="button" on:click="{setLogLevel}" value="SetLogLevel using {lang} runtime">
|
|
||||||
<CodeSnippet bind:isJs={isJs} jsCode={testcodeJs} goCode={testcodeGo}/>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</CodeBlock>
|
|
@ -1,23 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Logger struct
|
|
||||||
type Logger struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Logger) WailsInit(runtime *wails.Runtime) error {
|
|
||||||
|
|
||||||
runtime.Log.SetLogLevel(logger.TRACE)
|
|
||||||
// runtime.Log.SetLogLevel(logger.DEBUG)
|
|
||||||
// runtime.Log.SetLogLevel(logger.INFO)
|
|
||||||
// runtime.Log.SetLogLevel(logger.WARNING)
|
|
||||||
// runtime.Log.SetLogLevel(logger.ERROR)
|
|
||||||
|
|
||||||
l.runtime = runtime
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
import { Log } from '@wails/runtime';
|
|
||||||
|
|
||||||
function setLogLevel() {
|
|
||||||
Log.SetLogLevel(Log.Level.TRACE);
|
|
||||||
// Log.SetLogLevel(Log.Level.DEBUG);
|
|
||||||
// Log.SetLogLevel(Log.Level.INFO);
|
|
||||||
// Log.SetLogLevel(Log.Level.WARNING);
|
|
||||||
// Log.SetLogLevel(Log.Level.ERROR);
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
<script>
|
|
||||||
import CodeBlock from '../../../components/CodeBlock.svelte';
|
|
||||||
import CodeSnippet from '../../../components/CodeSnippet.svelte';
|
|
||||||
import FakeTerm from '../../../components/FakeTerm.svelte';
|
|
||||||
import jsCode from './code.jsx';
|
|
||||||
import goCode from './code.go';
|
|
||||||
import { writable } from 'svelte/store';
|
|
||||||
import { System } from '@wails/runtime';
|
|
||||||
import description from './description.txt';
|
|
||||||
|
|
||||||
var isJs = false;
|
|
||||||
$: lang = isJs ? 'Javascript' : 'Go';
|
|
||||||
var id = "Platform";
|
|
||||||
|
|
||||||
let output = writable("");
|
|
||||||
|
|
||||||
function log(message) {
|
|
||||||
output.update( (current) => {
|
|
||||||
current += message;
|
|
||||||
return current;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPlatform() {
|
|
||||||
if( isJs ) {
|
|
||||||
log("Platform from JS runtime: " + System.Platform() + "\n");
|
|
||||||
} else {
|
|
||||||
backend.main.System.Platform().then( (platformFromGo) => {
|
|
||||||
log("Platform from Go runtime: " + platformFromGo + "\n");
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: testcodeJs = "import { runtime } from '@wails/runtime';\nruntime.Log.Info('Platform from JS runtime: ' + runtime.System.Platform());";
|
|
||||||
$: testcodeGo = '// runtime is given through WailsInit()\nruntime.Log.Info("Platform from Go runtime: " + runtime.System.Platform())';
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<CodeBlock bind:isJs={isJs} {jsCode} {goCode} {description} title="Platform()" {id} showRun=true>
|
|
||||||
<div class="browser-form">
|
|
||||||
<form data-wails-no-drag class="mw-full">
|
|
||||||
<input class="btn btn-primary" type="button" on:click="{getPlatform}" value="Fetch platform using {lang} runtime">
|
|
||||||
|
|
||||||
<CodeSnippet bind:isJs={isJs} jsCode={testcodeJs} goCode={testcodeGo}></CodeSnippet>
|
|
||||||
<FakeTerm text={$output} style="height: 100px; overflow: scroll"></FakeTerm>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</CodeBlock>
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MyStruct struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShowPlatformHelp shows specific help for the platform
|
|
||||||
func (l *MyStruct) ShowPlatformHelp() {
|
|
||||||
l.runtime.Browser.Open("https://wails.app/gettingstarted/" + l.runtime.System.Platform())
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
import { System, Browser } from '@wails/runtime';
|
|
||||||
|
|
||||||
function showPlatformHelp() {
|
|
||||||
// Do things
|
|
||||||
Browser.Open("https://wails.app/gettingstarted/" + System.Platform());
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
System.Platform() returns the platform that the application in running on. It uses the same values as Go's <code>runtime.GOOS</code>
|
|
@ -1,11 +0,0 @@
|
|||||||
<script>
|
|
||||||
import Platform from "./Platform/Platform.svelte";
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
The Wails runtime offers the ability to query system information through the <code>runtime.System</code> component.
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
<Platform></Platform>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
|||||||
|
|
||||||
<div class="mainpage">
|
|
||||||
<h2>Wails Kitchen Sink</h2>
|
|
||||||
|
|
||||||
This application is a demonstation of the capabilities of Wails.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.mainpage {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,55 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { Tray } from '@wails/runtime';
|
|
||||||
import CodeBlock from '../../../components/CodeBlock.svelte';
|
|
||||||
import CodeSnippet from '../../../components/CodeSnippet.svelte';
|
|
||||||
import description from './description.txt';
|
|
||||||
import { UniqueID } from '../../../utils/utils';
|
|
||||||
import jsCode from './code.jsx';
|
|
||||||
import goCode from './code.go';
|
|
||||||
import { darkMode } from '../../../Store';
|
|
||||||
|
|
||||||
let isJs = false;
|
|
||||||
$: lang = isJs ? 'Javascript' : 'Go';
|
|
||||||
|
|
||||||
let id = UniqueID('tray');
|
|
||||||
|
|
||||||
var icons = ["light", "dark", "svelte"];
|
|
||||||
let darkmode = $darkmode;
|
|
||||||
let iconName = darkMode ? 'light' : 'dark';
|
|
||||||
|
|
||||||
function setIcon() {
|
|
||||||
console.log(iconName);
|
|
||||||
if( isJs ) {
|
|
||||||
Tray.SetIcon(iconName);
|
|
||||||
} else {
|
|
||||||
backend.main.Tray.SetIcon(iconName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: exampleCodeJS = `import { Tray } from '@wails/runtime';\n\nTray.SetIcon('` + iconName + `');`;
|
|
||||||
$: exampleCodeGo = `// runtime is given through WailsInit()\nruntime.Tray.SetIcon("` + iconName + `");`;
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<CodeBlock bind:isJs={isJs} {jsCode} {goCode} {id} title="Tray.SetIcon(trayIconID)" {description}>
|
|
||||||
<div class="logging-form">
|
|
||||||
<form data-wails-no-drag class="mw-full">
|
|
||||||
<!-- Radio -->
|
|
||||||
<div class="form-group">
|
|
||||||
<div>Select Tray Icon</div>
|
|
||||||
{#each icons as option}
|
|
||||||
<div class="custom-radio">
|
|
||||||
<input type="radio" name="trayicon" bind:group="{iconName}" id="{id}-{option}" value="{option}">
|
|
||||||
<label for="{id}-{option}">{option}</label>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input class="btn btn-primary" type="button" on:click="{setIcon}" value="Set Icon using {lang} runtime">
|
|
||||||
|
|
||||||
<CodeSnippet bind:isJs={isJs} jsCode={exampleCodeJS} goCode={exampleCodeGo}></CodeSnippet>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</CodeBlock>
|
|
@ -1,26 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MyStruct struct {
|
|
||||||
runtime *wails.Runtime
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MyStruct) WailsInit(runtime *wails.Runtime) error {
|
|
||||||
|
|
||||||
// Load notes
|
|
||||||
data, err := ioutil.ReadFile("notes.txt")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetIcon an event with the loaded data
|
|
||||||
runtime.Events.Emit("notes loaded", string(data))
|
|
||||||
|
|
||||||
m.runtime = runtime
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
import { Events } from '@wails/runtime';
|
|
||||||
|
|
||||||
function processButtonPress(name, address) {
|
|
||||||
Events.Emit("new user", name, address);
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
<code>SetIcon(trayIconID)</code> is used to set the tray icon.
|
|
@ -1,17 +0,0 @@
|
|||||||
<script>
|
|
||||||
import SetIcon from "./SetIcon/SetIcon.svelte";
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
Wails includes support for adding icons/menus to the system tray. Tray icons are read from the "trayicons" directory in the project directory and bundled during the compilation phase.
|
|
||||||
The filenames follow a convention and only PNG icons are supported. The file `<projectroot>/trayicons/light.png` is given a tray icon ID of 'light'. This is used
|
|
||||||
when setting the icon.
|
|
||||||
|
|
||||||
<div style="padding: 15px"></div>
|
|
||||||
|
|
||||||
<SetIcon></SetIcon>
|
|
||||||
<br/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
</style>
|
|
@ -1,11 +0,0 @@
|
|||||||
<script>
|
|
||||||
import Window from './Window/Window.svelte';
|
|
||||||
</script>
|
|
||||||
<div>
|
|
||||||
The Wails runtime offers extensive control over the appliation window. This is available through the <code>runtime.Window</code> component.
|
|
||||||
|
|
||||||
<br/><br/>
|
|
||||||
|
|
||||||
<Window></Window>
|
|
||||||
</div>
|
|
||||||
|
|