mirror of
https://github.com/taigrr/wails.git
synced 2026-04-05 06:32:42 -07:00
Compare commits
168 Commits
v2.0.0-alp
...
v2-alpha-m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
52554009ce | ||
|
|
9f89a4a58a | ||
|
|
5585d72c1c | ||
|
|
7748cc2497 | ||
|
|
60f9a02143 | ||
|
|
899e522c74 | ||
|
|
be87d73da8 | ||
|
|
00639677f5 | ||
|
|
3c25a73ae8 | ||
|
|
344103739f | ||
|
|
c2b8247fbb | ||
|
|
03cdfad418 | ||
|
|
3fe4c5455a | ||
|
|
a6b95b23c9 | ||
|
|
2616d87922 | ||
|
|
f983649bc6 | ||
|
|
15ed02b78c | ||
|
|
2cb93b4b4b | ||
|
|
7e0ad801b0 | ||
|
|
ccdfa9a8be | ||
|
|
85e04d8094 | ||
|
|
e7d4ec5836 | ||
|
|
7fdbb0372c | ||
|
|
72f6f08f11 | ||
|
|
d16d5bdcd4 | ||
|
|
22d0e4ff8f | ||
|
|
c001a5f3cb | ||
|
|
43ab0e084f | ||
|
|
954470250e | ||
|
|
5ab5246aa0 | ||
|
|
abbbdda102 | ||
|
|
d270cc2ffa | ||
|
|
d6cdd1df82 | ||
|
|
3c0da9fd15 | ||
|
|
c9f93cd313 | ||
|
|
78c43d23b6 | ||
|
|
322f6b9b64 | ||
|
|
88bbfcb7f1 | ||
|
|
cae9827841 | ||
|
|
414b0149f2 | ||
|
|
33e4ec3e80 | ||
|
|
c46182923c | ||
|
|
5d2242f7a4 | ||
|
|
6204e63c56 | ||
|
|
4468edc939 | ||
|
|
b54a94135d | ||
|
|
e4d70f94b1 | ||
|
|
70418783a8 | ||
|
|
d9aa125a15 | ||
|
|
dacea399ab | ||
|
|
a78b9a5b9b | ||
|
|
36cd6af6df | ||
|
|
1e9807189c | ||
|
|
d54834d501 | ||
|
|
ac06e6728d | ||
|
|
227c316cb0 | ||
|
|
2c2ce66ec4 | ||
|
|
9a99b47f07 | ||
|
|
505bb51a27 | ||
|
|
6ade38e0ff | ||
|
|
6551e1b499 | ||
|
|
20f82cbde4 | ||
|
|
1ee9cf41e2 | ||
|
|
1cd38d12f9 | ||
|
|
0b71d64931 | ||
|
|
4954655ad4 | ||
|
|
8db91df185 | ||
|
|
ac4c17ca09 | ||
|
|
604dc6ace3 | ||
|
|
627aa06786 | ||
|
|
e718fb8333 | ||
|
|
c5d9fd1a0d | ||
|
|
63117fd519 | ||
|
|
a7c5064a33 | ||
|
|
f20ce7411d | ||
|
|
a7c04ac891 | ||
|
|
01de76a32e | ||
|
|
a861aa36b9 | ||
|
|
af593ef47a | ||
|
|
b98ab1f5b5 | ||
|
|
5ff3a286cf | ||
|
|
58dc917fb7 | ||
|
|
e00d65d468 | ||
|
|
dbcf4058e5 | ||
|
|
b558246d52 | ||
|
|
c3c88f5e27 | ||
|
|
31468aa177 | ||
|
|
6923ea301b | ||
|
|
ec8d8e4587 | ||
|
|
32591465f3 | ||
|
|
1c5c26e04a | ||
|
|
83baf4c6bb | ||
|
|
c383a61036 | ||
|
|
9d9c3d971a | ||
|
|
8acfeba3e1 | ||
|
|
09bae529de | ||
|
|
38c507a605 | ||
|
|
b7cd36921e | ||
|
|
de255729e6 | ||
|
|
3ac1dcc8d9 | ||
|
|
1d6cce7c52 | ||
|
|
c2ac4961ef | ||
|
|
8e84bdfa8d | ||
|
|
316e4de8e2 | ||
|
|
d83fd1c2b4 | ||
|
|
619d8cc05e | ||
|
|
244b3dc2b4 | ||
|
|
1a69d93d32 | ||
|
|
5ba85f2817 | ||
|
|
76f19f0752 | ||
|
|
5b10ee4b40 | ||
|
|
72b1e58218 | ||
|
|
7eb0718c9c | ||
|
|
ca8d41dd3b | ||
|
|
179d26b1c4 | ||
|
|
9786053324 | ||
|
|
aee395020f | ||
|
|
f377c94ba3 | ||
|
|
c5f1bd4449 | ||
|
|
e11dc0e080 | ||
|
|
0ea135a546 | ||
|
|
ccda8c5760 | ||
|
|
8a5287794e | ||
|
|
3e28bfe717 | ||
|
|
06ebe5f51f | ||
|
|
f02c140709 | ||
|
|
b80a64b0ee | ||
|
|
5d2cc81123 | ||
|
|
b86d2fe8cd | ||
|
|
fee14babbc | ||
|
|
f06ffb62de | ||
|
|
4a1a4d75ad | ||
|
|
b552c16539 | ||
|
|
d574d53fca | ||
|
|
2b69ac8391 | ||
|
|
e7cb40d5ee | ||
|
|
f409dbdab1 | ||
|
|
1748e8479f | ||
|
|
4f2788a294 | ||
|
|
856b81ab04 | ||
|
|
76aab2271c | ||
|
|
3192026e6d | ||
|
|
90dd05e52e | ||
|
|
e73cf44ddc | ||
|
|
4c2804eac9 | ||
|
|
e1dd77fd3f | ||
|
|
b69f1e6c43 | ||
|
|
7661082d58 | ||
|
|
34da4f056a | ||
|
|
642c1d5ec5 | ||
|
|
1f3351ffa5 | ||
|
|
30e96118b1 | ||
|
|
efd768ac5d | ||
|
|
6dbcd4fc45 | ||
|
|
11cd51c9ca | ||
|
|
3de38003bf | ||
|
|
418438b762 | ||
|
|
0a5c43435e | ||
|
|
d7bb831d7f | ||
|
|
824256db6d | ||
|
|
2f311ee403 | ||
|
|
e04db8775f | ||
|
|
2fbc63b458 | ||
|
|
8ac69d6afd | ||
|
|
6dec097184 | ||
|
|
c2015b1d72 | ||
|
|
9c75e61704 | ||
|
|
995d485a43 |
4
.github/workflows/latest-pre.yml
vendored
4
.github/workflows/latest-pre.yml
vendored
@@ -1,8 +1,10 @@
|
||||
name: latest pre-release
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
tags:
|
||||
- '**-pre**'
|
||||
- '**-pre**'
|
||||
jobs:
|
||||
|
||||
build:
|
||||
|
||||
29
.github/workflows/runtime.yml
vendored
Normal file
29
.github/workflows/runtime.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
name: Runtime
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- v2-alpha
|
||||
paths:
|
||||
- 'v2/internal/frontend/runtime/**'
|
||||
jobs:
|
||||
rebuild-runtime:
|
||||
name: Rebuild the runtime
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 14.17.6
|
||||
cache: 'npm'
|
||||
cache-dependency-path: v2/internal/frontend/runtime/package-lock.json
|
||||
- run: npm install
|
||||
working-directory: v2/internal/frontend/runtime
|
||||
- run: npm run build
|
||||
working-directory: v2/internal/frontend/runtime
|
||||
|
||||
- name: Commit changes
|
||||
uses: devops-infra/action-commit-push@master
|
||||
with:
|
||||
github_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
commit_prefix: "[AUTO]"
|
||||
commit_message: "The runtime was rebuilt"
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build linux || darwin || !windows
|
||||
// +build linux darwin !windows
|
||||
|
||||
package wails
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows || !linux || !darwin
|
||||
// +build windows !linux !darwin
|
||||
|
||||
package wails
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,3 +1,4 @@
|
||||
//go:build dev
|
||||
// +build dev
|
||||
|
||||
package main
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build dev
|
||||
// +build dev
|
||||
|
||||
package main
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package cmd
|
||||
|
||||
1
go.sum
1
go.sum
@@ -79,7 +79,6 @@ golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c h1:UIcGWL6/wpCfyGuJnRFJRurA+yj8RrW7Q6x2YMCXt6c=
|
||||
golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package interfaces
|
||||
|
||||
// Runtime interface
|
||||
type Runtime interface {}
|
||||
type Runtime interface{}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -2,4 +2,5 @@
|
||||
|
||||
This branch contains WORK IN PROGRESS! There are no guarantees. Use at your peril!
|
||||
|
||||
This document will be updated as progress is made.
|
||||
This document will be updated as progress is made.
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ The build command processes the Wails project and generates an application binar
|
||||
| -upx | Compress final binary with UPX (if installed) | |
|
||||
| -upxflags "custom flags" | Flags to pass to upx | |
|
||||
| -v int | Verbosity level (0 - silent, 1 - default, 2 - verbose) | 1 |
|
||||
| -delve | If true, runs delve on the compiled binary | false |
|
||||
|
||||
## The Build Process
|
||||
|
||||
@@ -44,11 +45,4 @@ The build process is as follows:
|
||||
- If the `-upx` flag was provided, `upx` is invoked to compress the binary. Custom flags may be provided using the `-upxflags` flag.
|
||||
- If the `package` flag is given for a non Windows target, the application is bundled for the platform. On Mac, this creates a `.app` with the processed icons, the `Info.plist` in `build/darwin` and the compiled binary.
|
||||
|
||||
### Server Target
|
||||
|
||||
TBD
|
||||
|
||||
### Hybrid Target
|
||||
|
||||
TBD
|
||||
|
||||
|
||||
@@ -4,11 +4,14 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/system"
|
||||
|
||||
"github.com/leaanthony/clir"
|
||||
"github.com/leaanthony/slicer"
|
||||
"github.com/wailsapp/wails/v2/pkg/clilogger"
|
||||
@@ -24,13 +27,9 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
|
||||
command := app.NewSubCommand("build", "Builds the application")
|
||||
|
||||
// Setup production flag
|
||||
production := false
|
||||
command.BoolFlag("production", "Build in production mode", &production)
|
||||
|
||||
// Setup pack flag
|
||||
pack := false
|
||||
command.BoolFlag("package", "Create a platform specific package", &pack)
|
||||
// Setup noPackage flag
|
||||
noPackage := false
|
||||
command.BoolFlag("noPackage", "Skips platform specific packaging", &noPackage)
|
||||
|
||||
compilerCommand := "go"
|
||||
command.StringFlag("compiler", "Use a different go compiler to build, eg go1.15beta1", &compilerCommand)
|
||||
@@ -57,11 +56,6 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
tags := ""
|
||||
command.StringFlag("tags", "tags to pass to Go compiler (quoted and space separated)", &tags)
|
||||
|
||||
// Retain assets
|
||||
keepAssets := false
|
||||
command.BoolFlag("k", "Keep generated assets", &keepAssets)
|
||||
|
||||
// Retain assets
|
||||
outputFilename := ""
|
||||
command.StringFlag("o", "Output filename", &outputFilename)
|
||||
|
||||
@@ -72,6 +66,12 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
webview2 := "download"
|
||||
command.StringFlag("webview2", "WebView2 installer strategy: download,embed,browser,error.", &webview2)
|
||||
|
||||
skipFrontend := false
|
||||
command.BoolFlag("s", "Skips building the frontend", &skipFrontend)
|
||||
|
||||
forceBuild := false
|
||||
command.BoolFlag("f", "Force build application", &forceBuild)
|
||||
|
||||
command.Action(func() error {
|
||||
|
||||
quiet := verbosity == 0
|
||||
@@ -89,12 +89,6 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
app.PrintBanner()
|
||||
}
|
||||
|
||||
// Setup mode
|
||||
mode := build.Debug
|
||||
if production {
|
||||
mode = build.Production
|
||||
}
|
||||
|
||||
// Check platform
|
||||
validPlatformArch := slicer.String([]string{
|
||||
"darwin",
|
||||
@@ -116,6 +110,12 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
compress = false
|
||||
}
|
||||
|
||||
// Lookup compiler path
|
||||
compilerPath, err := exec.LookPath(compilerCommand)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to find compiler: %s", compilerCommand)
|
||||
}
|
||||
|
||||
// Tags
|
||||
userTags := []string{}
|
||||
for _, tag := range strings.Split(tags, " ") {
|
||||
@@ -150,12 +150,13 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
OutputType: outputType,
|
||||
OutputFile: outputFilename,
|
||||
CleanBuildDirectory: cleanBuildDirectory,
|
||||
Mode: mode,
|
||||
Pack: pack,
|
||||
Mode: build.Production,
|
||||
Pack: !noPackage,
|
||||
LDFlags: ldflags,
|
||||
Compiler: compilerCommand,
|
||||
KeepAssets: keepAssets,
|
||||
Verbosity: verbosity,
|
||||
ForceBuild: forceBuild,
|
||||
IgnoreFrontend: skipFrontend,
|
||||
Compress: compress,
|
||||
CompressFlags: compressFlags,
|
||||
UserTags: userTags,
|
||||
@@ -165,7 +166,11 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
// Calculate platform and arch
|
||||
platformSplit := strings.Split(platform, "/")
|
||||
buildOptions.Platform = platformSplit[0]
|
||||
buildOptions.Arch = runtime.GOARCH
|
||||
if system.IsAppleSilicon {
|
||||
buildOptions.Arch = "arm64"
|
||||
} else {
|
||||
buildOptions.Arch = runtime.GOARCH
|
||||
}
|
||||
if len(platformSplit) == 2 {
|
||||
buildOptions.Arch = platformSplit[1]
|
||||
}
|
||||
@@ -174,22 +179,16 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
w := new(tabwriter.Writer)
|
||||
w.Init(os.Stdout, 8, 8, 0, '\t', 0)
|
||||
|
||||
buildModeText := "debug"
|
||||
if production {
|
||||
buildModeText = "production"
|
||||
}
|
||||
|
||||
// Write out the system information
|
||||
fmt.Fprintf(w, "\n")
|
||||
fmt.Fprintf(w, "App Type: \t%s\n", buildOptions.OutputType)
|
||||
fmt.Fprintf(w, "Platform: \t%s\n", buildOptions.Platform)
|
||||
fmt.Fprintf(w, "Arch: \t%s\n", buildOptions.Arch)
|
||||
fmt.Fprintf(w, "Compiler: \t%s\n", buildOptions.Compiler)
|
||||
fmt.Fprintf(w, "Compiler: \t%s\n", compilerPath)
|
||||
fmt.Fprintf(w, "Skip Frontend: \t%t\n", skipFrontend)
|
||||
fmt.Fprintf(w, "Compress: \t%t\n", buildOptions.Compress)
|
||||
fmt.Fprintf(w, "Build Mode: \t%s\n", buildModeText)
|
||||
fmt.Fprintf(w, "Package: \t%t\n", buildOptions.Pack)
|
||||
fmt.Fprintf(w, "Clean Build Dir: \t%t\n", buildOptions.CleanBuildDirectory)
|
||||
fmt.Fprintf(w, "KeepAssets: \t%t\n", buildOptions.KeepAssets)
|
||||
fmt.Fprintf(w, "LDFlags: \t\"%s\"\n", buildOptions.LDFlags)
|
||||
fmt.Fprintf(w, "Tags: \t[%s]\n", strings.Join(buildOptions.UserTags, ","))
|
||||
if len(buildOptions.OutputFile) > 0 {
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v2/internal/shell"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/leaanthony/clir"
|
||||
"github.com/leaanthony/slicer"
|
||||
"github.com/wailsapp/wails/v2/pkg/clilogger"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/build"
|
||||
)
|
||||
|
||||
// AddSubcommand adds the `debug` command for the Wails application
|
||||
func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
|
||||
outputType := "desktop"
|
||||
|
||||
validTargetTypes := slicer.String([]string{"desktop", "hybrid", "server"})
|
||||
|
||||
command := app.NewSubCommand("debug", "Builds the application then runs delve on the binary")
|
||||
|
||||
// Setup target type flag
|
||||
description := "Type of application to build. Valid types: " + validTargetTypes.Join(",")
|
||||
command.StringFlag("t", description, &outputType)
|
||||
|
||||
compilerCommand := "go"
|
||||
command.StringFlag("compiler", "Use a different go compiler to build, eg go1.15beta1", &compilerCommand)
|
||||
|
||||
quiet := false
|
||||
command.BoolFlag("q", "Suppress output to console", &quiet)
|
||||
|
||||
// ldflags to pass to `go`
|
||||
ldflags := ""
|
||||
command.StringFlag("ldflags", "optional ldflags", &ldflags)
|
||||
|
||||
// Log to file
|
||||
logFile := ""
|
||||
command.StringFlag("l", "Log to file", &logFile)
|
||||
|
||||
command.Action(func() error {
|
||||
|
||||
// Create logger
|
||||
logger := clilogger.New(w)
|
||||
logger.Mute(quiet)
|
||||
|
||||
// Validate output type
|
||||
if !validTargetTypes.Contains(outputType) {
|
||||
return fmt.Errorf("output type '%s' is not valid", outputType)
|
||||
}
|
||||
|
||||
if !quiet {
|
||||
app.PrintBanner()
|
||||
}
|
||||
|
||||
task := fmt.Sprintf("Building %s Application", strings.Title(outputType))
|
||||
logger.Println(task)
|
||||
logger.Println(strings.Repeat("-", len(task)))
|
||||
|
||||
// Setup mode
|
||||
mode := build.Debug
|
||||
|
||||
// Create BuildOptions
|
||||
buildOptions := &build.Options{
|
||||
Logger: logger,
|
||||
OutputType: outputType,
|
||||
Mode: mode,
|
||||
Pack: false,
|
||||
Platform: runtime.GOOS,
|
||||
LDFlags: ldflags,
|
||||
Compiler: compilerCommand,
|
||||
KeepAssets: false,
|
||||
}
|
||||
|
||||
outputFilename, err := doDebugBuild(buildOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check delve exists
|
||||
delveExists := shell.CommandExists("dlv")
|
||||
if !delveExists {
|
||||
return fmt.Errorf("cannot launch delve (Is it installed?)")
|
||||
}
|
||||
|
||||
// Get cwd
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Launch delve
|
||||
println("Launching Delve on port 2345...")
|
||||
command := shell.CreateCommand(cwd, "dlv", "--listen=:2345", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", outputFilename)
|
||||
return command.Run()
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doDebugBuild is our main build command
|
||||
func doDebugBuild(buildOptions *build.Options) (string, error) {
|
||||
|
||||
// Start Time
|
||||
start := time.Now()
|
||||
|
||||
outputFilename, err := build.Build(buildOptions)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Output stats
|
||||
elapsed := time.Since(start)
|
||||
buildOptions.Logger.Println("")
|
||||
buildOptions.Logger.Println(fmt.Sprintf("Built '%s' in %s.", outputFilename, elapsed.Round(time.Millisecond).String()))
|
||||
buildOptions.Logger.Println("")
|
||||
|
||||
return outputFilename, nil
|
||||
}
|
||||
@@ -2,8 +2,11 @@ package dev
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/leaanthony/slicer"
|
||||
"github.com/wailsapp/wails/v2/internal/project"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
@@ -12,6 +15,7 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/browser"
|
||||
"github.com/wailsapp/wails/v2/internal/colour"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
@@ -37,6 +41,14 @@ func LogDarkYellow(message string, args ...interface{}) {
|
||||
println(colour.DarkYellow(text))
|
||||
}
|
||||
|
||||
func sliceToMap(input []string) map[string]struct{} {
|
||||
result := map[string]struct{}{}
|
||||
for _, value := range input {
|
||||
result[value] = struct{}{}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// AddSubcommand adds the `dev` command for the Wails application
|
||||
func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
|
||||
@@ -50,20 +62,35 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
compilerCommand := "go"
|
||||
command.StringFlag("compiler", "Use a different go compiler to build, eg go1.15beta1", &compilerCommand)
|
||||
|
||||
// extensions to trigger rebuilds
|
||||
extensions := "go"
|
||||
command.StringFlag("e", "Extensions to trigger rebuilds (comma separated) eg go,js,css,html", &extensions)
|
||||
assetDir := ""
|
||||
command.StringFlag("assetdir", "Serve assets from the given directory", &assetDir)
|
||||
|
||||
// extensions to trigger rebuilds
|
||||
showWarnings := false
|
||||
command.BoolFlag("w", "Show warnings", &showWarnings)
|
||||
// extensions to trigger rebuilds of application
|
||||
extensions := "go"
|
||||
command.StringFlag("e", "Extensions to trigger rebuilds (comma separated) eg go", &extensions)
|
||||
|
||||
openBrowser := false
|
||||
command.BoolFlag("browser", "Open application in browser", &openBrowser)
|
||||
|
||||
noreload := false
|
||||
command.BoolFlag("noreload", "Disable reload on asset change", &noreload)
|
||||
|
||||
wailsjsdir := ""
|
||||
command.StringFlag("wailsjsdir", "Directory to generate the Wails JS modules", &wailsjsdir)
|
||||
|
||||
// tags to pass to `go`
|
||||
tags := ""
|
||||
command.StringFlag("tags", "tags to pass to Go compiler (quoted and space separated)", &tags)
|
||||
|
||||
// Verbosity
|
||||
verbosity := 1
|
||||
command.IntFlag("v", "Verbosity level (0 - silent, 1 - default, 2 - verbose)", &verbosity)
|
||||
command.IntFlag("v", "Verbosity level (0 - silent, 1 - standard, 2 - verbose)", &verbosity)
|
||||
|
||||
loglevel := ""
|
||||
command.StringFlag("loglevel", "Loglevel to use - Trace, Debug, Info, Warning, Error", &loglevel)
|
||||
command.StringFlag("loglevel", "Loglevel to use - Trace, Dev, Info, Warning, Error", &loglevel)
|
||||
|
||||
forceBuild := false
|
||||
command.BoolFlag("f", "Force build application", &forceBuild)
|
||||
|
||||
command.Action(func() error {
|
||||
|
||||
@@ -71,7 +98,65 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
logger := clilogger.New(w)
|
||||
app.PrintBanner()
|
||||
|
||||
// TODO: Check you are in a project directory
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
projectConfig, err := project.Load(cwd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if projectConfig.AssetDirectory == "" && assetDir == "" {
|
||||
return fmt.Errorf("No asset directory provided. Please use -assetdir to indicate which directory contains your built assets.")
|
||||
}
|
||||
|
||||
if assetDir == "" && projectConfig.AssetDirectory != "" {
|
||||
assetDir = projectConfig.AssetDirectory
|
||||
}
|
||||
|
||||
if assetDir != projectConfig.AssetDirectory {
|
||||
projectConfig.AssetDirectory = filepath.ToSlash(assetDir)
|
||||
err := projectConfig.Save()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if wailsjsdir == "" && projectConfig.WailsJSDir != "" {
|
||||
wailsjsdir = projectConfig.WailsJSDir
|
||||
}
|
||||
|
||||
if wailsjsdir == "" {
|
||||
wailsjsdir = "./frontend"
|
||||
}
|
||||
|
||||
if wailsjsdir != projectConfig.WailsJSDir {
|
||||
projectConfig.WailsJSDir = filepath.ToSlash(wailsjsdir)
|
||||
err := projectConfig.Save()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
buildOptions := &build.Options{
|
||||
Logger: logger,
|
||||
OutputType: "dev",
|
||||
Mode: build.Dev,
|
||||
Arch: runtime.GOARCH,
|
||||
Pack: true,
|
||||
Platform: runtime.GOOS,
|
||||
LDFlags: ldflags,
|
||||
Compiler: compilerCommand,
|
||||
ForceBuild: forceBuild,
|
||||
IgnoreFrontend: false,
|
||||
Verbosity: verbosity,
|
||||
WailsJSDir: wailsjsdir,
|
||||
}
|
||||
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
@@ -85,13 +170,12 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
}(watcher)
|
||||
|
||||
var debugBinaryProcess *process.Process = nil
|
||||
var extensionsThatTriggerARebuild = strings.Split(extensions, ",")
|
||||
var extensionsThatTriggerARebuild = sliceToMap(strings.Split(extensions, ","))
|
||||
|
||||
// Setup signal handler
|
||||
quitChannel := make(chan os.Signal, 1)
|
||||
signal.Notify(quitChannel, os.Interrupt, os.Kill, syscall.SIGTERM)
|
||||
|
||||
debounceQuit := make(chan bool, 1)
|
||||
exitCodeChannel := make(chan int, 1)
|
||||
|
||||
var passthruArgs []string
|
||||
//if len(os.Args) > 2 {
|
||||
@@ -100,70 +184,26 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
|
||||
// Do initial build
|
||||
logger.Println("Building application for development...")
|
||||
newProcess, appBinary, err := restartApp(logger, ldflags, compilerCommand, debugBinaryProcess, loglevel, passthruArgs, verbosity)
|
||||
newProcess, appBinary, err := restartApp(logger, buildOptions, debugBinaryProcess, loglevel, passthruArgs, assetDir, false, exitCodeChannel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if newProcess != nil {
|
||||
debugBinaryProcess = newProcess
|
||||
}
|
||||
|
||||
// open browser
|
||||
if openBrowser {
|
||||
err = browser.OpenURL("http://localhost:34115")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var newBinaryProcess *process.Process
|
||||
go debounce(100*time.Millisecond, watcher.Events, debounceQuit, func(event fsnotify.Event) {
|
||||
// logger.Println("event: %+v", event)
|
||||
|
||||
// Check for new directories
|
||||
if event.Op&fsnotify.Create == fsnotify.Create {
|
||||
// If this is a folder, add it to our watch list
|
||||
if fs.DirExists(event.Name) {
|
||||
if !strings.Contains(event.Name, "node_modules") {
|
||||
err := watcher.Add(event.Name)
|
||||
if err != nil {
|
||||
logger.Fatal("%s", err.Error())
|
||||
}
|
||||
LogGreen("[New Directory] Watching new directory: %s", event.Name)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Check for file writes
|
||||
if event.Op&fsnotify.Write == fsnotify.Write {
|
||||
|
||||
var rebuild bool = false
|
||||
|
||||
// Iterate all file patterns
|
||||
for _, pattern := range extensionsThatTriggerARebuild {
|
||||
if strings.HasSuffix(event.Name, pattern) {
|
||||
rebuild = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !rebuild {
|
||||
if showWarnings {
|
||||
LogDarkYellow("[File change] %s did not match extension list (%s)", event.Name, extensions)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
LogGreen("[Attempting rebuild] %s updated", event.Name)
|
||||
|
||||
// Do a rebuild
|
||||
|
||||
// Try and build the app
|
||||
newBinaryProcess, _, err = restartApp(logger, ldflags, compilerCommand, debugBinaryProcess, loglevel, passthruArgs, verbosity)
|
||||
if err != nil {
|
||||
fmt.Printf("Error during build: %s", err.Error())
|
||||
return
|
||||
}
|
||||
// If we have a new process, save it
|
||||
if newBinaryProcess != nil {
|
||||
debugBinaryProcess = newBinaryProcess
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
// Get project dir
|
||||
projectDir, err := os.Getwd()
|
||||
@@ -188,20 +228,88 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
if strings.HasPrefix(dir, filepath.Join(projectDir, "build")) {
|
||||
return
|
||||
}
|
||||
//println("Watching", dir)
|
||||
err = watcher.Add(dir)
|
||||
if err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
})
|
||||
|
||||
// Wait until we get a quit signal
|
||||
// Main Loop
|
||||
quit := false
|
||||
// Use 100ms debounce
|
||||
interval := 100 * time.Millisecond
|
||||
timer := time.NewTimer(interval)
|
||||
rebuild := false
|
||||
reload := false
|
||||
for quit == false {
|
||||
//reload := false
|
||||
select {
|
||||
case exitCode := <-exitCodeChannel:
|
||||
if exitCode == 0 {
|
||||
quit = true
|
||||
}
|
||||
case item := <-watcher.Events:
|
||||
// Check for file writes
|
||||
if item.Op&fsnotify.Write == fsnotify.Write {
|
||||
// Ignore directories
|
||||
if fs.DirExists(item.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Iterate all file patterns
|
||||
ext := filepath.Ext(item.Name)
|
||||
if ext != "" {
|
||||
ext = ext[1:]
|
||||
if _, exists := extensionsThatTriggerARebuild[ext]; exists {
|
||||
rebuild = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(item.Name, assetDir) {
|
||||
reload = true
|
||||
}
|
||||
timer.Reset(interval)
|
||||
}
|
||||
// Check for new directories
|
||||
if item.Op&fsnotify.Create == fsnotify.Create {
|
||||
// If this is a folder, add it to our watch list
|
||||
if fs.DirExists(item.Name) {
|
||||
//node_modules is BANNED!
|
||||
if !strings.Contains(item.Name, "node_modules") {
|
||||
err := watcher.Add(item.Name)
|
||||
if err != nil {
|
||||
logger.Fatal("%s", err.Error())
|
||||
}
|
||||
LogGreen("Added new directory to watcher: %s", item.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
case <-timer.C:
|
||||
if rebuild {
|
||||
rebuild = false
|
||||
LogGreen("[Rebuild triggered] files updated")
|
||||
// Try and build the app
|
||||
newBinaryProcess, _, err = restartApp(logger, buildOptions, debugBinaryProcess, loglevel, passthruArgs, assetDir, false, exitCodeChannel)
|
||||
if err != nil {
|
||||
LogRed("Error during build: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
// If we have a new process, save it
|
||||
if newBinaryProcess != nil {
|
||||
debugBinaryProcess = newBinaryProcess
|
||||
}
|
||||
}
|
||||
if reload {
|
||||
reload = false
|
||||
_, err = http.Get("http://localhost:34115/wails/reload")
|
||||
if err != nil {
|
||||
LogRed("Error during refresh: %s", err.Error())
|
||||
}
|
||||
}
|
||||
case <-quitChannel:
|
||||
LogGreen("\nCaught quit")
|
||||
// Notify debouncer to quit
|
||||
debounceQuit <- true
|
||||
quit = true
|
||||
}
|
||||
}
|
||||
@@ -228,30 +336,14 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Credit: https://drailing.net/2018/01/debounce-function-for-golang/
|
||||
func debounce(interval time.Duration, input chan fsnotify.Event, quitChannel chan bool, cb func(arg fsnotify.Event)) {
|
||||
var item fsnotify.Event
|
||||
timer := time.NewTimer(interval)
|
||||
exit:
|
||||
for {
|
||||
select {
|
||||
case item = <-input:
|
||||
timer.Reset(interval)
|
||||
case <-timer.C:
|
||||
if item.Name != "" {
|
||||
cb(item)
|
||||
}
|
||||
case <-quitChannel:
|
||||
break exit
|
||||
}
|
||||
}
|
||||
}
|
||||
func restartApp(logger *clilogger.CLILogger, buildOptions *build.Options, debugBinaryProcess *process.Process, loglevel string, passthruArgs []string, assetDir string, firstRun bool, exitCodeChannel chan int) (*process.Process, string, error) {
|
||||
|
||||
func restartApp(logger *clilogger.CLILogger, ldflags string, compilerCommand string, debugBinaryProcess *process.Process, loglevel string, passthruArgs []string, verbosity int) (*process.Process, string, error) {
|
||||
|
||||
appBinary, err := buildApp(logger, ldflags, compilerCommand, verbosity)
|
||||
appBinary, err := build.Build(buildOptions)
|
||||
println()
|
||||
if err != nil {
|
||||
if firstRun {
|
||||
return nil, "", err
|
||||
}
|
||||
LogRed("Build error - continuing to run current version")
|
||||
LogDarkYellow(err.Error())
|
||||
return nil, "", nil
|
||||
@@ -268,15 +360,18 @@ func restartApp(logger *clilogger.CLILogger, ldflags string, compilerCommand str
|
||||
debugBinaryProcess = nil
|
||||
}
|
||||
|
||||
// TODO: Generate `backend.js`
|
||||
|
||||
// Start up new binary with correct args
|
||||
var args = []string{"-loglevel", loglevel}
|
||||
if len(passthruArgs) > 0 {
|
||||
args = append(args, passthruArgs...)
|
||||
args := slicer.StringSlicer{}
|
||||
args.Add("-loglevel", loglevel)
|
||||
if assetDir != "" {
|
||||
args.Add("-assetdir", assetDir)
|
||||
}
|
||||
newProcess := process.NewProcess(logger, appBinary, args...)
|
||||
err = newProcess.Start()
|
||||
|
||||
if len(passthruArgs) > 0 {
|
||||
args.AddSlice(passthruArgs)
|
||||
}
|
||||
newProcess := process.NewProcess(appBinary, args.AsSlice()...)
|
||||
err = newProcess.Start(exitCodeChannel)
|
||||
if err != nil {
|
||||
// Remove binary
|
||||
deleteError := fs.DeleteFile(appBinary)
|
||||
@@ -288,29 +383,3 @@ func restartApp(logger *clilogger.CLILogger, ldflags string, compilerCommand str
|
||||
|
||||
return newProcess, appBinary, nil
|
||||
}
|
||||
|
||||
func buildApp(logger *clilogger.CLILogger, ldflags string, compilerCommand string, verbosity int) (string, error) {
|
||||
|
||||
// Create random output file
|
||||
outputFile := "wailsdev"
|
||||
if runtime.GOOS == "windows" {
|
||||
outputFile += ".exe"
|
||||
}
|
||||
|
||||
// Create BuildOptions
|
||||
buildOptions := &build.Options{
|
||||
Logger: logger,
|
||||
OutputType: "dev",
|
||||
Mode: build.Debug,
|
||||
Pack: false,
|
||||
Platform: runtime.GOOS,
|
||||
LDFlags: ldflags,
|
||||
Compiler: compilerCommand,
|
||||
OutputFile: outputFile,
|
||||
IgnoreFrontend: true,
|
||||
Verbosity: verbosity,
|
||||
}
|
||||
|
||||
return build.Build(buildOptions)
|
||||
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
}
|
||||
logger.Println("Done.")
|
||||
|
||||
logger.Println("")
|
||||
|
||||
// Start a new tabwriter
|
||||
w := new(tabwriter.Writer)
|
||||
w.Init(os.Stdout, 8, 8, 0, '\t', 0)
|
||||
|
||||
18
v2/cmd/wails/internal/commands/generate/README.md
Normal file
18
v2/cmd/wails/internal/commands/generate/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generate
|
||||
|
||||
The `generate` command provides the ability to generate various Wails related components.
|
||||
|
||||
## Usage
|
||||
|
||||
`wails generate [subcommand] [options]`
|
||||
|
||||
## Template
|
||||
|
||||
`wails generate template -name <name> [-frontend] [-q]`
|
||||
|
||||
Generate a starter template for you to customise.
|
||||
|
||||
| Flag | Details |
|
||||
| :------------- | :----------- |
|
||||
| -frontend | Copies all the files from the current directory into the template's `frontend` directory. Useful for converting frontend projects created by boilerplate generators. |
|
||||
| -q | Suppress output |
|
||||
@@ -2,7 +2,8 @@ package generate
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/wailsapp/wails/v2/cmd/wails/internal/commands/generate/template"
|
||||
|
||||
"github.com/leaanthony/clir"
|
||||
"github.com/wailsapp/wails/v2/pkg/clilogger"
|
||||
@@ -14,50 +15,9 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
|
||||
command := app.NewSubCommand("generate", "Code Generation Tools")
|
||||
|
||||
// Backend API
|
||||
backendAPI := command.NewSubCommand("module", "Generates a JS module for the frontend to interface with the backend")
|
||||
//AddModuleCommand(app, command, w)
|
||||
template.AddSubCommand(app, command, w)
|
||||
|
||||
// Quiet Init
|
||||
quiet := false
|
||||
backendAPI.BoolFlag("q", "Suppress output to console", &quiet)
|
||||
|
||||
backendAPI.Action(func() error {
|
||||
|
||||
// Create logger
|
||||
logger := clilogger.New(w)
|
||||
logger.Mute(quiet)
|
||||
|
||||
app.PrintBanner()
|
||||
|
||||
logger.Print("Generating Javascript module for Go code...")
|
||||
|
||||
// Start Time
|
||||
start := time.Now()
|
||||
|
||||
p, err := parser.GenerateWailsFrontendPackage()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Println("done.")
|
||||
logger.Println("")
|
||||
|
||||
elapsed := time.Since(start)
|
||||
packages := p.Packages
|
||||
|
||||
// Print report
|
||||
for _, pkg := range p.Packages {
|
||||
if pkg.ShouldGenerate() {
|
||||
logPackage(pkg, logger)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
logger.Println("%d packages parsed in %s.", len(packages), elapsed)
|
||||
|
||||
return nil
|
||||
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
58
v2/cmd/wails/internal/commands/generate/module.go
Normal file
58
v2/cmd/wails/internal/commands/generate/module.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/leaanthony/clir"
|
||||
"github.com/wailsapp/wails/v2/pkg/clilogger"
|
||||
"github.com/wailsapp/wails/v2/pkg/parser"
|
||||
)
|
||||
|
||||
func AddModuleCommand(app *clir.Cli, parent *clir.Command, w io.Writer) {
|
||||
|
||||
// Backend API
|
||||
backendAPI := parent.NewSubCommand("module", "Generates a JS module for the frontend to interface with the backend")
|
||||
|
||||
// Quiet Init
|
||||
quiet := false
|
||||
backendAPI.BoolFlag("q", "Suppress output to console", &quiet)
|
||||
|
||||
backendAPI.Action(func() error {
|
||||
|
||||
// Create logger
|
||||
logger := clilogger.New(w)
|
||||
logger.Mute(quiet)
|
||||
|
||||
app.PrintBanner()
|
||||
|
||||
logger.Print("Generating Javascript module for Go code...")
|
||||
|
||||
// Start Time
|
||||
start := time.Now()
|
||||
|
||||
p, err := parser.GenerateWailsFrontendPackage()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Println("done.")
|
||||
logger.Println("")
|
||||
|
||||
elapsed := time.Since(start)
|
||||
packages := p.Packages
|
||||
|
||||
// Print report
|
||||
for _, pkg := range p.Packages {
|
||||
if pkg.ShouldGenerate() {
|
||||
logPackage(pkg, logger)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
logger.Println("%d packages parsed in %s.", len(packages), elapsed)
|
||||
|
||||
return nil
|
||||
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
# Next Steps
|
||||
|
||||
Congratulations on generating your template!
|
||||
|
||||
## Completing your template
|
||||
|
||||
The next steps to complete the template are:
|
||||
|
||||
1. Complete the fields in the `template.json` file.
|
||||
2. Update `README.md`.
|
||||
3. Edit `wails.tmpl.json` and ensure all fields are correct, especially:
|
||||
- `html` - path to your `index.html`
|
||||
- `frontend:install` - The command to install your frontend dependencies
|
||||
- `frontend:build` - The command to build your frontend
|
||||
4. Remove any `public` or `dist` directories.
|
||||
5. Delete this file.
|
||||
|
||||
## Testing your template
|
||||
|
||||
You can test your template by running this command:
|
||||
|
||||
`wails init -name test -t {{.TemplateDir}}`
|
||||
|
||||
### Checklist
|
||||
Once generated, do the following tests:
|
||||
- Change into the new project directory and run `wails build`. A working binary should be generated in the `build/bin` project directory.
|
||||
- Run `wails dev`. This will compile your backend and run it. You should be able to go into the frontend directory and run `npm run dev` (or whatever your dev command is) and this should run correctly. You should be able to then open a browser to your local dev server and the application should work.
|
||||
|
||||
## Publishing your template
|
||||
|
||||
You can publish a template to a git repository and use it as follows:
|
||||
|
||||
`wails init -name test -t https://your/git/url`
|
||||
|
||||
EG:
|
||||
|
||||
`wails init -name test -t https://github.com/leaanthony/testtemplate`
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# README
|
||||
|
||||
## About
|
||||
|
||||
About your template
|
||||
|
||||
## Building
|
||||
|
||||
To build this project in debug mode, use `wails build`. For production, use `wails build -production`.
|
||||
To generate a platform native package, add the `-package` flag.
|
||||
|
||||
## Live Development
|
||||
|
||||
To run in live development mode, run `wails dev` in the project directory. In another terminal, go into the `frontend`
|
||||
directory and run `npm run dev`. The frontend dev server will run on http://localhost:5000. Connect to this
|
||||
in your browser and connect to your application.
|
||||
@@ -0,0 +1,35 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// App struct
|
||||
type App struct {
|
||||
runtime context.Context
|
||||
}
|
||||
|
||||
// NewApp creates a new App application struct
|
||||
func NewApp() *App {
|
||||
return &App{}
|
||||
}
|
||||
|
||||
// startup is called at application startup
|
||||
func (b *App) startup(ctx context.Context) {
|
||||
// Perform your setup here
|
||||
//TODO: move to new runtime layout
|
||||
|
||||
//b.runtime = runtime
|
||||
//runtime.Window.SetTitle("{{.ProjectName}}")
|
||||
}
|
||||
|
||||
// shutdown is called at application termination
|
||||
func (b *App) shutdown(ctx context.Context) {
|
||||
// Perform your teardown here
|
||||
}
|
||||
|
||||
// Greet returns a greeting for the given name
|
||||
func (b *App) Greet(name string) string {
|
||||
return fmt.Sprintf("Hello %s!", name)
|
||||
}
|
||||
@@ -7,8 +7,7 @@
|
||||
<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>
|
||||
<input id="name" type="text">
|
||||
<button onclick="greet()">Greet</button>
|
||||
</div>
|
||||
<div id="result"></div>
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,21 @@
|
||||
|
||||
import {ready} from '@wails/runtime';
|
||||
|
||||
ready( () => {
|
||||
// Get input + focus
|
||||
let nameElement = document.getElementById("name");
|
||||
nameElement.focus();
|
||||
|
||||
// Setup the greet function
|
||||
window.greet = function () {
|
||||
|
||||
// Get name
|
||||
let 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;
|
||||
});
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
module test
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/wailsapp/wails/v2 v2.0.0-alpha
|
||||
)
|
||||
|
||||
replace github.com/wailsapp/wails/v2 v2.0.0-alpha => {{.WailsDirectory}}
|
||||
@@ -0,0 +1,47 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/options/windows"
|
||||
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/logger"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
// Create application with options
|
||||
app := NewApp()
|
||||
|
||||
err := wails.Run(&options.App{
|
||||
Title: "{{.ProjectName}}",
|
||||
Width: 800,
|
||||
Height: 600,
|
||||
MinWidth: 400,
|
||||
MinHeight: 400,
|
||||
MaxWidth: 1280,
|
||||
MaxHeight: 1024,
|
||||
DisableResize: false,
|
||||
Fullscreen: false,
|
||||
Frameless: false,
|
||||
StartHidden: false,
|
||||
HideWindowOnClose: false,
|
||||
RGBA: &options.RGBA{0, 0, 0, 255},
|
||||
Windows: &windows.Options{
|
||||
WebviewIsTransparent: true,
|
||||
WindowIsTranslucent: true,
|
||||
DisableWindowIcon: true,
|
||||
},
|
||||
LogLevel: logger.DEBUG,
|
||||
OnStartup: app.startup,
|
||||
OnShutdown: app.shutdown,
|
||||
Bind: []interface{}{
|
||||
app,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "Long name",
|
||||
"shortname": "{{.Name}}",
|
||||
"author": "",
|
||||
"description": "Description of the template",
|
||||
"helpurl": "URL for help with the template, eg homepage"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "{{.ProjectName}}",
|
||||
"outputfilename": "{{.BinaryName}}",
|
||||
"html": "frontend/dist/index.html",
|
||||
"frontend:build": "npm run build",
|
||||
"frontend:install": "npm install",
|
||||
"author": {
|
||||
"name": "{{.AuthorName}}",
|
||||
"email": "{{.AuthorEmail}}"
|
||||
}
|
||||
}
|
||||
188
v2/cmd/wails/internal/commands/generate/template/template.go
Normal file
188
v2/cmd/wails/internal/commands/generate/template/template.go
Normal file
@@ -0,0 +1,188 @@
|
||||
package template
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/leaanthony/debme"
|
||||
|
||||
"github.com/leaanthony/gosod"
|
||||
"github.com/wailsapp/wails/v2/internal/fs"
|
||||
|
||||
"github.com/leaanthony/clir"
|
||||
"github.com/tidwall/sjson"
|
||||
)
|
||||
|
||||
//go:embed base
|
||||
var base embed.FS
|
||||
|
||||
func AddSubCommand(app *clir.Cli, parent *clir.Command, w io.Writer) {
|
||||
|
||||
// command
|
||||
command := parent.NewSubCommand("template", "Generates a wails template")
|
||||
|
||||
name := ""
|
||||
command.StringFlag("name", "The name of the template", &name)
|
||||
|
||||
migrate := false
|
||||
command.BoolFlag("migrate", "This indicates that the current directory is a frontend project and should be used by the template", &migrate)
|
||||
|
||||
// Quiet Init
|
||||
quiet := false
|
||||
command.BoolFlag("q", "Suppress output to console", &quiet)
|
||||
|
||||
command.Action(func() error {
|
||||
|
||||
// If the current directory is not empty, we create a new directory
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
templateDir := cwd
|
||||
empty, err := fs.DirIsEmpty(templateDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !empty {
|
||||
templateDir = filepath.Join(cwd, name)
|
||||
println("Creating new template directory:", name)
|
||||
err = fs.Mkdir(templateDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Create base template
|
||||
baseTemplate, err := debme.FS(base, "base")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
g := gosod.New(baseTemplate)
|
||||
g.SetTemplateFilters([]string{".template"})
|
||||
|
||||
err = os.Chdir(templateDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type templateData struct {
|
||||
Name string
|
||||
Description string
|
||||
TemplateDir string
|
||||
}
|
||||
|
||||
println("Extracting base template files...")
|
||||
|
||||
err = g.Extract(templateDir, &templateData{
|
||||
Name: name,
|
||||
TemplateDir: templateDir,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If we aren't migrating the files, just exit
|
||||
if migrate == false {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove frontend directory
|
||||
frontendDir := filepath.Join(templateDir, "frontend")
|
||||
err = os.RemoveAll(frontendDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Move the files into a new frontend directory
|
||||
println("Migrating files to frontend directory...")
|
||||
err = fs.MoveDirExtended(cwd, frontendDir, []string{name})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Process package.json
|
||||
err = processPackageJSON(frontendDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Process package-lock.json
|
||||
err = processPackageLockJSON(frontendDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove node_modules - ignore error, eg it doesn't exist
|
||||
_ = os.RemoveAll(filepath.Join(frontendDir, "node_modules"))
|
||||
|
||||
return nil
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func processPackageJSON(frontendDir string) error {
|
||||
var err error
|
||||
|
||||
packageJSON := filepath.Join(frontendDir, "package.json")
|
||||
if !fs.FileExists(packageJSON) {
|
||||
println("No package.json found - cannot process.")
|
||||
return nil
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(packageJSON)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
json := string(data)
|
||||
|
||||
// We will ignore these errors - it's not critical
|
||||
println("Updating package.json data...")
|
||||
json, _ = sjson.Set(json, "name", "{{.ProjectName}}")
|
||||
json, _ = sjson.Set(json, "author", "{{.AuthorName}}")
|
||||
|
||||
err = os.WriteFile(packageJSON, []byte(json), 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
baseDir := filepath.Dir(packageJSON)
|
||||
println("Renaming package.json -> package.tmpl.json...")
|
||||
err = os.Rename(packageJSON, filepath.Join(baseDir, "package.tmpl.json"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func processPackageLockJSON(frontendDir string) error {
|
||||
var err error
|
||||
|
||||
filename := filepath.Join(frontendDir, "package-lock.json")
|
||||
if !fs.FileExists(filename) {
|
||||
println("No package-lock.json found - cannot process.")
|
||||
return nil
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
json := string(data)
|
||||
|
||||
// We will ignore these errors - it's not critical
|
||||
println("Updating package-lock.json data...")
|
||||
json, _ = sjson.Set(json, "name", "{{.ProjectName}}")
|
||||
|
||||
err = os.WriteFile(filename, []byte(json), 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
baseDir := filepath.Dir(filename)
|
||||
println("Renaming package-lock.json -> package-lock.tmpl.json...")
|
||||
err = os.Rename(filename, filepath.Join(baseDir, "package-lock.tmpl.json"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -2,11 +2,12 @@ package initialise
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v2/pkg/buildassets"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/buildassets"
|
||||
|
||||
"github.com/wailsapp/wails/v2/cmd/wails/internal/commands/initialise/templates"
|
||||
|
||||
"github.com/leaanthony/clir"
|
||||
@@ -18,17 +19,11 @@ import (
|
||||
// AddSubcommand adds the `init` command for the Wails application
|
||||
func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
|
||||
// Load the template shortnames
|
||||
validShortNames, err := templates.TemplateShortNames()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
command := app.NewSubCommand("init", "Initialise a new Wails project")
|
||||
|
||||
// Setup template name flag
|
||||
templateName := "vanilla"
|
||||
description := "Name of template to use. Valid tempates: " + validShortNames.Join(" ")
|
||||
description := "Name of built-in template to use, path to template or template url."
|
||||
command.StringFlag("t", description, &templateName)
|
||||
|
||||
// Setup project name
|
||||
@@ -72,14 +67,6 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Validate output type
|
||||
if !validShortNames.Contains(templateName) {
|
||||
logger.Print(fmt.Sprintf("[ERROR] Template '%s' is not valid", templateName))
|
||||
logger.Println("")
|
||||
command.PrintHelp()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate name
|
||||
if len(projectName) == 0 {
|
||||
logger.Println("ERROR: Project name required")
|
||||
@@ -122,7 +109,7 @@ func initProject(options *templates.Options) error {
|
||||
start := time.Now()
|
||||
|
||||
// Install the template
|
||||
err := templates.Install(options)
|
||||
remote, err := templates.Install(options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -152,6 +139,11 @@ func initProject(options *templates.Options) error {
|
||||
if options.InitGit {
|
||||
options.Logger.Println("Git repository initialised.")
|
||||
}
|
||||
|
||||
if remote {
|
||||
options.Logger.Println("\nNOTE: You have created a project using a remote template. The Wails project takes no responsibility for 3rd party templates. Only use remote templates that you trust.")
|
||||
}
|
||||
|
||||
options.Logger.Println("")
|
||||
options.Logger.Println(fmt.Sprintf("Initialised project '%s' in %s.", options.ProjectName, elapsed.Round(time.Millisecond).String()))
|
||||
options.Logger.Println("")
|
||||
|
||||
@@ -5,14 +5,19 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
gofs "io/fs"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/go-git/go-git/v5"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/leaanthony/debme"
|
||||
"github.com/leaanthony/gosod"
|
||||
"github.com/leaanthony/slicer"
|
||||
"github.com/olekukonko/tablewriter"
|
||||
"github.com/wailsapp/wails/v2/internal/fs"
|
||||
"github.com/wailsapp/wails/v2/pkg/clilogger"
|
||||
@@ -74,7 +79,7 @@ func parseTemplate(template gofs.FS) (Template, error) {
|
||||
var result Template
|
||||
data, err := gofs.ReadFile(template, "template.json")
|
||||
if err != nil {
|
||||
return result, err
|
||||
return result, errors.Wrap(err, "Error parsing template")
|
||||
}
|
||||
err = json.Unmarshal(data, &result)
|
||||
if err != nil {
|
||||
@@ -84,26 +89,6 @@ func parseTemplate(template gofs.FS) (Template, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// TemplateShortNames returns a slicer of short template names
|
||||
func TemplateShortNames() (*slicer.StringSlicer, error) {
|
||||
|
||||
var result slicer.StringSlicer
|
||||
|
||||
// If the cache isn't loaded, load it
|
||||
if templateCache == nil {
|
||||
err := loadTemplateCache()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, template := range templateCache {
|
||||
result.Add(template.ShortName)
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// List returns the list of available templates
|
||||
func List() ([]Template, error) {
|
||||
|
||||
@@ -175,12 +160,12 @@ func loadTemplateCache() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Install the given template
|
||||
func Install(options *Options) error {
|
||||
// Install the given template. Returns true if the template is remote.
|
||||
func Install(options *Options) (bool, error) {
|
||||
// Get cwd
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Did the user want to install in current directory?
|
||||
@@ -189,7 +174,7 @@ func Install(options *Options) error {
|
||||
// If the current directory is empty, use it
|
||||
isEmpty, err := fs.DirIsEmpty(cwd)
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
if isEmpty {
|
||||
@@ -198,7 +183,7 @@ func Install(options *Options) error {
|
||||
} else {
|
||||
options.TargetDir = filepath.Join(cwd, options.ProjectName)
|
||||
if fs.DirExists(options.TargetDir) {
|
||||
return fmt.Errorf("cannot create project directory. Dir exists: %s", options.TargetDir)
|
||||
return false, fmt.Errorf("cannot create project directory. Dir exists: %s", options.TargetDir)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,21 +191,56 @@ func Install(options *Options) error {
|
||||
// Get the absolute path of the given directory
|
||||
targetDir, err := filepath.Abs(filepath.Join(cwd, options.TargetDir))
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
options.TargetDir = targetDir
|
||||
if !fs.DirExists(options.TargetDir) {
|
||||
err := fs.Mkdir(options.TargetDir)
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get template
|
||||
// Flag to indicate remote template
|
||||
remoteTemplate := false
|
||||
|
||||
// Is this a shortname?
|
||||
template, err := getTemplateByShortname(options.TemplateName)
|
||||
if err != nil {
|
||||
return err
|
||||
// Is this a filepath?
|
||||
templatePath, err := filepath.Abs(options.TemplateName)
|
||||
if fs.DirExists(templatePath) {
|
||||
templateFS := os.DirFS(templatePath)
|
||||
template, err = parseTemplate(templateFS)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "Error installing template")
|
||||
}
|
||||
} else {
|
||||
// git clone to temporary dir
|
||||
tempdir, err := gitclone(options)
|
||||
defer func(path string) {
|
||||
err := os.RemoveAll(path)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}(tempdir)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// Remove the .git directory
|
||||
err = os.RemoveAll(filepath.Join(tempdir, ".git"))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
templateFS := os.DirFS(tempdir)
|
||||
template, err = parseTemplate(templateFS)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
remoteTemplate = true
|
||||
}
|
||||
}
|
||||
|
||||
// Use Gosod to install the template
|
||||
@@ -255,15 +275,30 @@ func Install(options *Options) error {
|
||||
// Extract the template
|
||||
err = installer.Extract(options.TargetDir, templateData)
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = generateIDEFiles(options)
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
return nil
|
||||
return remoteTemplate, nil
|
||||
}
|
||||
|
||||
// Clones the given uri and returns the temporary cloned directory
|
||||
func gitclone(options *Options) (string, error) {
|
||||
// Create temporary directory
|
||||
dirname, err := ioutil.TempDir("", "wails-template-*")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, err = git.PlainClone(dirname, false, &git.CloneOptions{
|
||||
URL: options.TemplateName,
|
||||
})
|
||||
|
||||
return dirname, err
|
||||
|
||||
}
|
||||
|
||||
// OutputList prints the list of available tempaltes to the given logger
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# README
|
||||
|
||||
## About
|
||||
|
||||
This is a basic Svelte template, using rollup to bundle the assets into a single JS file.
|
||||
Rollup is configured to do the following:
|
||||
|
||||
- Convert imported images to base64 strings
|
||||
- Convert `url()` in `@font-face` declarations to base64 strings
|
||||
- Bundle all css into the JS bundle
|
||||
- Copy `index.html` from `frontend/src/` to `frontend/dist/`
|
||||
|
||||
Clicking the button will call the backend
|
||||
|
||||
## Building
|
||||
|
||||
To build this project in debug mode, use `wails build`. For production, use `wails build -production`.
|
||||
To generate a platform native package, add the `-package` flag.
|
||||
|
||||
## Live Development
|
||||
|
||||
To run in live development mode, run `wails dev` in the project directory. In another terminal, go into the `frontend`
|
||||
directory and run `npm run dev`. The frontend dev server will run on http://localhost:5000. Connect to this
|
||||
in your browser and connect to your application.
|
||||
@@ -0,0 +1,32 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// App application struct
|
||||
type App struct {
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// NewApp creates a new App application struct
|
||||
func NewApp() *App {
|
||||
return &App{}
|
||||
}
|
||||
|
||||
// startup is called at application startup
|
||||
func (b *App) startup(ctx context.Context) {
|
||||
// Perform your setup here
|
||||
b.ctx = ctx
|
||||
}
|
||||
|
||||
// shutdown is called at application termination
|
||||
func (b *App) shutdown(ctx context.Context) {
|
||||
// Perform your teardown here
|
||||
}
|
||||
|
||||
// Greet returns a greeting for the given name
|
||||
func (b *App) Greet(name string) string {
|
||||
return fmt.Sprintf("Hello %s!", name)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/node_modules/
|
||||
/public/build/
|
||||
/dist/build/
|
||||
|
||||
.DS_Store
|
||||
@@ -35,6 +35,7 @@ Navigate to [localhost:5000](http://localhost:5000). You should see your app run
|
||||
|
||||
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`.
|
||||
|
||||
If you're using [Visual Studio Code](https://code.visualstudio.com/) we recommend installing the official extension [Svelte for VS Code](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). If you are using other editors you may need to install a plugin in order to get syntax highlighting and intellisense.
|
||||
|
||||
## Building and running in production mode
|
||||
|
||||
@@ -57,26 +58,37 @@ If you're building a single-page app (SPA) with multiple routes, sirv needs to b
|
||||
"start": "sirv public --single"
|
||||
```
|
||||
|
||||
## Using TypeScript
|
||||
|
||||
This template comes with a script to set up a TypeScript development environment, you can run it immediately after cloning the template with:
|
||||
|
||||
```bash
|
||||
node scripts/setupTypeScript.js
|
||||
```
|
||||
|
||||
Or remove the script via:
|
||||
|
||||
```bash
|
||||
rm scripts/setupTypeScript.js
|
||||
```
|
||||
|
||||
## Deploying to the web
|
||||
|
||||
### With [now](https://zeit.co/now)
|
||||
### With [Vercel](https://vercel.com)
|
||||
|
||||
Install `now` if you haven't already:
|
||||
Install `vercel` if you haven't already:
|
||||
|
||||
```bash
|
||||
npm install -g now
|
||||
npm install -g vercel
|
||||
```
|
||||
|
||||
Then, from within your project folder:
|
||||
|
||||
```bash
|
||||
cd public
|
||||
now deploy --name my-project
|
||||
vercel 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:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "{{.ProjectName}}",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "rollup -c",
|
||||
"dev": "rollup -c -w",
|
||||
"start": "sirv dist --no-clear"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^17.0.0",
|
||||
"@rollup/plugin-image": "^2.0.6",
|
||||
"@rollup/plugin-node-resolve": "^11.0.0",
|
||||
"postcss": "^8.3.5",
|
||||
"postcss-url": "^10.1.3",
|
||||
"rollup": "^2.3.4",
|
||||
"rollup-plugin-copy": "^3.4.0",
|
||||
"rollup-plugin-livereload": "^2.0.0",
|
||||
"rollup-plugin-postcss": "^4.0.0",
|
||||
"rollup-plugin-svelte": "^7.0.0",
|
||||
"rollup-plugin-terser": "^7.0.0",
|
||||
"svelte": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"sirv-cli": "^1.0.0"
|
||||
}
|
||||
,"author":"{{.AuthorName}}"}
|
||||
@@ -0,0 +1,91 @@
|
||||
import svelte from 'rollup-plugin-svelte';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
import livereload from 'rollup-plugin-livereload';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
import copy from 'rollup-plugin-copy';
|
||||
import image from '@rollup/plugin-image';
|
||||
import postcss from 'rollup-plugin-postcss'
|
||||
import url from 'postcss-url';
|
||||
|
||||
const production = !process.env.ROLLUP_WATCH;
|
||||
|
||||
function serve() {
|
||||
let server;
|
||||
|
||||
function toExit() {
|
||||
if (server) server.kill(0);
|
||||
}
|
||||
|
||||
return {
|
||||
writeBundle() {
|
||||
if (server) return;
|
||||
server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
|
||||
stdio: ['ignore', 'inherit', 'inherit'],
|
||||
shell: true
|
||||
});
|
||||
|
||||
process.on('SIGTERM', toExit);
|
||||
process.on('exit', toExit);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
input: 'src/main.js',
|
||||
output: {
|
||||
sourcemap: true,
|
||||
format: 'iife',
|
||||
name: 'app',
|
||||
file: 'dist/bundle.js'
|
||||
},
|
||||
plugins: [
|
||||
image({
|
||||
include: './src/assets/images/**'
|
||||
}),
|
||||
svelte({
|
||||
compilerOptions: {
|
||||
// enable run-time checks when not in production
|
||||
dev: !production
|
||||
}
|
||||
}),
|
||||
postcss({
|
||||
minimize: true,
|
||||
plugins: [
|
||||
url({
|
||||
url: "inline"
|
||||
})
|
||||
]
|
||||
}),
|
||||
// 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(),
|
||||
copy({
|
||||
targets: [
|
||||
{ src: 'src/index.html', dest: 'dist/' },
|
||||
]
|
||||
}),
|
||||
|
||||
// In dev mode, call `npm run start` once
|
||||
// the bundle has been generated
|
||||
!production && serve(),
|
||||
|
||||
// Watch the `dist` directory and refresh the
|
||||
// browser on changes when not in production
|
||||
!production && livereload('dist'),
|
||||
|
||||
// If we're building for production (npm run build
|
||||
// instead of npm run dev), minify
|
||||
production && terser()
|
||||
],
|
||||
watch: {
|
||||
clearScreen: false
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,121 @@
|
||||
// @ts-check
|
||||
|
||||
/** This script modifies the project to support TS code in .svelte files like:
|
||||
|
||||
<script lang="ts">
|
||||
export let name: string;
|
||||
</script>
|
||||
|
||||
As well as validating the code for CI.
|
||||
*/
|
||||
|
||||
/** To work on this script:
|
||||
rm -rf test-template template && git clone sveltejs/template test-template && node scripts/setupTypeScript.js test-template
|
||||
*/
|
||||
|
||||
const fs = require("fs")
|
||||
const path = require("path")
|
||||
const { argv } = require("process")
|
||||
|
||||
const projectRoot = argv[2] || path.join(__dirname, "..")
|
||||
|
||||
// Add deps to pkg.json
|
||||
const packageJSON = JSON.parse(fs.readFileSync(path.join(projectRoot, "package.json"), "utf8"))
|
||||
packageJSON.devDependencies = Object.assign(packageJSON.devDependencies, {
|
||||
"svelte-check": "^2.0.0",
|
||||
"svelte-preprocess": "^4.0.0",
|
||||
"@rollup/plugin-typescript": "^8.0.0",
|
||||
"typescript": "^4.0.0",
|
||||
"tslib": "^2.0.0",
|
||||
"@tsconfig/svelte": "^2.0.0"
|
||||
})
|
||||
|
||||
// Add script for checking
|
||||
packageJSON.scripts = Object.assign(packageJSON.scripts, {
|
||||
"check": "svelte-check --tsconfig ./tsconfig.json"
|
||||
})
|
||||
|
||||
// Write the package JSON
|
||||
fs.writeFileSync(path.join(projectRoot, "package.json"), JSON.stringify(packageJSON, null, " "))
|
||||
|
||||
// mv src/main.js to main.ts - note, we need to edit rollup.config.js for this too
|
||||
const beforeMainJSPath = path.join(projectRoot, "src", "main.js")
|
||||
const afterMainTSPath = path.join(projectRoot, "src", "main.ts")
|
||||
fs.renameSync(beforeMainJSPath, afterMainTSPath)
|
||||
|
||||
// Switch the app.svelte file to use TS
|
||||
const appSveltePath = path.join(projectRoot, "src", "App.svelte")
|
||||
let appFile = fs.readFileSync(appSveltePath, "utf8")
|
||||
appFile = appFile.replace("<script>", '<script lang="ts">')
|
||||
appFile = appFile.replace("export let name;", 'export let name: string;')
|
||||
fs.writeFileSync(appSveltePath, appFile)
|
||||
|
||||
// Edit rollup config
|
||||
const rollupConfigPath = path.join(projectRoot, "rollup.config.js")
|
||||
let rollupConfig = fs.readFileSync(rollupConfigPath, "utf8")
|
||||
|
||||
// Edit imports
|
||||
rollupConfig = rollupConfig.replace(`'rollup-plugin-terser';`, `'rollup-plugin-terser';
|
||||
import sveltePreprocess from 'svelte-preprocess';
|
||||
import typescript from '@rollup/plugin-typescript';`)
|
||||
|
||||
// Replace name of entry point
|
||||
rollupConfig = rollupConfig.replace(`'src/main.js'`, `'src/main.ts'`)
|
||||
|
||||
// Add preprocessor
|
||||
rollupConfig = rollupConfig.replace(
|
||||
'compilerOptions:',
|
||||
'preprocess: sveltePreprocess({ sourceMap: !production }),\n\t\t\tcompilerOptions:'
|
||||
);
|
||||
|
||||
// Add TypeScript
|
||||
rollupConfig = rollupConfig.replace(
|
||||
'commonjs(),',
|
||||
'commonjs(),\n\t\ttypescript({\n\t\t\tsourceMap: !production,\n\t\t\tinlineSources: !production\n\t\t}),'
|
||||
);
|
||||
fs.writeFileSync(rollupConfigPath, rollupConfig)
|
||||
|
||||
// Add TSConfig
|
||||
const tsconfig = `{
|
||||
"extends": "@tsconfig/svelte/tsconfig.json",
|
||||
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules/*", "__sapper__/*", "public/*"]
|
||||
}`
|
||||
const tsconfigPath = path.join(projectRoot, "tsconfig.json")
|
||||
fs.writeFileSync(tsconfigPath, tsconfig)
|
||||
|
||||
// Add global.d.ts
|
||||
const dtsPath = path.join(projectRoot, "src", "global.d.ts")
|
||||
fs.writeFileSync(dtsPath, `/// <reference types="svelte" />`)
|
||||
|
||||
// Delete this script, but not during testing
|
||||
if (!argv[2]) {
|
||||
// Remove the script
|
||||
fs.unlinkSync(path.join(__filename))
|
||||
|
||||
// Check for Mac's DS_store file, and if it's the only one left remove it
|
||||
const remainingFiles = fs.readdirSync(path.join(__dirname))
|
||||
if (remainingFiles.length === 1 && remainingFiles[0] === '.DS_store') {
|
||||
fs.unlinkSync(path.join(__dirname, '.DS_store'))
|
||||
}
|
||||
|
||||
// Check if the scripts folder is empty
|
||||
if (fs.readdirSync(path.join(__dirname)).length === 0) {
|
||||
// Remove the scripts folder
|
||||
fs.rmdirSync(path.join(__dirname))
|
||||
}
|
||||
}
|
||||
|
||||
// Adds the extension recommendation
|
||||
fs.mkdirSync(path.join(projectRoot, ".vscode"), { recursive: true })
|
||||
fs.writeFileSync(path.join(projectRoot, ".vscode", "extensions.json"), `{
|
||||
"recommendations": ["svelte.svelte-vscode"]
|
||||
}
|
||||
`)
|
||||
|
||||
console.log("Converted to TypeScript.")
|
||||
|
||||
if (fs.existsSync(path.join(projectRoot, "node_modules"))) {
|
||||
console.log("\nYou will need to re-run your dependency manager to get started.")
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<script>
|
||||
let name = "";
|
||||
let greeting = "";
|
||||
|
||||
function greet() {
|
||||
window.go.main.App.Greet(name).then((result) => {
|
||||
greeting = result;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<div id="logo"></div>
|
||||
<div id="input" data-wails-no-drag>
|
||||
<input id="name" type="text" bind:value={name}>
|
||||
<button class="button" on:click={greet}>Greet</button>
|
||||
</div>
|
||||
{#if greeting}
|
||||
<div id="result">{greeting}</div>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
<style>
|
||||
|
||||
main {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#result {
|
||||
margin-top: 1rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
-webkit-appearance: default-button;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
#name {
|
||||
border-radius: 3px;
|
||||
outline: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
#logo {
|
||||
width: 40%;
|
||||
height: 40%;
|
||||
padding-top: 20%;
|
||||
margin: auto;
|
||||
display: block;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("assets/images/logo-dark.svg");
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,93 @@
|
||||
Copyright 2016 The Nunito Project Authors (contact@sansoxygen.com),
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 551 436" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1.27527,0,0,1.27527,104.01,410.563)">
|
||||
<path d="M0,-51.891L14.429,-51.891L13.043,-21.183L22.568,-51.891L34.226,-51.891L34.084,-21.183L42.365,-51.891L56.794,-51.891L38.526,0L25.198,0L25.34,-32.45L15.211,0L1.919,0L0,-51.891Z" style="fill:white;fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(1.27527,0,0,1.27527,224.985,367.503)">
|
||||
<path d="M0,15.639L5.793,15.639L5.971,-3.589L0,15.639ZM-20.187,33.765L-0.675,-18.126L16.42,-18.126L20.08,33.765L5.437,33.765L5.509,26.123L-3.057,26.123L-5.332,33.765L-20.187,33.765Z" style="fill:white;fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.19929,-1.2596,-1.2596,-0.19929,332.323,396.949)">
|
||||
<path d="M-16.046,33.107L36.491,33.107L38.757,18.784L-13.785,18.82L-16.046,33.107Z" style="fill:white;fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(1.27527,0,0,1.27527,353.217,344.388)">
|
||||
<path d="M0,51.891L8.246,0L22.781,0L16.597,39.024L27.224,39.024L25.199,51.891L0,51.891Z" style="fill:white;fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(1.27527,0,0,1.27527,427.939,364.922)">
|
||||
<path d="M0,19.83C1.611,21.181 3.305,22.224 5.083,22.959C6.859,23.693 8.565,24.06 10.2,24.06C11.645,24.06 12.794,23.663 13.647,22.87C14.5,22.076 14.927,20.992 14.927,19.617C14.927,18.434 14.571,17.254 13.861,16.081C13.15,14.908 11.775,13.351 9.738,11.408C7.273,9.015 5.58,6.906 4.655,5.081C3.731,3.257 3.27,1.243 3.27,-0.96C3.27,-5.912 4.839,-9.846 7.979,-12.76C11.118,-15.674 15.377,-17.132 20.756,-17.132C22.936,-17.132 25.008,-16.889 26.975,-16.403C28.941,-15.917 30.943,-15.165 32.982,-14.146L30.92,-1.493C29.356,-2.583 27.834,-3.412 26.354,-3.981C24.872,-4.551 23.457,-4.835 22.106,-4.835C20.898,-4.835 19.943,-4.521 19.245,-3.894C18.546,-3.265 18.196,-2.406 18.196,-1.316C18.196,0.154 19.535,2.215 22.213,4.868C22.544,5.2 22.805,5.46 22.995,5.649C25.696,8.304 27.473,10.578 28.326,12.475C29.179,14.37 29.605,16.56 29.605,19.049C29.605,24.594 27.893,28.965 24.469,32.163C21.046,35.361 16.36,36.962 10.413,36.962C7.877,36.962 5.479,36.66 3.216,36.056C0.953,35.45 -0.948,34.615 -2.488,33.549L0,19.83Z" style="fill:white;fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(-166.599,4.57132,4.57132,166.599,147.403,167.648)">
|
||||
<path d="M0.883,-0.081L0.121,0.081L0.256,-0.063L0.883,-0.081Z" style="fill:url(#_Linear1);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(-106.443,-16.0669,-16.0669,106.443,428.19,188.033)">
|
||||
<path d="M0.878,-0.285L-0.073,0.71L-1.186,0.542L0.015,0.207L-0.846,0.077L0.355,-0.258L-0.505,-0.388L0.649,-0.71L0.878,-0.285Z" style="fill:url(#_Linear2);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(-114.484,-162.408,-162.408,114.484,333.291,285.804)">
|
||||
<path d="M0.44,-0.04L0.44,-0.04L0.44,-0.04L0.265,-0.056L0.177,0.437L-0.311,-0.255L0.262,-0.437L0.568,-0.437L0.44,-0.04Z" style="fill:url(#_Linear3);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(61.6919,58.8091,58.8091,-61.6919,258.631,180.413)">
|
||||
<path d="M0.5,0L0.5,-0L0.5,0L0.5,0Z" style="fill:url(#_Linear4);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(238.126,298.893,298.893,-238.126,113.516,-150.536)">
|
||||
<path d="M0.622,-0.115L0.761,-0.115L0.806,-0.013L0.826,0.182L0.622,-0.115Z" style="fill:url(#_Linear5);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(-369.529,-97.4118,-97.4118,369.529,582.38,94.027)">
|
||||
<path d="M0.467,0.005L0.49,0.062L0.271,-0.062L0.467,0.005Z" style="fill:url(#_Linear6);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(-496.156,-53.9751,-53.9751,496.156,367.888,125.085)">
|
||||
<path d="M0.2,0.001L0.219,-0.018L0.614,0.012L0.519,0.089L0.282,0.068L0.2,0.135L0.463,0.194L0.374,0.266L0.138,0.186L0.138,0.186L0.138,0.186L0.047,0.033L-0.131,-0.266L0.2,0.001Z" style="fill:url(#_Linear7);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(185.076,176.427,176.427,-185.076,153.446,80.1488)">
|
||||
<path d="M0.735,-0L0.735,-0L0.735,0L0.735,-0Z" style="fill:url(#_Linear8);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-3.46945e-18,-3.46945e-18,-1,0,-3.05761e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,0,-2.75467e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-1.11022e-16,-1.11022e-16,-1,0,-2.61861e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear4" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-5.55112e-17,-5.55112e-17,-1,0,-1.57562e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear5" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.801899,-0.59746,-0.59746,0.801899,1.3495,0.447457)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear6" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-2.77556e-17,-2.77556e-17,-1,0,-1.92826e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear7" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,0,9.68429e-07)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear8" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,0,1.43665e-07)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.8 KiB |
@@ -0,0 +1,24 @@
|
||||
|
||||
html {
|
||||
text-align: center;
|
||||
color: white;
|
||||
background-color: rgba(1,1,1,0.1);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: white;
|
||||
font-family: 'Nunito', -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local(''),
|
||||
url('./assets/fonts/nunito-v16-latin-regular.woff2') format('woff2')
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta name='viewport' content='width=device-width,initial-scale=1'>
|
||||
|
||||
<title>Svelte app</title>
|
||||
|
||||
<script defer src='bundle.js'></script>
|
||||
</head>
|
||||
|
||||
<body data-wails-drag>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,10 +1,9 @@
|
||||
|
||||
import App from './App.svelte';
|
||||
import './global.css';
|
||||
|
||||
const app = new App({
|
||||
target: document.body,
|
||||
props: {
|
||||
name: 'Wails User'
|
||||
}
|
||||
});
|
||||
|
||||
export default app;
|
||||
export default app;
|
||||
@@ -0,0 +1,9 @@
|
||||
module test
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/wailsapp/wails/v2 v2.0.0-alpha
|
||||
)
|
||||
|
||||
replace github.com/wailsapp/wails/v2 v2.0.0-alpha => {{.WailsDirectory}}
|
||||
@@ -0,0 +1,52 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"log"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/options/windows"
|
||||
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/logger"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
|
||||
//go:embed frontend/dist
|
||||
var assets embed.FS
|
||||
|
||||
func main() {
|
||||
|
||||
// Create application with options
|
||||
app := NewApp()
|
||||
|
||||
err := wails.Run(&options.App{
|
||||
Title: "",
|
||||
Width: 800,
|
||||
Height: 600,
|
||||
MinWidth: 400,
|
||||
MinHeight: 400,
|
||||
MaxWidth: 1280,
|
||||
MaxHeight: 1024,
|
||||
DisableResize: false,
|
||||
Fullscreen: false,
|
||||
Frameless: false,
|
||||
StartHidden: false,
|
||||
HideWindowOnClose: false,
|
||||
RGBA: 0x000000FF,
|
||||
Assets: assets,
|
||||
Windows: &windows.Options{
|
||||
WebviewIsTransparent: true,
|
||||
WindowIsTranslucent: true,
|
||||
DisableWindowIcon: true,
|
||||
},
|
||||
LogLevel: logger.DEBUG,
|
||||
OnStartup: app.startup,
|
||||
OnShutdown: app.shutdown,
|
||||
Bind: []interface{}{
|
||||
app,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "Basic Svelte + Rollup",
|
||||
"shortname": "svelte",
|
||||
"author": "Lea Anthony",
|
||||
"description": "Svelte template using rollup to bundle css, images and fonts",
|
||||
"helpurl": "https://github.com/wailsapp/wails"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "{{.ProjectName}}",
|
||||
"outputfilename": "{{.BinaryName}}",
|
||||
"assetdir": "frontend/dist",
|
||||
"frontend:build": "npm run build",
|
||||
"frontend:install": "npm install",
|
||||
"author": {
|
||||
"name": "{{.AuthorName}}",
|
||||
"email": "{{.AuthorEmail}}"
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
## About
|
||||
|
||||
This template uses vanilla JS / HTML and CSS. [Rollup](https://rollupjs.org/guide/en/) is used for processing and bundling the files.
|
||||
|
||||
## Building
|
||||
|
||||
To build this project in debug mode, use `wails build`. For production, use `wails build -production`.
|
||||
To generate a platform native package, add the `-package` flag.
|
||||
This template uses vanilla JS / HTML and CSS.
|
||||
|
||||
## Live Development
|
||||
|
||||
To run in live development mode, run `wails dev` in the project directory. In another terminal, go into the `frontend`
|
||||
directory and run `npm run dev`. The frontend dev server will run on http://localhost:5000. Connect to this
|
||||
in your browser and connect to your application.
|
||||
To run in live development mode, run `wails dev` in the project directory. In another terminal, go into the `frontend`
|
||||
directory and run `npm run dev`. The frontend dev server will run on http://localhost:5000. Connect to this in your
|
||||
browser and connect to your application.
|
||||
|
||||
## Building
|
||||
|
||||
For a production build, use `wails build`.
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// App struct
|
||||
type App struct {
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// NewApp creates a new App application struct
|
||||
func NewApp() *App {
|
||||
return &App{}
|
||||
}
|
||||
|
||||
// startup is called at application startup
|
||||
func (b *App) startup(ctx context.Context) {
|
||||
// Perform your setup here
|
||||
b.ctx = ctx
|
||||
}
|
||||
|
||||
// shutdown is called at application termination
|
||||
func (b *App) shutdown(ctx context.Context) {
|
||||
// Perform your teardown here
|
||||
}
|
||||
|
||||
// Greet returns a greeting for the given name
|
||||
func (b *App) Greet(name string) string {
|
||||
return fmt.Sprintf("Hello %s!", name)
|
||||
}
|
||||
@@ -1,34 +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{}
|
||||
}
|
||||
|
||||
// startup is called at application startup
|
||||
func (b *Basic) startup(runtime *wails.Runtime) {
|
||||
// Perform your setup here
|
||||
b.runtime = runtime
|
||||
runtime.Window.SetTitle("{{.ProjectName}}")
|
||||
}
|
||||
|
||||
// shutdown is called at application termination
|
||||
func (b *Basic) shutdown() {
|
||||
// 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)
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
Copyright 2016 The Nunito Project Authors (contact@sansoxygen.com),
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 551 436" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
xml:space="preserve"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1.27527,0,0,1.27527,104.01,410.563)">
|
||||
<path d="M0,-51.891L14.429,-51.891L13.043,-21.183L22.568,-51.891L34.226,-51.891L34.084,-21.183L42.365,-51.891L56.794,-51.891L38.526,0L25.198,0L25.34,-32.45L15.211,0L1.919,0L0,-51.891Z"
|
||||
style="fill:white;fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(1.27527,0,0,1.27527,224.985,367.503)">
|
||||
<path d="M0,15.639L5.793,15.639L5.971,-3.589L0,15.639ZM-20.187,33.765L-0.675,-18.126L16.42,-18.126L20.08,33.765L5.437,33.765L5.509,26.123L-3.057,26.123L-5.332,33.765L-20.187,33.765Z"
|
||||
style="fill:white;fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.19929,-1.2596,-1.2596,-0.19929,332.323,396.949)">
|
||||
<path d="M-16.046,33.107L36.491,33.107L38.757,18.784L-13.785,18.82L-16.046,33.107Z"
|
||||
style="fill:white;fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(1.27527,0,0,1.27527,353.217,344.388)">
|
||||
<path d="M0,51.891L8.246,0L22.781,0L16.597,39.024L27.224,39.024L25.199,51.891L0,51.891Z"
|
||||
style="fill:white;fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(1.27527,0,0,1.27527,427.939,364.922)">
|
||||
<path d="M0,19.83C1.611,21.181 3.305,22.224 5.083,22.959C6.859,23.693 8.565,24.06 10.2,24.06C11.645,24.06 12.794,23.663 13.647,22.87C14.5,22.076 14.927,20.992 14.927,19.617C14.927,18.434 14.571,17.254 13.861,16.081C13.15,14.908 11.775,13.351 9.738,11.408C7.273,9.015 5.58,6.906 4.655,5.081C3.731,3.257 3.27,1.243 3.27,-0.96C3.27,-5.912 4.839,-9.846 7.979,-12.76C11.118,-15.674 15.377,-17.132 20.756,-17.132C22.936,-17.132 25.008,-16.889 26.975,-16.403C28.941,-15.917 30.943,-15.165 32.982,-14.146L30.92,-1.493C29.356,-2.583 27.834,-3.412 26.354,-3.981C24.872,-4.551 23.457,-4.835 22.106,-4.835C20.898,-4.835 19.943,-4.521 19.245,-3.894C18.546,-3.265 18.196,-2.406 18.196,-1.316C18.196,0.154 19.535,2.215 22.213,4.868C22.544,5.2 22.805,5.46 22.995,5.649C25.696,8.304 27.473,10.578 28.326,12.475C29.179,14.37 29.605,16.56 29.605,19.049C29.605,24.594 27.893,28.965 24.469,32.163C21.046,35.361 16.36,36.962 10.413,36.962C7.877,36.962 5.479,36.66 3.216,36.056C0.953,35.45 -0.948,34.615 -2.488,33.549L0,19.83Z"
|
||||
style="fill:white;fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(-166.599,4.57132,4.57132,166.599,147.403,167.648)">
|
||||
<path d="M0.883,-0.081L0.121,0.081L0.256,-0.063L0.883,-0.081Z" style="fill:url(#_Linear1);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(-106.443,-16.0669,-16.0669,106.443,428.19,188.033)">
|
||||
<path d="M0.878,-0.285L-0.073,0.71L-1.186,0.542L0.015,0.207L-0.846,0.077L0.355,-0.258L-0.505,-0.388L0.649,-0.71L0.878,-0.285Z"
|
||||
style="fill:url(#_Linear2);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(-114.484,-162.408,-162.408,114.484,333.291,285.804)">
|
||||
<path d="M0.44,-0.04L0.44,-0.04L0.44,-0.04L0.265,-0.056L0.177,0.437L-0.311,-0.255L0.262,-0.437L0.568,-0.437L0.44,-0.04Z"
|
||||
style="fill:url(#_Linear3);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(61.6919,58.8091,58.8091,-61.6919,258.631,180.413)">
|
||||
<path d="M0.5,0L0.5,-0L0.5,0L0.5,0Z" style="fill:url(#_Linear4);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(238.126,298.893,298.893,-238.126,113.516,-150.536)">
|
||||
<path d="M0.622,-0.115L0.761,-0.115L0.806,-0.013L0.826,0.182L0.622,-0.115Z"
|
||||
style="fill:url(#_Linear5);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(-369.529,-97.4118,-97.4118,369.529,582.38,94.027)">
|
||||
<path d="M0.467,0.005L0.49,0.062L0.271,-0.062L0.467,0.005Z" style="fill:url(#_Linear6);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(-496.156,-53.9751,-53.9751,496.156,367.888,125.085)">
|
||||
<path d="M0.2,0.001L0.219,-0.018L0.614,0.012L0.519,0.089L0.282,0.068L0.2,0.135L0.463,0.194L0.374,0.266L0.138,0.186L0.138,0.186L0.138,0.186L0.047,0.033L-0.131,-0.266L0.2,0.001Z"
|
||||
style="fill:url(#_Linear7);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(185.076,176.427,176.427,-185.076,153.446,80.1488)">
|
||||
<path d="M0.735,-0L0.735,-0L0.735,0L0.735,-0Z" style="fill:url(#_Linear8);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,-3.46945e-18,-3.46945e-18,-1,0,-3.05761e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/>
|
||||
<stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,-1,0,-2.75467e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/>
|
||||
<stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,-1.11022e-16,-1.11022e-16,-1,0,-2.61861e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/>
|
||||
<stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear4" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,-5.55112e-17,-5.55112e-17,-1,0,-1.57562e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/>
|
||||
<stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear5" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-0.801899,-0.59746,-0.59746,0.801899,1.3495,0.447457)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/>
|
||||
<stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear6" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,-2.77556e-17,-2.77556e-17,-1,0,-1.92826e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/>
|
||||
<stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear7" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,-1,0,9.68429e-07)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/>
|
||||
<stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear8" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,-1,0,1.43665e-07)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/>
|
||||
<stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.2 KiB |
File diff suppressed because one or more lines are too long
@@ -1,21 +1,16 @@
|
||||
// Get input + focus
|
||||
let nameElement = document.getElementById("name");
|
||||
nameElement.focus();
|
||||
|
||||
import {ready} from '@wails/runtime';
|
||||
// Setup the greet function
|
||||
window.greet = function () {
|
||||
|
||||
ready( () => {
|
||||
// Get input + focus
|
||||
let nameElement = document.getElementById("name");
|
||||
nameElement.focus();
|
||||
// Get name
|
||||
let name = nameElement.value;
|
||||
|
||||
// Setup the greet function
|
||||
window.greet = function () {
|
||||
|
||||
// Get name
|
||||
let 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;
|
||||
});
|
||||
};
|
||||
});
|
||||
// Call App.Greet(name)
|
||||
window.go.main.App.Greet(name).then((result) => {
|
||||
// Update result with data back from App.Greet()
|
||||
document.getElementById("result").innerText = result;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/pkg/options/windows"
|
||||
"embed"
|
||||
"log"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/options/windows"
|
||||
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/logger"
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/mac"
|
||||
)
|
||||
|
||||
//go:embed frontend/src
|
||||
var assets embed.FS
|
||||
|
||||
func main() {
|
||||
|
||||
// Create application with options
|
||||
app := NewBasic()
|
||||
app := NewApp()
|
||||
|
||||
err := wails.Run(&options.App{
|
||||
Title: "{{.ProjectName}}",
|
||||
@@ -29,22 +32,16 @@ func main() {
|
||||
Frameless: false,
|
||||
StartHidden: false,
|
||||
HideWindowOnClose: false,
|
||||
DevTools: false,
|
||||
RGBA: 0x000000FF,
|
||||
RGBA: &options.RGBA{0, 0, 0, 255},
|
||||
Assets: assets,
|
||||
Windows: &windows.Options{
|
||||
WebviewIsTransparent: true,
|
||||
WindowBackgroundIsTranslucent: true,
|
||||
DisableWindowIcon: true,
|
||||
WebviewIsTransparent: false,
|
||||
WindowIsTranslucent: false,
|
||||
DisableWindowIcon: false,
|
||||
},
|
||||
Mac: &mac.Options{
|
||||
WebviewIsTransparent: true,
|
||||
WindowBackgroundIsTranslucent: true,
|
||||
TitleBar: mac.TitleBarHiddenInset(),
|
||||
Menu: menu.DefaultMacMenu(),
|
||||
},
|
||||
LogLevel: logger.DEBUG,
|
||||
Startup: app.startup,
|
||||
Shutdown: app.shutdown,
|
||||
LogLevel: logger.DEBUG,
|
||||
OnStartup: app.startup,
|
||||
OnShutdown: app.shutdown,
|
||||
Bind: []interface{}{
|
||||
app,
|
||||
},
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
{
|
||||
"name": "{{.ProjectName}}",
|
||||
"outputfilename": "{{.BinaryName}}",
|
||||
"html": "frontend/dist/index.html",
|
||||
"frontend:build": "npm run build",
|
||||
"frontend:install": "npm ci",
|
||||
"author": {
|
||||
"name": "{{.AuthorName}}",
|
||||
"email": "{{.AuthorEmail}}"
|
||||
}
|
||||
"name": "{{.ProjectName}}",
|
||||
"outputfilename": "{{.BinaryName}}",
|
||||
"assetdir": "frontend/src",
|
||||
"author": {
|
||||
"name": "{{.AuthorName}}",
|
||||
"email": "{{.AuthorEmail}}"
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
|
||||
"github.com/leaanthony/clir"
|
||||
"github.com/wailsapp/wails/v2/cmd/wails/internal/commands/build"
|
||||
"github.com/wailsapp/wails/v2/cmd/wails/internal/commands/debug"
|
||||
"github.com/wailsapp/wails/v2/cmd/wails/internal/commands/dev"
|
||||
"github.com/wailsapp/wails/v2/cmd/wails/internal/commands/doctor"
|
||||
"github.com/wailsapp/wails/v2/cmd/wails/internal/commands/generate"
|
||||
@@ -40,10 +39,6 @@ func main() {
|
||||
fatal(err.Error())
|
||||
}
|
||||
|
||||
err = debug.AddSubcommand(app, os.Stdout)
|
||||
if err != nil {
|
||||
fatal(err.Error())
|
||||
}
|
||||
err = doctor.AddSubcommand(app, os.Stdout)
|
||||
if err != nil {
|
||||
fatal(err.Error())
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
package main
|
||||
|
||||
var version = "v2.0.0-alpha.68"
|
||||
var version = "v2.0.0-alpha.73"
|
||||
|
||||
67
v2/go.mod
67
v2/go.mod
@@ -1,33 +1,86 @@
|
||||
module github.com/wailsapp/wails/v2
|
||||
|
||||
go 1.16
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver v1.5.0
|
||||
github.com/fatih/structtag v1.2.0
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/gabriel-vasile/mimetype v1.3.1
|
||||
github.com/go-git/go-billy/v5 v5.2.0 // indirect
|
||||
github.com/go-git/go-git/v5 v5.3.0
|
||||
github.com/gofiber/fiber/v2 v2.17.0
|
||||
github.com/gofiber/websocket/v2 v2.0.8
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/uuid v1.1.2 // indirect
|
||||
github.com/gorilla/websocket v1.4.1
|
||||
github.com/imdario/mergo v0.3.11
|
||||
github.com/imdario/mergo v0.3.12
|
||||
github.com/jackmordaunt/icns v1.0.0
|
||||
github.com/klauspost/compress v1.12.2 // indirect
|
||||
github.com/leaanthony/clir v1.0.4
|
||||
github.com/leaanthony/debme v1.2.1
|
||||
github.com/leaanthony/go-ansi-parser v1.0.1
|
||||
github.com/leaanthony/go-common-file-dialog v1.0.3
|
||||
github.com/leaanthony/go-webview2 v0.0.0-20210914103035-f00aa774a934
|
||||
github.com/leaanthony/gosod v1.0.1
|
||||
github.com/leaanthony/idgen v1.0.0
|
||||
github.com/leaanthony/slicer v1.5.0
|
||||
github.com/leaanthony/webview2runtime v1.1.0
|
||||
github.com/leaanthony/winicon v0.0.0-20200606125418-4419cea822a0
|
||||
github.com/leaanthony/winc v0.0.0-20210906113646-fd400754f6ba
|
||||
github.com/leaanthony/winicon v1.0.0
|
||||
github.com/matryer/is v1.4.0
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.4
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/tc-hib/winres v0.1.5
|
||||
github.com/tdewolff/minify v2.3.6+incompatible
|
||||
github.com/tdewolff/parse v2.3.4+incompatible // indirect
|
||||
github.com/tdewolff/test v1.0.6 // indirect
|
||||
github.com/tidwall/sjson v1.1.7
|
||||
github.com/tkrajina/typescriptify-golang-structs v0.1.6
|
||||
github.com/wailsapp/wails v1.16.6
|
||||
github.com/wzshiming/ctc v1.2.3
|
||||
github.com/xyproto/xpm v1.2.1
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202
|
||||
golang.org/x/sys v0.0.0-20210611083646-a4fc73990273
|
||||
golang.org/x/tools v0.0.0-20200902012652-d1954cc86c82
|
||||
github.com/ztrue/tracerr v0.3.0
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
|
||||
golang.org/x/mod v0.4.1 // indirect
|
||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed
|
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf
|
||||
golang.org/x/tools v0.1.0
|
||||
nhooyr.io/websocket v1.8.6
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.4.16 // indirect
|
||||
github.com/abadojack/whatlanggo v1.0.1 // indirect
|
||||
github.com/andybalholm/brotli v1.0.2 // indirect
|
||||
github.com/emirpasic/gods v1.12.0 // indirect
|
||||
github.com/fasthttp/websocket v0.0.0-20200320073529-1554a54587ab // indirect
|
||||
github.com/go-git/gcfg v1.5.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.5 // indirect
|
||||
github.com/google/go-cmp v0.5.5 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/jchv/go-winloader v0.0.0-20200815041850-dec1ee9a7fd5 // indirect
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
||||
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e // indirect
|
||||
github.com/mattn/go-runewidth v0.0.7 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||
github.com/savsgio/gotils v0.0.0-20200117113501-90175b0fbe3f // indirect
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.4.1 // indirect
|
||||
github.com/tidwall/gjson v1.8.0 // indirect
|
||||
github.com/tidwall/match v1.0.3 // indirect
|
||||
github.com/tidwall/pretty v1.1.0 // indirect
|
||||
github.com/tkrajina/go-reflector v0.5.4 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.28.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
github.com/wzshiming/winseq v0.0.0-20200112104235-db357dc107ae // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6 // indirect
|
||||
golang.org/x/text v0.3.6 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
)
|
||||
|
||||
225
v2/go.sum
225
v2/go.sum
@@ -1,18 +1,57 @@
|
||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
|
||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
|
||||
github.com/abadojack/whatlanggo v1.0.1 h1:19N6YogDnf71CTHm3Mp2qhYfkRdyvbgwWdd2EPxJRG4=
|
||||
github.com/abadojack/whatlanggo v1.0.1/go.mod h1:66WiQbSbJBIlOZMsvbKe5m6pzQovxCH9B/K8tQB2uoc=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||
github.com/andybalholm/brotli v1.0.2 h1:JKnhI/XQ75uFBTiuzXpzFrUriDPiZjlOSzh6wXogP0E=
|
||||
github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
|
||||
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||
github.com/fasthttp/websocket v0.0.0-20200320073529-1554a54587ab h1:9e2joQGp642wHGFP5m86SDptAavrdGBe8/x9DGEEAaI=
|
||||
github.com/fasthttp/websocket v0.0.0-20200320073529-1554a54587ab/go.mod h1:smsv/h4PBEBaU0XDTY5UwJTpZv69fQ0FfcLJr21mA6Y=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
|
||||
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gabriel-vasile/mimetype v1.3.1 h1:qevA6c2MtE1RorlScnixeG0VA1H4xrXyhyX3oWBynNQ=
|
||||
github.com/gabriel-vasile/mimetype v1.3.1/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
|
||||
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
|
||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-billy/v5 v5.2.0 h1:GcoouCP9J+5slw2uXAocL70z8ml4A8B/H8nEPt6CLPk=
|
||||
github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
||||
github.com/go-git/go-git/v5 v5.3.0 h1:8WKMtJR2j8RntEXR/uvTKagfEt4GYlwQ7mntE4+0GWc=
|
||||
github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
|
||||
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/colors v1.2.0/go.mod h1:miw1R2JIE19cclPxsXqNdzLZsk4DP4iF+m88bRc7kfM=
|
||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||
@@ -25,24 +64,58 @@ github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
|
||||
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
|
||||
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||
github.com/gofiber/fiber/v2 v2.17.0 h1:qP3PkGUbBB0i9iQh5E057XI1yO5CZigUxZhyUFYAFoM=
|
||||
github.com/gofiber/fiber/v2 v2.17.0/go.mod h1:iftruuHGkRYGEXVISmdD7HTYWyfS2Bh+Dkfq4n/1Owg=
|
||||
github.com/gofiber/websocket/v2 v2.0.8 h1:Hb4y6IxYZVMO0segROODXJiXVgVD3a6i7wnfot8kM6k=
|
||||
github.com/gofiber/websocket/v2 v2.0.8/go.mod h1:fv8HSGQX09sauNv9g5Xq8GeGAaahLFYQKKb4ZdT0x2w=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/jackmordaunt/icns v1.0.0 h1:RYSxplerf/l/DUd09AHtITwckkv/mqjVv4DjYdPmAMQ=
|
||||
github.com/jackmordaunt/icns v1.0.0/go.mod h1:7TTQVEuGzVVfOPPlLNHJIkzA6CoV7aH1Dv9dW351oOo=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jchv/go-winloader v0.0.0-20200815041850-dec1ee9a7fd5 h1:pdFFlHXY9tZXmJz+tRSm1DzYEH4ebha7cffmm607bMU=
|
||||
github.com/jchv/go-winloader v0.0.0-20200815041850-dec1ee9a7fd5/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.12.2 h1:2KCfW3I9M7nSc5wOqXAlW2v2U6v+w6cbjvbfp+OykW8=
|
||||
github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leaanthony/clir v1.0.4 h1:Dov2y9zWJmZr7CjaCe86lKa4b5CSxskGAt2yBkoDyiU=
|
||||
github.com/leaanthony/clir v1.0.4/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0=
|
||||
github.com/leaanthony/debme v1.1.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA=
|
||||
@@ -52,90 +125,208 @@ github.com/leaanthony/go-ansi-parser v1.0.1 h1:97v6c5kYppVsbScf4r/VZdXyQ21KQIfeQ
|
||||
github.com/leaanthony/go-ansi-parser v1.0.1/go.mod h1:7arTzgVI47srICYhvgUV4CGd063sGEeoSlych5yeSPM=
|
||||
github.com/leaanthony/go-common-file-dialog v1.0.3 h1:O0uGjKnWtdEADGrkg+TyAAbZylykMwwx/MNEXn9fp+Y=
|
||||
github.com/leaanthony/go-common-file-dialog v1.0.3/go.mod h1:TGhEc9eSJgRsupZ+iH1ZgAOnEo9zp05cRH2j08RPrF0=
|
||||
github.com/leaanthony/go-webview2 v0.0.0-20210914103035-f00aa774a934 h1:nK/JTPyJi5QRqYjVZjXgtN4/dhg2qtngoLxLDVn429k=
|
||||
github.com/leaanthony/go-webview2 v0.0.0-20210914103035-f00aa774a934/go.mod h1:lS5ds4bruPk9d7lzdF/OH31Z0YCerI6MmHNFGsWoUnM=
|
||||
github.com/leaanthony/gosod v1.0.1 h1:F+4c3DmEBfigi7oAswCV2RpQ+k4DcNbhuCZUGdBHacQ=
|
||||
github.com/leaanthony/gosod v1.0.1/go.mod h1:W8RyeSFBXu7RpIxPGEJfW4moSyGGEjlJMLV25wEbAdU=
|
||||
github.com/leaanthony/idgen v1.0.0 h1:IZreR+JGEzFV4yeVuBZA25gM0keUoFy+RDUldncQ+Jw=
|
||||
github.com/leaanthony/idgen v1.0.0/go.mod h1:4nBZnt8ml/f/ic/EVQuLxuj817RccT2fyrUaZFxrcVA=
|
||||
github.com/leaanthony/slicer v1.4.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
|
||||
github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0HtY=
|
||||
github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
|
||||
github.com/leaanthony/spinner v0.5.3/go.mod h1:oHlrvWicr++CVV7ALWYi+qHk/XNA91D9IJ48IqmpVUo=
|
||||
github.com/leaanthony/synx v0.1.0/go.mod h1:Iz7eybeeG8bdq640iR+CwYb8p+9EOsgMWghkSRyZcqs=
|
||||
github.com/leaanthony/webview2runtime v1.1.0 h1:N0pv55ift8XtqozIp4PNOtRCJ/Qdd/qzx80lUpalS4c=
|
||||
github.com/leaanthony/webview2runtime v1.1.0/go.mod h1:hH9GnWCve3DYzNaPOcPbhHQ7fodXR1QJNsnwixid4Tk=
|
||||
github.com/leaanthony/winicon v0.0.0-20200606125418-4419cea822a0 h1:FPGYnfxuuxqCZhrGq8nKjthEcYHgHmFbyY953Xv9cNI=
|
||||
github.com/leaanthony/winicon v0.0.0-20200606125418-4419cea822a0/go.mod h1:en5xhijl92aphrJdmRPlh4NI1L6wq3gEm0LpXAPghjU=
|
||||
github.com/leaanthony/winc v0.0.0-20210906113646-fd400754f6ba h1:JalbOARv2XoT3RtJg7XGKKYcp7IndycC7pccLlfVRZI=
|
||||
github.com/leaanthony/winc v0.0.0-20210906113646-fd400754f6ba/go.mod h1:KEbMsKoznsebyGHwLk5LqkFOxL5uXSRdvpP4+avmAMs=
|
||||
github.com/leaanthony/wincursor v0.1.0/go.mod h1:7TVwwrzSH/2Y9gLOGH+VhA+bZhoWXBRgbGNTMk+yimE=
|
||||
github.com/leaanthony/winicon v1.0.0 h1:ZNt5U5dY71oEoKZ97UVwJRT4e+5xo5o/ieKuHuk8NqQ=
|
||||
github.com/leaanthony/winicon v1.0.0/go.mod h1:en5xhijl92aphrJdmRPlh4NI1L6wq3gEm0LpXAPghjU=
|
||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e h1:9MlwzLdW7QSDrhDjFlsEYmxpFyIoXmYRon3dt0io31k=
|
||||
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
|
||||
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
|
||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 h1:acNfDZXmm28D2Yg/c3ALnZStzNaZMSagpbr96vY6Zjc=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/savsgio/gotils v0.0.0-20200117113501-90175b0fbe3f h1:PgA+Olipyj258EIEYnpFFONrrCcAIWNUNoFhUfMqAGY=
|
||||
github.com/savsgio/gotils v0.0.0-20200117113501-90175b0fbe3f/go.mod h1:lHhJedqxCoHN+zMtwGNTXWmF0u9Jt363FYRhV6g0CdY=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba/go.mod h1:iLnlXG2Pakcii2CU0cbY07DRCSvpWNa7nFxtevhOChk=
|
||||
github.com/tc-hib/winres v0.1.5 h1:2dA5yfjdoEA3UyRaOC92HNMt3jap66pLzoW4MjpC/0M=
|
||||
github.com/tc-hib/winres v0.1.5/go.mod h1:pe6dOR40VOrGz8PkzreVKNvEKnlE8t4yR8A8naL+t7A=
|
||||
github.com/tdewolff/minify v2.3.6+incompatible h1:2hw5/9ZvxhWLvBUnHE06gElGYz+Jv9R4Eys0XUzItYo=
|
||||
github.com/tdewolff/minify v2.3.6+incompatible/go.mod h1:9Ov578KJUmAWpS6NeZwRZyT56Uf6o3Mcz9CEsg8USYs=
|
||||
github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxpP46ghf0Qzh38=
|
||||
github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ=
|
||||
github.com/tdewolff/test v1.0.6 h1:76mzYJQ83Op284kMT+63iCNCI7NEERsIN8dLM+RiKr4=
|
||||
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
github.com/tidwall/gjson v1.8.0 h1:Qt+orfosKn0rbNTZqHYDqBrmm3UDA4KRkv70fDzG+PQ=
|
||||
github.com/tidwall/gjson v1.8.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
|
||||
github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE=
|
||||
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.1.0 h1:K3hMW5epkdAVwibsQEfR/7Zj0Qgt4DxtNumTq/VloO8=
|
||||
github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tidwall/sjson v1.1.7 h1:sgVPwu/yygHJ2m1pJDLgGM/h+1F5odx5Q9ljG3imRm8=
|
||||
github.com/tidwall/sjson v1.1.7/go.mod h1:w/yG+ezBeTdUxiKs5NcPicO9diP38nk96QBAbIIGeFs=
|
||||
github.com/tkrajina/go-reflector v0.5.4 h1:dS9aJEa/eYNQU/fwsb5CSiATOxcNyA/gG/A7a582D5s=
|
||||
github.com/tkrajina/go-reflector v0.5.4/go.mod h1:9PyLgEOzc78ey/JmQQHbW8cQJ1oucLlNQsg8yFvkVk8=
|
||||
github.com/tkrajina/typescriptify-golang-structs v0.1.6 h1:AlUeArKYvOdsl0wL7VKtRDgBqT7Hvk87w7hYGrITcqg=
|
||||
github.com/tkrajina/typescriptify-golang-structs v0.1.6/go.mod h1:mfb2iqie4FjTKHfbjjCp08SRphjYaM7f2LdfUcNP7wY=
|
||||
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
|
||||
github.com/valyala/fasthttp v1.26.0/go.mod h1:cmWIqlu99AO/RKcp1HWaViTqc57FswJOfYYdPJBl8BA=
|
||||
github.com/valyala/fasthttp v1.28.0 h1:ruVmTmZaBR5i67NqnjvvH5gEv0zwHfWtbjoyW98iho4=
|
||||
github.com/valyala/fasthttp v1.28.0/go.mod h1:cmWIqlu99AO/RKcp1HWaViTqc57FswJOfYYdPJBl8BA=
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/wailsapp/wails v1.16.6 h1:iN0tP0O/Gwr8SKWwgH4t+IqDlMCGeVquWoHTegk8JlQ=
|
||||
github.com/wailsapp/wails v1.16.6/go.mod h1:aADbAvTzZrKGd4Td7d1l4Dp5Hx7lLJEvVH7guIHoDf8=
|
||||
github.com/wzshiming/ctc v1.2.3 h1:q+hW3IQNsjIlOFBTGZZZeIXTElFM4grF4spW/errh/c=
|
||||
github.com/wzshiming/ctc v1.2.3/go.mod h1:2tVAtIY7SUyraSk0JxvwmONNPFL4ARavPuEsg5+KA28=
|
||||
github.com/wzshiming/winseq v0.0.0-20200112104235-db357dc107ae h1:tpXvBXC3hpQBDCc9OojJZCQMVRAbT3TTdUMP8WguXkY=
|
||||
github.com/wzshiming/winseq v0.0.0-20200112104235-db357dc107ae/go.mod h1:VTAq37rkGeV+WOybvZwjXiJOicICdpLCN8ifpISjK20=
|
||||
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
||||
github.com/xyproto/xpm v1.2.1 h1:trdvGjjWBsOOKzBBUPT6JvaIQM3acJEEYfbxN7M96wg=
|
||||
github.com/xyproto/xpm v1.2.1/go.mod h1:cMnesLsD0PBXLgjDfTDEaKr8XyTFsnP1QycSqRw7BiY=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/ztrue/tracerr v0.3.0 h1:lDi6EgEYhPYPnKcjsYzmWw4EkFEoA/gfe+I9Y5f+h6Y=
|
||||
github.com/ztrue/tracerr v0.3.0/go.mod h1:qEalzze4VN9O8tnhBXScfCrmoJo10o8TN5ciKjm6Mww=
|
||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6 h1:nfeHNc1nAqecKCy2FCy4HY+soOOe5sDLJ/gZLbx6GYI=
|
||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
||||
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I=
|
||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210611083646-a4fc73990273 h1:faDu4veV+8pcThn4fewv6TVlNCezafGoC1gM/mxQLbQ=
|
||||
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210611083646-a4fc73990273/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k=
|
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200902012652-d1954cc86c82 h1:shxDsb9Dz27xzk3A0DxP0JuJnZMpKrdg8+E14eiUAX4=
|
||||
golang.org/x/tools v0.0.0-20200902012652-d1954cc86c82/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/AlecAivazis/survey.v1 v1.8.4/go.mod h1:iBNOmqKz/NUbZx3bA+4hAGLRC7fSK7tgtVDT4tB22XA=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k=
|
||||
nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// +build debug
|
||||
//go:build dev
|
||||
// +build dev
|
||||
|
||||
package app
|
||||
|
||||
@@ -14,11 +15,6 @@ func (a *App) Init() error {
|
||||
// Indicate debug mode
|
||||
a.debug = true
|
||||
|
||||
if a.appType == "desktop" {
|
||||
// Enable dev tools
|
||||
a.options.DevTools = true
|
||||
}
|
||||
|
||||
// Set log levels
|
||||
loglevel := flag.String("loglevel", "debug", "Loglevel to use - Trace, Debug, Info, Warning, Error")
|
||||
flag.Parse()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build desktop && !server
|
||||
// +build desktop,!server
|
||||
|
||||
package app
|
||||
@@ -11,7 +12,6 @@ import (
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/internal/menumanager"
|
||||
"github.com/wailsapp/wails/v2/internal/messagedispatcher"
|
||||
"github.com/wailsapp/wails/v2/internal/runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/servicebus"
|
||||
"github.com/wailsapp/wails/v2/internal/signal"
|
||||
"github.com/wailsapp/wails/v2/internal/subsystem"
|
||||
@@ -46,12 +46,8 @@ type App struct {
|
||||
// This is our binding DB
|
||||
bindings *binding.Bindings
|
||||
|
||||
// Application Stores
|
||||
loglevelStore *runtime.Store
|
||||
appconfigStore *runtime.Store
|
||||
|
||||
// Startup/Shutdown
|
||||
startupCallback func(*runtime.Runtime)
|
||||
// OnStartup/OnShutdown
|
||||
startupCallback func(ctx context.Context)
|
||||
shutdownCallback func()
|
||||
}
|
||||
|
||||
@@ -69,7 +65,8 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
menuManager := menumanager.NewManager()
|
||||
|
||||
// Process the application menu
|
||||
menuManager.SetApplicationMenu(options.GetApplicationMenu(appoptions))
|
||||
appMenu := options.GetApplicationMenu(appoptions)
|
||||
menuManager.SetApplicationMenu(appMenu)
|
||||
|
||||
// Process context menus
|
||||
contextMenus := options.GetContextMenus(appoptions)
|
||||
@@ -86,7 +83,7 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
window := ffenestri.NewApplicationWithConfig(appoptions, myLogger, menuManager)
|
||||
|
||||
// Create binding exemptions - Ugly hack. There must be a better way
|
||||
bindingExemptions := []interface{}{appoptions.Startup, appoptions.Shutdown}
|
||||
bindingExemptions := []interface{}{appoptions.OnStartup, appoptions.OnShutdown, appoptions.OnDomReady}
|
||||
|
||||
result := &App{
|
||||
appType: "desktop",
|
||||
@@ -95,8 +92,8 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
logger: myLogger,
|
||||
bindings: binding.NewBindings(myLogger, appoptions.Bind, bindingExemptions),
|
||||
menuManager: menuManager,
|
||||
startupCallback: appoptions.Startup,
|
||||
shutdownCallback: appoptions.Shutdown,
|
||||
startupCallback: appoptions.OnStartup,
|
||||
shutdownCallback: appoptions.OnShutdown,
|
||||
}
|
||||
|
||||
result.options = appoptions
|
||||
@@ -144,12 +141,8 @@ func (a *App) Run() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Application Stores
|
||||
a.loglevelStore = a.runtime.GoRuntime().Store.New("wails:loglevel", a.options.LogLevel)
|
||||
a.appconfigStore = a.runtime.GoRuntime().Store.New("wails:appconfig", a.options)
|
||||
|
||||
// Start the logging subsystem
|
||||
log, err := subsystem.NewLog(a.servicebus, a.logger, a.loglevelStore)
|
||||
log, err := subsystem.NewLog(a.servicebus, a.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -206,7 +199,7 @@ func (a *App) Run() error {
|
||||
}
|
||||
|
||||
// Start the call subsystem
|
||||
callSubsystem, err := subsystem.NewCall(ctx, a.servicebus, a.logger, a.bindings.DB(), a.runtime.GoRuntime())
|
||||
callSubsystem, err := subsystem.NewCall(ctx, a.servicebus, a.logger, a.bindings.DB())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -254,7 +247,7 @@ func (a *App) Run() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Shutdown callback
|
||||
// OnShutdown callback
|
||||
if a.shutdownCallback != nil {
|
||||
a.shutdownCallback()
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
//go:build dev
|
||||
// +build dev
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/wailsapp/wails/runtime"
|
||||
"sync"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/bridge"
|
||||
@@ -14,7 +16,6 @@ import (
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/internal/messagedispatcher"
|
||||
"github.com/wailsapp/wails/v2/internal/runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/servicebus"
|
||||
"github.com/wailsapp/wails/v2/internal/signal"
|
||||
"github.com/wailsapp/wails/v2/internal/subsystem"
|
||||
@@ -50,7 +51,7 @@ type App struct {
|
||||
loglevelStore *runtime.Store
|
||||
appconfigStore *runtime.Store
|
||||
|
||||
// Startup/Shutdown
|
||||
// OnStartup/OnShutdown
|
||||
startupCallback func(*runtime.Runtime)
|
||||
shutdownCallback func()
|
||||
|
||||
@@ -86,15 +87,15 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
}
|
||||
|
||||
// Create binding exemptions - Ugly hack. There must be a better way
|
||||
bindingExemptions := []interface{}{appoptions.Startup, appoptions.Shutdown}
|
||||
bindingExemptions := []interface{}{appoptions.OnStartup, appoptions.OnShutdown, appoptions.OnDomReady}
|
||||
|
||||
result := &App{
|
||||
appType: "dev",
|
||||
bindings: binding.NewBindings(myLogger, appoptions.Bind, bindingExemptions),
|
||||
logger: myLogger,
|
||||
servicebus: servicebus.New(myLogger),
|
||||
startupCallback: appoptions.Startup,
|
||||
shutdownCallback: appoptions.Shutdown,
|
||||
startupCallback: appoptions.OnStartup,
|
||||
shutdownCallback: appoptions.OnShutdown,
|
||||
bridge: bridge.NewBridge(myLogger),
|
||||
menuManager: menuManager,
|
||||
}
|
||||
@@ -117,6 +118,7 @@ func (a *App) Run() error {
|
||||
var subsystemWaitGroup sync.WaitGroup
|
||||
parentContext := context.WithValue(context.Background(), "waitgroup", &subsystemWaitGroup)
|
||||
ctx, cancel := context.WithCancel(parentContext)
|
||||
defer cancel()
|
||||
|
||||
// Start the service bus
|
||||
a.servicebus.Debug()
|
||||
@@ -125,7 +127,7 @@ func (a *App) Run() error {
|
||||
return err
|
||||
}
|
||||
|
||||
runtimesubsystem, err := subsystem.NewRuntime(ctx, a.servicebus, a.logger, a.startupCallback, nil)
|
||||
runtimesubsystem, err := subsystem.NewRuntime(ctx, a.servicebus, a.logger, a.startupCallback)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -184,7 +186,7 @@ func (a *App) Run() error {
|
||||
}
|
||||
|
||||
// Start the call subsystem
|
||||
callSubsystem, err := subsystem.NewCall(ctx, a.servicebus, a.logger, a.bindings.DB(), a.runtime.GoRuntime())
|
||||
callSubsystem, err := subsystem.NewCall(ctx, a.servicebus, a.logger, a.bindings.DB())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -235,7 +237,7 @@ func (a *App) Run() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Shutdown callback
|
||||
// OnShutdown callback
|
||||
if a.shutdownCallback != nil {
|
||||
a.shutdownCallback()
|
||||
}
|
||||
|
||||
@@ -9,11 +9,18 @@ import (
|
||||
|
||||
func (a *App) PreflightChecks(options *options.App) error {
|
||||
|
||||
_ = options
|
||||
|
||||
// Process the webview2 runtime situation. We can pass a strategy in via the `webview2` flag for `wails build`.
|
||||
// This will determine how wv2runtime.Process will handle a lack of valid runtime.
|
||||
err := wv2runtime.Process()
|
||||
installedVersion, err := wv2runtime.Process()
|
||||
if installedVersion != nil {
|
||||
a.logger.Debug("WebView2 Runtime installed: Name: '%s' Version:'%s' Location:'%s'. Minimum version required: %s.",
|
||||
installedVersion.Name, installedVersion.Version, installedVersion.Location, wv2runtime.MinimumRuntimeVersion)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// +build !debug
|
||||
//go:build production
|
||||
// +build production
|
||||
|
||||
package app
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
//go:build server && !desktop
|
||||
// +build server,!desktop
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
@@ -12,7 +14,6 @@ import (
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/internal/messagedispatcher"
|
||||
"github.com/wailsapp/wails/v2/internal/runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/servicebus"
|
||||
"github.com/wailsapp/wails/v2/internal/subsystem"
|
||||
"github.com/wailsapp/wails/v2/internal/webserver"
|
||||
@@ -26,7 +27,6 @@ type App struct {
|
||||
call *subsystem.Call
|
||||
event *subsystem.Event
|
||||
log *subsystem.Log
|
||||
runtime *subsystem.Runtime
|
||||
|
||||
options *options.App
|
||||
|
||||
@@ -38,12 +38,8 @@ type App struct {
|
||||
|
||||
debug bool
|
||||
|
||||
// Application Stores
|
||||
loglevelStore *runtime.Store
|
||||
appconfigStore *runtime.Store
|
||||
|
||||
// Startup/Shutdown
|
||||
startupCallback func(*runtime.Runtime)
|
||||
// OnStartup/OnShutdown
|
||||
startupCallback func(ctx context.Context)
|
||||
shutdownCallback func()
|
||||
}
|
||||
|
||||
@@ -63,8 +59,8 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
logger: myLogger,
|
||||
servicebus: servicebus.New(myLogger),
|
||||
webserver: webserver.NewWebServer(myLogger),
|
||||
startupCallback: appoptions.Startup,
|
||||
shutdownCallback: appoptions.Shutdown,
|
||||
startupCallback: appoptions.OnStartup,
|
||||
shutdownCallback: appoptions.OnShutdown,
|
||||
}
|
||||
|
||||
// Initialise app
|
||||
@@ -109,19 +105,15 @@ func (a *App) Run() error {
|
||||
}
|
||||
|
||||
// Start the runtime
|
||||
runtime, err := subsystem.NewRuntime(a.servicebus, a.logger, a.startupCallback, a.shutdownCallback)
|
||||
runtime, err := subsystem.NewRuntime(a.servicebus, a.logger, a.startupCallback)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.runtime = runtime
|
||||
a.runtime.Start()
|
||||
|
||||
// Application Stores
|
||||
a.loglevelStore = a.runtime.GoRuntime().Store.New("wails:loglevel", a.options.LogLevel)
|
||||
a.appconfigStore = a.runtime.GoRuntime().Store.New("wails:appconfig", a.options)
|
||||
|
||||
a.servicebus.Start()
|
||||
log, err := subsystem.NewLog(a.servicebus, a.logger, a.loglevelStore)
|
||||
log, err := subsystem.NewLog(a.servicebus, a.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -135,7 +127,7 @@ func (a *App) Run() error {
|
||||
a.dispatcher.Start()
|
||||
|
||||
// Start the binding subsystem
|
||||
binding, err := subsystem.NewBinding(a.servicebus, a.logger, a.bindings, runtime.GoRuntime())
|
||||
binding, err := subsystem.NewBinding(a.servicebus, a.logger, a.bindings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
29
v2/internal/appng/app_default.go
Normal file
29
v2/internal/appng/app_default.go
Normal file
@@ -0,0 +1,29 @@
|
||||
//go:build !dev && !production && windows
|
||||
|
||||
package appng
|
||||
|
||||
import (
|
||||
"github.com/leaanthony/winc/w32"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// App defines a Wails application structure
|
||||
type App struct{}
|
||||
|
||||
func (a *App) Run() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateApp creates the app!
|
||||
func CreateApp(_ *options.App) (*App, error) {
|
||||
result := w32.MessageBox(0,
|
||||
`Wails applications will not build without the correct build tags.
|
||||
Please use "wails build" or press "OK" to open the documentation on how to use "go build"`,
|
||||
"Error",
|
||||
w32.MB_ICONERROR|w32.MB_OKCANCEL)
|
||||
if result == 1 {
|
||||
exec.Command("rundll32", "url.dll,FileProtocolHandler", "https://wails.io").Start()
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
166
v2/internal/appng/app_dev.go
Normal file
166
v2/internal/appng/app_dev.go
Normal file
@@ -0,0 +1,166 @@
|
||||
//go:build dev
|
||||
// +build dev
|
||||
|
||||
package appng
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/devserver"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/dispatcher"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/fs"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/internal/menumanager"
|
||||
"github.com/wailsapp/wails/v2/internal/project"
|
||||
"github.com/wailsapp/wails/v2/internal/signal"
|
||||
pkglogger "github.com/wailsapp/wails/v2/pkg/logger"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// App defines a Wails application structure
|
||||
type App struct {
|
||||
frontend frontend.Frontend
|
||||
logger *logger.Logger
|
||||
signal *signal.Manager
|
||||
options *options.App
|
||||
|
||||
menuManager *menumanager.Manager
|
||||
|
||||
// Indicates if the app is in debug mode
|
||||
debug bool
|
||||
|
||||
// OnStartup/OnShutdown
|
||||
startupCallback func(ctx context.Context)
|
||||
shutdownCallback func(ctx context.Context)
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func (a *App) Run() error {
|
||||
err := a.frontend.Run(a.ctx)
|
||||
if a.shutdownCallback != nil {
|
||||
a.shutdownCallback(a.ctx)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// CreateApp creates the app!
|
||||
func CreateApp(appoptions *options.App) (*App, error) {
|
||||
var err error
|
||||
|
||||
ctx := context.WithValue(context.Background(), "debug", true)
|
||||
|
||||
// Set up logger
|
||||
myLogger := logger.New(appoptions.Logger)
|
||||
myLogger.SetLogLevel(appoptions.LogLevel)
|
||||
|
||||
// Check for CLI Flags
|
||||
assetdir := flag.String("assetdir", "", "Directory to serve assets")
|
||||
loglevel := flag.String("loglevel", "debug", "Loglevel to use - Trace, Debug, Info, Warning, Error")
|
||||
flag.Parse()
|
||||
if assetdir != nil && *assetdir != "" {
|
||||
ctx = context.WithValue(ctx, "assetdir", *assetdir)
|
||||
}
|
||||
if loglevel != nil && *loglevel != "" {
|
||||
level, err := pkglogger.StringToLogLevel(*loglevel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
myLogger.SetLogLevel(level)
|
||||
}
|
||||
|
||||
// Attach logger to context
|
||||
ctx = context.WithValue(ctx, "logger", myLogger)
|
||||
|
||||
// Preflight checks
|
||||
err = PreflightChecks(appoptions, myLogger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Merge default options
|
||||
options.MergeDefaults(appoptions)
|
||||
|
||||
var menuManager *menumanager.Manager
|
||||
|
||||
// Process the application menu
|
||||
if appoptions.Menu != nil {
|
||||
// Create the menu manager
|
||||
menuManager = menumanager.NewManager()
|
||||
err = menuManager.SetApplicationMenu(appoptions.Menu)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Create binding exemptions - Ugly hack. There must be a better way
|
||||
bindingExemptions := []interface{}{appoptions.OnStartup, appoptions.OnShutdown, appoptions.OnDomReady}
|
||||
appBindings := binding.NewBindings(myLogger, appoptions.Bind, bindingExemptions)
|
||||
|
||||
err = generateBindings(appBindings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
eventHandler := runtime.NewEvents(myLogger)
|
||||
ctx = context.WithValue(ctx, "events", eventHandler)
|
||||
messageDispatcher := dispatcher.NewDispatcher(myLogger, appBindings, eventHandler)
|
||||
|
||||
// Create the frontends and register to event handler
|
||||
desktopFrontend := desktop.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher)
|
||||
appFrontend := devserver.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher, menuManager, desktopFrontend)
|
||||
eventHandler.AddFrontend(appFrontend)
|
||||
eventHandler.AddFrontend(desktopFrontend)
|
||||
|
||||
result := &App{
|
||||
ctx: ctx,
|
||||
frontend: appFrontend,
|
||||
logger: myLogger,
|
||||
menuManager: menuManager,
|
||||
startupCallback: appoptions.OnStartup,
|
||||
shutdownCallback: appoptions.OnShutdown,
|
||||
debug: true,
|
||||
}
|
||||
|
||||
result.options = appoptions
|
||||
|
||||
return result, nil
|
||||
|
||||
}
|
||||
|
||||
func generateBindings(bindings *binding.Bindings) error {
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
projectConfig, err := project.Load(cwd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
targetDir := filepath.Join(projectConfig.WailsJSDir, "wailsjs", "go")
|
||||
err = os.RemoveAll(targetDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = fs.MkDirs(targetDir)
|
||||
modelsFile := filepath.Join(targetDir, "models.ts")
|
||||
err = bindings.WriteTS(modelsFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write backend method wrappers
|
||||
bindingsFilename := filepath.Join(targetDir, "bindings.js")
|
||||
err = bindings.GenerateBackendJS(bindingsFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
101
v2/internal/appng/app_production.go
Normal file
101
v2/internal/appng/app_production.go
Normal file
@@ -0,0 +1,101 @@
|
||||
//go:build production
|
||||
// +build production
|
||||
|
||||
package appng
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/dispatcher"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/internal/menumanager"
|
||||
"github.com/wailsapp/wails/v2/internal/signal"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
|
||||
// App defines a Wails application structure
|
||||
type App struct {
|
||||
frontend frontend.Frontend
|
||||
logger *logger.Logger
|
||||
signal *signal.Manager
|
||||
options *options.App
|
||||
|
||||
menuManager *menumanager.Manager
|
||||
|
||||
// Indicates if the app is in debug mode
|
||||
debug bool
|
||||
|
||||
// OnStartup/OnShutdown
|
||||
startupCallback func(ctx context.Context)
|
||||
shutdownCallback func(ctx context.Context)
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func (a *App) Run() error {
|
||||
err := a.frontend.Run(a.ctx)
|
||||
if a.shutdownCallback != nil {
|
||||
a.shutdownCallback(a.ctx)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// CreateApp creates the app!
|
||||
func CreateApp(appoptions *options.App) (*App, error) {
|
||||
var err error
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Merge default options
|
||||
options.MergeDefaults(appoptions)
|
||||
|
||||
// Set up logger
|
||||
myLogger := logger.New(appoptions.Logger)
|
||||
myLogger.SetLogLevel(appoptions.LogLevel)
|
||||
|
||||
// Preflight Checks
|
||||
err = PreflightChecks(appoptions, myLogger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create the menu manager
|
||||
menuManager := menumanager.NewManager()
|
||||
|
||||
// Process the application menu
|
||||
if appoptions.Menu != nil {
|
||||
err = menuManager.SetApplicationMenu(appoptions.Menu)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Create binding exemptions - Ugly hack. There must be a better way
|
||||
bindingExemptions := []interface{}{appoptions.OnStartup, appoptions.OnShutdown, appoptions.OnDomReady}
|
||||
appBindings := binding.NewBindings(myLogger, appoptions.Bind, bindingExemptions)
|
||||
eventHandler := runtime.NewEvents(myLogger)
|
||||
ctx = context.WithValue(ctx, "events", eventHandler)
|
||||
messageDispatcher := dispatcher.NewDispatcher(myLogger, appBindings, eventHandler)
|
||||
|
||||
appFrontend := desktop.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher)
|
||||
eventHandler.AddFrontend(appFrontend)
|
||||
|
||||
result := &App{
|
||||
ctx: ctx,
|
||||
frontend: appFrontend,
|
||||
logger: myLogger,
|
||||
menuManager: menuManager,
|
||||
startupCallback: appoptions.OnStartup,
|
||||
shutdownCallback: appoptions.OnShutdown,
|
||||
debug: false,
|
||||
}
|
||||
|
||||
result.options = appoptions
|
||||
|
||||
result.ctx = context.WithValue(result.ctx, "debug", result.debug)
|
||||
|
||||
return result, nil
|
||||
|
||||
}
|
||||
27
v2/internal/appng/app_windows.go
Normal file
27
v2/internal/appng/app_windows.go
Normal file
@@ -0,0 +1,27 @@
|
||||
//go:build windows
|
||||
|
||||
package appng
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/internal/ffenestri/windows/wv2runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
|
||||
func PreflightChecks(options *options.App, logger *logger.Logger) error {
|
||||
|
||||
_ = options
|
||||
|
||||
// Process the webview2 runtime situation. We can pass a strategy in via the `webview2` flag for `wails build`.
|
||||
// This will determine how wv2runtime.Process will handle a lack of valid runtime.
|
||||
installedVersion, err := wv2runtime.Process()
|
||||
if installedVersion != nil {
|
||||
logger.Debug("WebView2 Runtime installed: Name: '%s' Version:'%s' Location:'%s'. Minimum version required: %s.",
|
||||
installedVersion.Name, installedVersion.Version, installedVersion.Location, wv2runtime.MinimumRuntimeVersion)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
{
|
||||
"name": "backend",
|
||||
"name": "go",
|
||||
"version": "1.0.0",
|
||||
"description": "Package to wrap backend method calls",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"description": "Package to wrap your bound go methods",
|
||||
"main": "bindings.js",
|
||||
"types": "bindings.d.ts",
|
||||
"scripts": {},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
||||
@@ -2,12 +2,12 @@ package binding
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tkrajina/typescriptify-golang-structs/typescriptify"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/leaanthony/slicer"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
)
|
||||
|
||||
@@ -15,15 +15,25 @@ type Bindings struct {
|
||||
db *DB
|
||||
logger logger.CustomLogger
|
||||
exemptions slicer.StringSlicer
|
||||
|
||||
// Typescript writer
|
||||
converter *typescriptify.TypeScriptify
|
||||
}
|
||||
|
||||
// NewBindings returns a new Bindings object
|
||||
func NewBindings(logger *logger.Logger, structPointersToBind []interface{}, exemptions []interface{}) *Bindings {
|
||||
result := &Bindings{
|
||||
db: newDB(),
|
||||
logger: logger.CustomLogger("Bindings"),
|
||||
db: newDB(),
|
||||
logger: logger.CustomLogger("Bindings"),
|
||||
converter: typescriptify.New(),
|
||||
}
|
||||
|
||||
// No backups
|
||||
result.converter.WithBackupDir("")
|
||||
|
||||
// Hack for TS compilation error
|
||||
result.converter.AddImport("export {};")
|
||||
|
||||
for _, exemption := range exemptions {
|
||||
if exemptions == nil {
|
||||
continue
|
||||
@@ -65,6 +75,11 @@ func (b *Bindings) Add(structPtr interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bindings) WriteTS(filename string) error {
|
||||
println("WriteTS to:", filename)
|
||||
return b.converter.ConvertToFile(filename)
|
||||
}
|
||||
|
||||
func (b *Bindings) DB() *DB {
|
||||
return b.db
|
||||
}
|
||||
|
||||
@@ -4,20 +4,18 @@ import (
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"log"
|
||||
"github.com/wailsapp/wails/v2/internal/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/fs"
|
||||
|
||||
"github.com/leaanthony/slicer"
|
||||
)
|
||||
|
||||
//go:embed assets/package.json
|
||||
var packageJSON []byte
|
||||
|
||||
func (b *Bindings) GenerateBackendJS() {
|
||||
func (b *Bindings) GenerateBackendJS(targetfile string) error {
|
||||
|
||||
store := b.db.store
|
||||
var output bytes.Buffer
|
||||
@@ -26,7 +24,7 @@ func (b *Bindings) GenerateBackendJS() {
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
const backend = {`)
|
||||
const go = {`)
|
||||
output.WriteString("\n")
|
||||
|
||||
var sortedPackageNames slicer.StringSlicer
|
||||
@@ -84,7 +82,7 @@ const backend = {`)
|
||||
argsString := args.Join(", ")
|
||||
output.WriteString(fmt.Sprintf(" \"%s\": (%s) => {", methodName, argsString))
|
||||
output.WriteString("\n")
|
||||
output.WriteString(fmt.Sprintf(" return window.backend.%s.%s.%s(%s);", packageName, structName, methodName, argsString))
|
||||
output.WriteString(fmt.Sprintf(" return window.go.%s.%s.%s(%s);", packageName, structName, methodName, argsString))
|
||||
output.WriteString("\n")
|
||||
output.WriteString(fmt.Sprintf(" },"))
|
||||
output.WriteString("\n")
|
||||
@@ -100,35 +98,19 @@ const backend = {`)
|
||||
})
|
||||
|
||||
output.WriteString(`};
|
||||
export default backend;`)
|
||||
export default go;`)
|
||||
output.WriteString("\n")
|
||||
|
||||
// TODO: Make this configurable in wails.json
|
||||
dirname, err := fs.RelativeToCwd("frontend/src/backend")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if !fs.DirExists(dirname) {
|
||||
err := fs.MkDirs(dirname)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
packageJsonFile := filepath.Join(dirname, "package.json")
|
||||
dir := filepath.Dir(targetfile)
|
||||
packageJsonFile := filepath.Join(dir, "package.json")
|
||||
if !fs.FileExists(packageJsonFile) {
|
||||
err := os.WriteFile(packageJsonFile, packageJSON, 0755)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
filename := filepath.Join(dirname, "index.js")
|
||||
err = os.WriteFile(filename, output.Bytes(), 0755)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return os.WriteFile(targetfile, output.Bytes(), 0755)
|
||||
}
|
||||
|
||||
func goTypeToJSDocType(input string) string {
|
||||
@@ -150,6 +132,9 @@ func goTypeToJSDocType(input string) string {
|
||||
arrayType := goTypeToJSDocType(input[2:])
|
||||
return "Array.<" + arrayType + ">"
|
||||
default:
|
||||
if strings.ContainsRune(input, '.') {
|
||||
return strings.Split(input, ".")[1]
|
||||
}
|
||||
return "any"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +77,24 @@ func (b *Bindings) getMethods(value interface{}) ([]*BoundMethod, error) {
|
||||
for inputIndex := 0; inputIndex < inputParamCount; inputIndex++ {
|
||||
input := methodType.In(inputIndex)
|
||||
thisParam := newParameter("", input)
|
||||
|
||||
// Process struct pointer params
|
||||
if input.Kind() == reflect.Ptr {
|
||||
if input.Elem().Kind() == reflect.Struct {
|
||||
typ := input.Elem()
|
||||
a := reflect.New(typ)
|
||||
s := reflect.Indirect(a).Interface()
|
||||
b.converter.Add(s)
|
||||
}
|
||||
}
|
||||
|
||||
// Process struct params
|
||||
if input.Kind() == reflect.Struct {
|
||||
a := reflect.New(input)
|
||||
s := reflect.Indirect(a).Interface()
|
||||
b.converter.Add(s)
|
||||
}
|
||||
|
||||
inputs = append(inputs, thisParam)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package bridge
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
)
|
||||
|
||||
type BridgeClient struct {
|
||||
@@ -27,22 +27,30 @@ func (b BridgeClient) Quit() {
|
||||
|
||||
func (b BridgeClient) NotifyEvent(message string) {
|
||||
b.session.sendMessage("n" + message)
|
||||
b.session.log.Info("NotifyEvent: %s", message)
|
||||
b.session.log.Info("Notify: %s", message)
|
||||
}
|
||||
|
||||
func (b BridgeClient) CallResult(message string) {
|
||||
b.session.sendMessage("c" + message)
|
||||
}
|
||||
|
||||
func (b BridgeClient) OpenDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
||||
func (b BridgeClient) OpenFileDialog(dialogOptions runtime.OpenDialogOptions, callbackID string) {
|
||||
// Handled by dialog_client
|
||||
}
|
||||
|
||||
func (b BridgeClient) SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string) {
|
||||
func (b BridgeClient) OpenMultipleFilesDialog(dialogOptions runtime.OpenDialogOptions, callbackID string) {
|
||||
// Handled by dialog_client
|
||||
}
|
||||
|
||||
func (b BridgeClient) MessageDialog(dialogOptions *dialog.MessageDialog, callbackID string) {
|
||||
func (b BridgeClient) OpenDirectoryDialog(dialogOptions runtime.OpenDialogOptions, callbackID string) {
|
||||
// Handled by dialog_client
|
||||
}
|
||||
|
||||
func (b BridgeClient) SaveDialog(dialogOptions runtime.SaveDialogOptions, callbackID string) {
|
||||
// Handled by dialog_client
|
||||
}
|
||||
|
||||
func (b BridgeClient) MessageDialog(dialogOptions runtime.MessageDialogOptions, callbackID string) {
|
||||
// Handled by dialog_client
|
||||
}
|
||||
|
||||
@@ -110,8 +118,8 @@ func (b BridgeClient) DarkModeEnabled(callbackID string) {
|
||||
b.session.log.Info("DarkModeEnabled unsupported in Bridge mode")
|
||||
}
|
||||
|
||||
func (b BridgeClient) SetApplicationMenu(menuJSON string) {
|
||||
b.session.log.Info("SetApplicationMenu unsupported in Bridge mode")
|
||||
func (b BridgeClient) MenuSetApplicationMenu(menuJSON string) {
|
||||
b.session.log.Info("MenuSetApplicationMenu unsupported in Bridge mode")
|
||||
}
|
||||
|
||||
func (b BridgeClient) SetTrayMenu(trayMenuJSON string) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package bridge
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -11,7 +12,6 @@ import (
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
|
||||
"github.com/leaanthony/slicer"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
)
|
||||
|
||||
type DialogClient struct {
|
||||
@@ -37,13 +37,17 @@ func (d *DialogClient) NotifyEvent(message string) {
|
||||
func (d *DialogClient) CallResult(message string) {
|
||||
}
|
||||
|
||||
func (d *DialogClient) OpenDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
||||
func (d *DialogClient) OpenDirectoryDialog(options runtime.OpenDialogOptions, callbackID string) {
|
||||
}
|
||||
func (d *DialogClient) OpenFileDialog(options runtime.OpenDialogOptions, callbackID string) {
|
||||
}
|
||||
func (d *DialogClient) OpenMultipleFilesDialog(options runtime.OpenDialogOptions, callbackID string) {
|
||||
}
|
||||
|
||||
func (d *DialogClient) SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string) {
|
||||
func (d *DialogClient) SaveDialog(options runtime.SaveDialogOptions, callbackID string) {
|
||||
}
|
||||
|
||||
func (d *DialogClient) MessageDialog(dialogOptions *dialog.MessageDialog, callbackID string) {
|
||||
func (d *DialogClient) MessageDialog(options runtime.MessageDialogOptions, callbackID string) {
|
||||
|
||||
osa, err := exec.LookPath("osascript")
|
||||
if err != nil {
|
||||
@@ -54,23 +58,23 @@ func (d *DialogClient) MessageDialog(dialogOptions *dialog.MessageDialog, callba
|
||||
var btns slicer.StringSlicer
|
||||
defaultButton := ""
|
||||
cancelButton := ""
|
||||
for index, btn := range dialogOptions.Buttons {
|
||||
for index, btn := range options.Buttons {
|
||||
btns.Add(strconv.Quote(btn))
|
||||
if btn == dialogOptions.DefaultButton {
|
||||
if btn == options.DefaultButton {
|
||||
defaultButton = fmt.Sprintf("default button %d", index+1)
|
||||
}
|
||||
if btn == dialogOptions.CancelButton {
|
||||
if btn == options.CancelButton {
|
||||
cancelButton = fmt.Sprintf("cancel button %d", index+1)
|
||||
}
|
||||
}
|
||||
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() {
|
||||
out, err := exec.Command(osa, "-e", script).Output()
|
||||
if err != nil {
|
||||
// Assume user has pressed cancel button
|
||||
if dialogOptions.CancelButton != "" {
|
||||
d.dispatcher.DispatchMessage("DM" + callbackID + "|" + dialogOptions.CancelButton)
|
||||
if options.CancelButton != "" {
|
||||
d.dispatcher.DispatchMessage("DM" + callbackID + "|" + options.CancelButton)
|
||||
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())
|
||||
|
||||
7
v2/internal/ffenestri/README.md
Normal file
7
v2/internal/ffenestri/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## Windows
|
||||
|
||||
- Left and Right Win keys act the same
|
||||
- Accelerators will automatically add appropriate text into the menu items. This can be prevented by adding a tab
|
||||
character to the menu label
|
||||
- Tooltips + styling with font currently unsupported
|
||||
-
|
||||
@@ -46,7 +46,7 @@ extern void UpdateTrayMenuLabel(struct Application*, const char* JSON);
|
||||
extern void AddContextMenu(struct Application*, char *contextMenuJSON);
|
||||
extern void UpdateContextMenu(struct Application*, char *contextMenuJSON);
|
||||
extern void WebviewIsTransparent(struct Application*);
|
||||
extern void WindowBackgroundIsTranslucent(struct Application*);
|
||||
extern void WindowIsTranslucent(struct Application*);
|
||||
extern void* GetWindowHandle(struct Application*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -8,11 +8,11 @@ package ffenestri
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
goruntime "runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
)
|
||||
@@ -127,9 +127,9 @@ func (c *Client) WindowSetColour(colour int) {
|
||||
}
|
||||
|
||||
// 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 runtime.OpenDialogOptions, callbackID string) {
|
||||
filters := []string{}
|
||||
if runtime.GOOS == "darwin" {
|
||||
if goruntime.GOOS == "darwin" {
|
||||
for _, filter := range dialogOptions.Filters {
|
||||
filters = append(filters, strings.Split(filter.Pattern, ",")...)
|
||||
}
|
||||
@@ -150,11 +150,10 @@ func (c *Client) OpenFileDialog(dialogOptions *dialog.OpenDialog, callbackID str
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// 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 runtime.OpenDialogOptions, callbackID string) {
|
||||
filters := []string{}
|
||||
if runtime.GOOS == "darwin" {
|
||||
if goruntime.GOOS == "darwin" {
|
||||
for _, filter := range dialogOptions.Filters {
|
||||
filters = append(filters, strings.Split(filter.Pattern, ",")...)
|
||||
}
|
||||
@@ -166,7 +165,7 @@ func (c *Client) OpenDirectoryDialog(dialogOptions *dialog.OpenDialog, callbackI
|
||||
c.app.string2CString(dialogOptions.DefaultFilename),
|
||||
c.app.string2CString(dialogOptions.DefaultDirectory),
|
||||
c.app.bool2Cint(false), // Files
|
||||
c.app.bool2Cint(true), // Directories
|
||||
c.app.bool2Cint(true), // Directories
|
||||
c.app.bool2Cint(false), // Multiple
|
||||
c.app.bool2Cint(dialogOptions.ShowHiddenFiles),
|
||||
c.app.bool2Cint(dialogOptions.CanCreateDirectories),
|
||||
@@ -176,9 +175,9 @@ func (c *Client) OpenDirectoryDialog(dialogOptions *dialog.OpenDialog, callbackI
|
||||
}
|
||||
|
||||
// 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 runtime.OpenDialogOptions, callbackID string) {
|
||||
filters := []string{}
|
||||
if runtime.GOOS == "darwin" {
|
||||
if goruntime.GOOS == "darwin" {
|
||||
for _, filter := range dialogOptions.Filters {
|
||||
filters = append(filters, strings.Split(filter.Pattern, ",")...)
|
||||
}
|
||||
@@ -200,9 +199,9 @@ func (c *Client) OpenMultipleFilesDialog(dialogOptions *dialog.OpenDialog, callb
|
||||
}
|
||||
|
||||
// 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 *runtime.SaveDialogOptions, callbackID string) {
|
||||
filters := []string{}
|
||||
if runtime.GOOS == "darwin" {
|
||||
if goruntime.GOOS == "darwin" {
|
||||
for _, filter := range dialogOptions.Filters {
|
||||
filters = append(filters, strings.Split(filter.Pattern, ",")...)
|
||||
}
|
||||
@@ -220,7 +219,7 @@ func (c *Client) SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string)
|
||||
}
|
||||
|
||||
// MessageDialog will open a message dialog with the given options
|
||||
func (c *Client) MessageDialog(dialogOptions *dialog.MessageDialog, callbackID string) {
|
||||
func (c *Client) MessageDialog(dialogOptions runtime.MessageDialogOptions, callbackID string) {
|
||||
|
||||
// Sanity check button length
|
||||
if len(dialogOptions.Buttons) > 4 {
|
||||
|
||||
@@ -10,13 +10,12 @@ import "C"
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/leaanthony/go-common-file-dialog/cfd"
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
"golang.org/x/sys/windows"
|
||||
"log"
|
||||
"strconv"
|
||||
"syscall"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
)
|
||||
|
||||
@@ -131,7 +130,7 @@ func (c *Client) WindowSetColour(colour int) {
|
||||
C.SetColour(c.app.app, r, g, b, a)
|
||||
}
|
||||
|
||||
func convertFilters(filters []dialog.FileFilter) []cfd.FileFilter {
|
||||
func convertFilters(filters []runtime.FileFilter) []cfd.FileFilter {
|
||||
var result []cfd.FileFilter
|
||||
for _, filter := range filters {
|
||||
result = append(result, cfd.FileFilter(filter))
|
||||
@@ -140,7 +139,7 @@ func convertFilters(filters []dialog.FileFilter) []cfd.FileFilter {
|
||||
}
|
||||
|
||||
// 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 runtime.OpenDialogOptions, callbackID string) {
|
||||
config := cfd.DialogConfig{
|
||||
Folder: options.DefaultDirectory,
|
||||
FileFilters: convertFilters(options.Filters),
|
||||
@@ -166,7 +165,7 @@ func (c *Client) OpenFileDialog(options *dialog.OpenDialog, callbackID string) {
|
||||
}
|
||||
|
||||
// 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 runtime.OpenDialogOptions, callbackID string) {
|
||||
config := cfd.DialogConfig{
|
||||
Title: dialogOptions.Title,
|
||||
Role: "PickFolder",
|
||||
@@ -191,7 +190,7 @@ func (c *Client) OpenDirectoryDialog(dialogOptions *dialog.OpenDialog, callbackI
|
||||
}
|
||||
|
||||
// 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 runtime.OpenDialogOptions, callbackID string) {
|
||||
config := cfd.DialogConfig{
|
||||
Title: dialogOptions.Title,
|
||||
Role: "OpenMultipleFiles",
|
||||
@@ -222,7 +221,7 @@ func (c *Client) OpenMultipleFilesDialog(dialogOptions *dialog.OpenDialog, callb
|
||||
}
|
||||
|
||||
// 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 runtime.SaveDialogOptions, callbackID string) {
|
||||
saveDialog, err := cfd.NewSaveFileDialog(cfd.DialogConfig{
|
||||
Title: dialogOptions.Title,
|
||||
Role: "SaveFile",
|
||||
@@ -246,7 +245,7 @@ func (c *Client) SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string)
|
||||
}
|
||||
|
||||
// MessageDialog will open a message dialog with the given options
|
||||
func (c *Client) MessageDialog(options *dialog.MessageDialog, callbackID string) {
|
||||
func (c *Client) MessageDialog(options runtime.MessageDialogOptions, callbackID string) {
|
||||
|
||||
title, err := syscall.UTF16PtrFromString(options.Title)
|
||||
if err != nil {
|
||||
@@ -258,13 +257,13 @@ func (c *Client) MessageDialog(options *dialog.MessageDialog, callbackID string)
|
||||
}
|
||||
var flags uint32
|
||||
switch options.Type {
|
||||
case dialog.InfoDialog:
|
||||
case runtime.InfoDialog:
|
||||
flags = windows.MB_OK | windows.MB_ICONINFORMATION
|
||||
case dialog.ErrorDialog:
|
||||
case runtime.ErrorDialog:
|
||||
flags = windows.MB_ICONERROR | windows.MB_OK
|
||||
case dialog.QuestionDialog:
|
||||
case runtime.QuestionDialog:
|
||||
flags = windows.MB_YESNO
|
||||
case dialog.WarningDialog:
|
||||
case runtime.WarningDialog:
|
||||
flags = windows.MB_OK | windows.MB_ICONWARNING
|
||||
}
|
||||
|
||||
@@ -284,8 +283,8 @@ func (c *Client) DarkModeEnabled(callbackID string) {
|
||||
}
|
||||
|
||||
// SetApplicationMenu sets the application menu
|
||||
func (c *Client) SetApplicationMenu(applicationMenuJSON string) {
|
||||
C.SetApplicationMenu(c.app.app, c.app.string2CString(applicationMenuJSON))
|
||||
func (c *Client) SetApplicationMenu(_ string) {
|
||||
c.updateApplicationMenu()
|
||||
}
|
||||
|
||||
// SetTrayMenu sets the tray menu
|
||||
|
||||
@@ -102,6 +102,7 @@ struct Application {
|
||||
id mouseDownMonitor;
|
||||
id mouseUpMonitor;
|
||||
int activationPolicy;
|
||||
id pool;
|
||||
|
||||
// Window Data
|
||||
const char *title;
|
||||
@@ -134,7 +135,7 @@ struct Application {
|
||||
int fullSizeContent;
|
||||
int useToolBar;
|
||||
int hideToolbarSeparator;
|
||||
int windowBackgroundIsTranslucent;
|
||||
int WindowIsTranslucent;
|
||||
int hasURLHandlers;
|
||||
const char *startupURL;
|
||||
|
||||
@@ -292,8 +293,8 @@ void Show(struct Application *app) {
|
||||
);
|
||||
}
|
||||
|
||||
void WindowBackgroundIsTranslucent(struct Application *app) {
|
||||
app->windowBackgroundIsTranslucent = 1;
|
||||
void WindowIsTranslucent(struct Application *app) {
|
||||
app->WindowIsTranslucent = 1;
|
||||
}
|
||||
|
||||
// Sends messages to the backend
|
||||
@@ -560,7 +561,7 @@ void ToggleFullscreen(struct Application *app) {
|
||||
}
|
||||
|
||||
bool isFullScreen(struct Application *app) {
|
||||
int mask = (int)msg_reg(app->mainWindow, s("styleMask"));
|
||||
long mask = (long)msg_reg(app->mainWindow, s("styleMask"));
|
||||
bool result = (mask & NSWindowStyleMaskFullscreen) == NSWindowStyleMaskFullscreen;
|
||||
return result;
|
||||
}
|
||||
@@ -789,7 +790,7 @@ void MessageDialog(struct Application *app, char *callbackID, char *type, char *
|
||||
|
||||
// Run modal
|
||||
char *buttonPressed;
|
||||
int response = (int)msg_reg(alert, s("runModal"));
|
||||
long response = (long)msg_reg(alert, s("runModal"));
|
||||
if( response == NSAlertFirstButtonReturn ) {
|
||||
buttonPressed = button1;
|
||||
}
|
||||
@@ -1451,6 +1452,7 @@ void processDialogIcons(struct hashmap_s *hashmap, const unsigned char *dialogIc
|
||||
// Create the icon and add to the hashmap
|
||||
id imageData = ((id(*)(id, SEL, const unsigned char *, int))objc_msgSend)(c("NSData"), s("dataWithBytes:length:"), data, length);
|
||||
id dialogImage = ALLOC("NSImage");
|
||||
msg_reg(dialogImage, s("autorelease"));
|
||||
msg_id(dialogImage, s("initWithData:"), imageData);
|
||||
hashmap_put(hashmap, (const char *)name, strlen((const char *)name), dialogImage);
|
||||
}
|
||||
@@ -1532,7 +1534,7 @@ void Run(struct Application *app, int argc, char **argv) {
|
||||
applyWindowColour(app);
|
||||
|
||||
// Process translucency
|
||||
if (app->windowBackgroundIsTranslucent) {
|
||||
if (app->WindowIsTranslucent) {
|
||||
makeWindowBackgroundTranslucent(app);
|
||||
}
|
||||
|
||||
@@ -1622,7 +1624,9 @@ void Run(struct Application *app, int argc, char **argv) {
|
||||
MEMFREE(temp);
|
||||
|
||||
// Add code that sets up the initial state, EG: State Stores.
|
||||
temp = concat(internalCode, getInitialState(app));
|
||||
const char *initialState = getInitialState(app);
|
||||
temp = concat(internalCode, initialState);
|
||||
MEMFREE(initialState);
|
||||
MEMFREE(internalCode);
|
||||
internalCode = temp;
|
||||
|
||||
@@ -1723,7 +1727,10 @@ id createImageFromBase64Data(const char *data, bool isTemplateImage) {
|
||||
imageData = ((id(*)(id, SEL, id, int))objc_msgSend)(nsdata, s("initWithBase64EncodedString:options:"), str(BrokenImage), 0);
|
||||
}
|
||||
id result = ALLOC("NSImage");
|
||||
msg_reg(result, s("autorelease"));
|
||||
msg_id(result, s("initWithData:"), imageData);
|
||||
msg_reg(nsdata, s("release"));
|
||||
msg_reg(imageData, s("release"));
|
||||
|
||||
if( isTemplateImage ) {
|
||||
msg_bool(result, s("setTemplate:"), YES);
|
||||
@@ -1768,7 +1775,7 @@ void* NewApplication(const char *title, int width, int height, int resizable, in
|
||||
result->useToolBar = 0;
|
||||
result->hideToolbarSeparator = 0;
|
||||
result->appearance = NULL;
|
||||
result->windowBackgroundIsTranslucent = 0;
|
||||
result->WindowIsTranslucent = 0;
|
||||
|
||||
// Window data
|
||||
result->delegate = NULL;
|
||||
@@ -1801,6 +1808,8 @@ void* NewApplication(const char *title, int width, int height, int resizable, in
|
||||
|
||||
result->running = false;
|
||||
|
||||
result->pool = msg_reg(c("NSAutoreleasePool"), s("new"));
|
||||
|
||||
return (void*) result;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,8 +57,8 @@ func (a *Application) processPlatformSettings() error {
|
||||
}
|
||||
|
||||
// Check if window should be translucent
|
||||
if mac.WindowBackgroundIsTranslucent {
|
||||
C.WindowBackgroundIsTranslucent(a.app)
|
||||
if mac.WindowIsTranslucent {
|
||||
C.WindowIsTranslucent(a.app)
|
||||
}
|
||||
|
||||
// Process menu
|
||||
|
||||
@@ -138,7 +138,7 @@ void HideToolbarSeparator(struct Application* app);
|
||||
void DisableFrame(struct Application* app);
|
||||
void SetAppearance(struct Application* app, const char *);
|
||||
void WebviewIsTransparent(struct Application* app);
|
||||
void WindowBackgroundIsTranslucent(struct Application* app);
|
||||
void WindowIsTranslucent(struct Application* app);
|
||||
void SetTray(struct Application* app, const char *, const char *, const char *);
|
||||
//void SetContextMenus(struct Application* app, const char *);
|
||||
void AddTrayMenu(struct Application* app, const char *);
|
||||
|
||||
@@ -862,7 +862,7 @@ void UpdateTrayMenuLabel(struct Application* app, const char* JSON) {}
|
||||
void AddContextMenu(struct Application* app, char *contextMenuJSON) {}
|
||||
void UpdateContextMenu(struct Application* app, char *contextMenuJSON) {}
|
||||
void WebviewIsTransparent(struct Application* app) {}
|
||||
void WindowBackgroundIsTranslucent(struct Application* app) {}
|
||||
void WindowIsTranslucent(struct Application* app) {}
|
||||
void OpenDialog(struct Application* app, char *callbackID, char *title, char *filters, char *defaultFilename, char *defaultDir, int allowFiles, int allowDirs, int allowMultiple, int showHiddenFiles, int canCreateDirectories, int resolvesAliases, int treatPackagesAsDirectories) {}
|
||||
void SaveDialog(struct Application* app, char *callbackID, char *title, char *filters, char *defaultFilename, char *defaultDir, int showHiddenFiles, int canCreateDirectories, int treatPackagesAsDirectories) {}
|
||||
void MessageDialog(struct Application* app, char *callbackID, char *type, char *title, char *message, char *icon, char *button1, char *button2, char *button3, char *button4, char *defaultButton, char *cancelButton) {}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// License included in README.md
|
||||
|
||||
#include "ffenestri_windows.h"
|
||||
#include "shellscalingapi.h"
|
||||
#include "wv2ComHandler_windows.h"
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
@@ -27,6 +28,25 @@ void dispatch(dispatchFunction func) {
|
||||
PostThreadMessage(mainThread, WM_APP, 0, (LPARAM) new dispatchFunction(func));
|
||||
}
|
||||
|
||||
void processKeyPress(UINT key) {
|
||||
// Get state of Control
|
||||
bool controlPressed = GetKeyState(VK_CONTROL) >> 15 != 0;
|
||||
bool altPressed = GetKeyState(VK_MENU) >> 15 != 0;
|
||||
bool shiftPressed = GetKeyState(VK_SHIFT) >> 15 != 0;
|
||||
|
||||
// Save the modifier keys
|
||||
BYTE modState = 0;
|
||||
if ( GetKeyState(VK_CONTROL) >> 15 != 0 ) { modState |= 1; }
|
||||
if ( GetKeyState(VK_MENU) >> 15 != 0 ) { modState |= 2; }
|
||||
if ( GetKeyState(VK_SHIFT) >> 15 != 0 ) { modState |= 4; }
|
||||
if ( GetKeyState(VK_LWIN) >> 15 != 0 ) { modState |= 8; }
|
||||
if ( GetKeyState(VK_RWIN) >> 15 != 0 ) { modState |= 8; }
|
||||
|
||||
// Notify app of keypress
|
||||
handleKeypressInGo(key, modState);
|
||||
}
|
||||
|
||||
|
||||
LPWSTR cstrToLPWSTR(const char *cstr) {
|
||||
int wchars_num = MultiByteToWideChar( CP_UTF8 , 0 , cstr , -1, NULL , 0 );
|
||||
wchar_t* wstr = new wchar_t[wchars_num+1];
|
||||
@@ -42,6 +62,30 @@ char* LPWSTRToCstr(LPWSTR input) {
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
// Credit: https://building.enlyze.com/posts/writing-win32-apps-like-its-2020-part-3/
|
||||
typedef int (__cdecl *PGetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE,UINT*,UINT*);
|
||||
void getDPIForWindow(struct Application *app)
|
||||
{
|
||||
HMODULE hShcore = LoadLibraryW(L"shcore");
|
||||
if (hShcore)
|
||||
{
|
||||
PGetDpiForMonitor pGetDpiForMonitor = reinterpret_cast<PGetDpiForMonitor>(GetProcAddress(hShcore, "GetDpiForMonitor"));
|
||||
if (pGetDpiForMonitor)
|
||||
{
|
||||
HMONITOR hMonitor = MonitorFromWindow(app->window, MONITOR_DEFAULTTOPRIMARY);
|
||||
pGetDpiForMonitor(hMonitor, (MONITOR_DPI_TYPE)0, &app->dpix, &app->dpiy);
|
||||
}
|
||||
} else {
|
||||
// We couldn't get the window's DPI above, so get the DPI of the primary monitor
|
||||
// using an API that is available in all Windows versions.
|
||||
HDC hScreenDC = GetDC(0);
|
||||
app->dpix = GetDeviceCaps(hScreenDC, LOGPIXELSX);
|
||||
app->dpiy = GetDeviceCaps(hScreenDC, LOGPIXELSY);
|
||||
ReleaseDC(0, hScreenDC);
|
||||
}
|
||||
}
|
||||
|
||||
struct Application *NewApplication(const char *title, int width, int height, int resizable, int devtools, int fullscreen, int startHidden, int logLevel, int hideWindowOnClose) {
|
||||
|
||||
// Create application
|
||||
@@ -61,7 +105,7 @@ struct Application *NewApplication(const char *title, int width, int height, int
|
||||
result->logLevel = logLevel;
|
||||
result->hideWindowOnClose = hideWindowOnClose;
|
||||
result->webviewIsTranparent = false;
|
||||
result->windowBackgroundIsTranslucent = false;
|
||||
result->WindowIsTranslucent = false;
|
||||
result->disableWindowIcon = false;
|
||||
|
||||
// Min/Max Width/Height
|
||||
@@ -88,6 +132,9 @@ struct Application *NewApplication(const char *title, int width, int height, int
|
||||
// Used to remember the window location when going fullscreen
|
||||
result->previousPlacement = { sizeof(result->previousPlacement) };
|
||||
|
||||
// DPI
|
||||
result->dpix = result->dpiy = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -142,6 +189,14 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
|
||||
switch(msg) {
|
||||
|
||||
case WM_CREATE: {
|
||||
createApplicationMenu(hwnd);
|
||||
break;
|
||||
}
|
||||
case WM_COMMAND:
|
||||
menuClicked(LOWORD(wParam));
|
||||
break;
|
||||
|
||||
case WM_CLOSE: {
|
||||
DestroyWindow( app->window );
|
||||
break;
|
||||
@@ -165,36 +220,39 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_KEYDOWN:
|
||||
// This is needed because webview2 is sometimes not in focus
|
||||
// https://github.com/MicrosoftEdge/WebView2Feedback/issues/1541
|
||||
processKeyPress(wParam);
|
||||
break;
|
||||
case WM_GETMINMAXINFO: {
|
||||
// Exit early if this is called before the window is created.
|
||||
if ( app == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get pixel density
|
||||
HDC hDC = GetDC(NULL);
|
||||
double DPIScaleX = GetDeviceCaps(hDC, 88)/96.0;
|
||||
double DPIScaleY = GetDeviceCaps(hDC, 90)/96.0;
|
||||
ReleaseDC(NULL, hDC);
|
||||
// update DPI
|
||||
getDPIForWindow(app);
|
||||
double DPIScaleX = app->dpix/96.0;
|
||||
double DPIScaleY = app->dpiy/96.0;
|
||||
|
||||
RECT rcClient, rcWind;
|
||||
RECT rcWind;
|
||||
POINT ptDiff;
|
||||
GetClientRect(hwnd, &rcClient);
|
||||
GetWindowRect(hwnd, &rcWind);
|
||||
|
||||
int widthExtra = (rcWind.right - rcWind.left) - rcClient.right;
|
||||
int heightExtra = (rcWind.bottom - rcWind.top) - rcClient.bottom;
|
||||
int widthExtra = (rcWind.right - rcWind.left);
|
||||
int heightExtra = (rcWind.bottom - rcWind.top);
|
||||
|
||||
LPMINMAXINFO mmi = (LPMINMAXINFO) lParam;
|
||||
if (app->minWidth > 0 && app->minHeight > 0) {
|
||||
mmi->ptMinTrackSize.x = app->minWidth * DPIScaleX + widthExtra;
|
||||
mmi->ptMinTrackSize.y = app->minHeight * DPIScaleY + heightExtra;
|
||||
mmi->ptMinTrackSize.x = app->minWidth * DPIScaleX;
|
||||
mmi->ptMinTrackSize.y = app->minHeight * DPIScaleY;
|
||||
}
|
||||
if (app->maxWidth > 0 && app->maxHeight > 0) {
|
||||
mmi->ptMaxSize.x = app->maxWidth * DPIScaleX + widthExtra;
|
||||
mmi->ptMaxSize.y = app->maxHeight * DPIScaleY + heightExtra;
|
||||
mmi->ptMaxTrackSize.x = app->maxWidth * DPIScaleX + widthExtra;
|
||||
mmi->ptMaxTrackSize.y = app->maxHeight * DPIScaleY + heightExtra;
|
||||
mmi->ptMaxSize.x = app->maxWidth * DPIScaleX;
|
||||
mmi->ptMaxSize.y = app->maxHeight * DPIScaleY;
|
||||
mmi->ptMaxTrackSize.x = app->maxWidth * DPIScaleX;
|
||||
mmi->ptMaxTrackSize.y = app->maxHeight * DPIScaleY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -294,7 +352,6 @@ void completed(struct Application* app) {
|
||||
messageFromWindowCallback(readyMessage.c_str());
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
bool initWebView2(struct Application *app, int debugEnabled, messageCallback cb) {
|
||||
|
||||
@@ -331,6 +388,7 @@ bool initWebView2(struct Application *app, int debugEnabled, messageCallback cb)
|
||||
}
|
||||
// Fix for invisible webview
|
||||
if( app->startHidden ) {}
|
||||
controller->MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC);
|
||||
flag.clear();
|
||||
}));
|
||||
if (!SUCCEEDED(res))
|
||||
@@ -384,6 +442,7 @@ bool initWebView2(struct Application *app, int debugEnabled, messageCallback cb)
|
||||
}
|
||||
app->webviewController = controller;
|
||||
app->webview = webview;
|
||||
|
||||
// Resize WebView to fit the bounds of the parent window
|
||||
RECT bounds;
|
||||
GetClientRect(app->window, &bounds);
|
||||
@@ -395,7 +454,64 @@ bool initWebView2(struct Application *app, int debugEnabled, messageCallback cb)
|
||||
LPCWSTR html = (LPCWSTR) cstrToLPWSTR((char*)assets[0]);
|
||||
app->webview->Navigate(html);
|
||||
|
||||
if( app->webviewIsTranparent ) {
|
||||
wchar_t szBuff[64];
|
||||
ICoreWebView2Controller2 *wc2;
|
||||
wc2 = nullptr;
|
||||
app->webviewController->QueryInterface(IID_ICoreWebView2Controller2, (void**)&wc2);
|
||||
|
||||
COREWEBVIEW2_COLOR wvColor;
|
||||
wvColor.R = app->backgroundColour.R;
|
||||
wvColor.G = app->backgroundColour.G;
|
||||
wvColor.B = app->backgroundColour.B;
|
||||
wvColor.A = app->backgroundColour.A == 0 ? 0 : 255;
|
||||
if( app->WindowIsTranslucent ) {
|
||||
wvColor.A = 0;
|
||||
}
|
||||
HRESULT result = wc2->put_DefaultBackgroundColor(wvColor);
|
||||
if (!SUCCEEDED(result))
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND):
|
||||
{
|
||||
MessageBox(
|
||||
app->window,
|
||||
L"Couldn't find Edge installation. "
|
||||
"Do you have a version installed that's compatible with this "
|
||||
"WebView2 SDK version?",
|
||||
nullptr, MB_OK);
|
||||
}
|
||||
break;
|
||||
case HRESULT_FROM_WIN32(ERROR_FILE_EXISTS):
|
||||
{
|
||||
MessageBox(
|
||||
app->window, L"User data folder cannot be created because a file with the same name already exists.", nullptr, MB_OK);
|
||||
}
|
||||
break;
|
||||
case E_ACCESSDENIED:
|
||||
{
|
||||
MessageBox(
|
||||
app->window, L"Unable to create user data folder, Access Denied.", nullptr, MB_OK);
|
||||
}
|
||||
break;
|
||||
case E_FAIL:
|
||||
{
|
||||
MessageBox(
|
||||
app->window, L"Edge runtime unable to start", nullptr, MB_OK);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
MessageBox(app->window, L"Failed to create WebView2 environment", nullptr, MB_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
messageFromWindowCallback("Ej{\"name\":\"wails:launched\",\"data\":[]}");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -422,7 +538,7 @@ void Run(struct Application* app, int argc, char **argv) {
|
||||
|
||||
// Configure translucency
|
||||
DWORD dwExStyle = 0;
|
||||
if ( app->windowBackgroundIsTranslucent) {
|
||||
if ( app->WindowIsTranslucent) {
|
||||
dwExStyle = WS_EX_NOREDIRECTIONBITMAP;
|
||||
wc.hbrBackground = CreateSolidBrush(RGB(255,255,255));
|
||||
}
|
||||
@@ -474,7 +590,7 @@ void Run(struct Application* app, int argc, char **argv) {
|
||||
SetWindowPos(nullptr, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
|
||||
}
|
||||
|
||||
if ( app->windowBackgroundIsTranslucent ) {
|
||||
if ( app->WindowIsTranslucent ) {
|
||||
|
||||
// Enable the translucent background effect
|
||||
enableTranslucentBackground(app);
|
||||
@@ -492,61 +608,6 @@ void Run(struct Application* app, int argc, char **argv) {
|
||||
// Add webview2
|
||||
initWebView2(app, debug, initialCallback);
|
||||
|
||||
if( app->webviewIsTranparent ) {
|
||||
wchar_t szBuff[64];
|
||||
ICoreWebView2Controller2 *wc2;
|
||||
wc2 = nullptr;
|
||||
app->webviewController->QueryInterface(IID_ICoreWebView2Controller2, (void**)&wc2);
|
||||
|
||||
COREWEBVIEW2_COLOR wvColor;
|
||||
wvColor.R = app->backgroundColour.R;
|
||||
wvColor.G = app->backgroundColour.G;
|
||||
wvColor.B = app->backgroundColour.B;
|
||||
wvColor.A = app->backgroundColour.A == 0 ? 0 : 255;
|
||||
if( app->windowBackgroundIsTranslucent ) {
|
||||
wvColor.A = 0;
|
||||
}
|
||||
HRESULT result = wc2->put_DefaultBackgroundColor(wvColor);
|
||||
if (!SUCCEEDED(result))
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND):
|
||||
{
|
||||
MessageBox(
|
||||
app->window,
|
||||
L"Couldn't find Edge installation. "
|
||||
"Do you have a version installed that's compatible with this "
|
||||
"WebView2 SDK version?",
|
||||
nullptr, MB_OK);
|
||||
}
|
||||
break;
|
||||
case HRESULT_FROM_WIN32(ERROR_FILE_EXISTS):
|
||||
{
|
||||
MessageBox(
|
||||
app->window, L"User data folder cannot be created because a file with the same name already exists.", nullptr, MB_OK);
|
||||
}
|
||||
break;
|
||||
case E_ACCESSDENIED:
|
||||
{
|
||||
MessageBox(
|
||||
app->window, L"Unable to create user data folder, Access Denied.", nullptr, MB_OK);
|
||||
}
|
||||
break;
|
||||
case E_FAIL:
|
||||
{
|
||||
MessageBox(
|
||||
app->window, L"Edge runtime unable to start", nullptr, MB_OK);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
MessageBox(app->window, L"Failed to create WebView2 environment", nullptr, MB_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Main event loop
|
||||
MSG msg;
|
||||
@@ -816,8 +877,8 @@ void WebviewIsTransparent(struct Application *app) {
|
||||
app->webviewIsTranparent = true;
|
||||
}
|
||||
|
||||
void WindowBackgroundIsTranslucent(struct Application *app) {
|
||||
app->windowBackgroundIsTranslucent = true;
|
||||
void WindowIsTranslucent(struct Application *app) {
|
||||
app->WindowIsTranslucent = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -13,9 +13,30 @@ extern void DisableWindowIcon(struct Application* app);
|
||||
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"github.com/ztrue/tracerr"
|
||||
"os"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
)
|
||||
|
||||
// Setup the global caches
|
||||
var globalCheckboxCache = NewCheckboxCache()
|
||||
var globalRadioGroupCache = NewRadioGroupCache()
|
||||
var globalRadioGroupMap = NewRadioGroupMap()
|
||||
var globalApplicationMenu *Menu
|
||||
|
||||
type menuType string
|
||||
|
||||
const (
|
||||
appMenuType menuType = "ApplicationMenu"
|
||||
contextMenuType
|
||||
trayMenuType
|
||||
)
|
||||
|
||||
func (a *Application) processPlatformSettings() error {
|
||||
|
||||
menuManager = a.menuManager
|
||||
config := a.config.Windows
|
||||
if config == nil {
|
||||
return nil
|
||||
@@ -26,20 +47,17 @@ func (a *Application) processPlatformSettings() error {
|
||||
C.WebviewIsTransparent(a.app)
|
||||
}
|
||||
|
||||
if config.WindowBackgroundIsTranslucent {
|
||||
C.WindowBackgroundIsTranslucent(a.app)
|
||||
if config.WindowIsTranslucent {
|
||||
C.WindowIsTranslucent(a.app)
|
||||
}
|
||||
|
||||
if config.DisableWindowIcon {
|
||||
C.DisableWindowIcon(a.app)
|
||||
}
|
||||
|
||||
//// Process menu
|
||||
////applicationMenu := options.GetApplicationMenu(a.config)
|
||||
//applicationMenu := a.menuManager.GetApplicationMenuJSON()
|
||||
//if applicationMenu != "" {
|
||||
// C.SetApplicationMenu(a.app, a.string2CString(applicationMenu))
|
||||
//}
|
||||
// Unfortunately, we need to store this in the package variable so the C callback can see it
|
||||
applicationMenu = a.menuManager.GetProcessedApplicationMenu()
|
||||
|
||||
//
|
||||
//// Process tray
|
||||
//trays, err := a.menuManager.GetTrayMenus()
|
||||
@@ -70,3 +88,111 @@ func (a *Application) processPlatformSettings() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) updateApplicationMenu() {
|
||||
applicationMenu = c.app.menuManager.GetProcessedApplicationMenu()
|
||||
createApplicationMenu(uintptr(C.GetWindowHandle(c.app.app)))
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------
|
||||
|
||||
Application Menu
|
||||
----------------
|
||||
There's only 1 application menu and this is where we create it. This method
|
||||
is called from C after the window is created and the WM_CREATE message has
|
||||
been sent.
|
||||
|
||||
*/
|
||||
|
||||
func checkFatal(err error) {
|
||||
if err != nil {
|
||||
tracerr.PrintSourceColor(err)
|
||||
globalRadioGroupCache.Dump()
|
||||
globalRadioGroupMap.Dump()
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
//export createApplicationMenu
|
||||
func createApplicationMenu(hwnd uintptr) {
|
||||
|
||||
if applicationMenu == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
window := win32Window(hwnd)
|
||||
|
||||
if globalApplicationMenu != nil {
|
||||
checkFatal(globalApplicationMenu.Destroy())
|
||||
}
|
||||
|
||||
globalApplicationMenu, err = createMenu(applicationMenu, appMenuType)
|
||||
checkFatal(err)
|
||||
|
||||
err = setWindowMenu(window, globalApplicationMenu.menu)
|
||||
checkFatal(err)
|
||||
}
|
||||
|
||||
//export handleKeypressInGo
|
||||
func handleKeypressInGo(keycode uint16, modifiers uint8) {
|
||||
//fmt.Printf("Key code: %#x\n", keycode)
|
||||
menuID, menuType := getCallbackForKeyPress(keycode, modifiers)
|
||||
if menuID == "" {
|
||||
return
|
||||
}
|
||||
err := menuManager.ProcessClick(menuID, "", string(menuType), "")
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This method is called by C when a menu item is pressed
|
||||
*/
|
||||
|
||||
//export menuClicked
|
||||
func menuClicked(id uint32) {
|
||||
win32MenuID := win32MenuItemID(id)
|
||||
//println("Got click from menu id", win32MenuID)
|
||||
|
||||
// Get the menu from the cache
|
||||
menuItemDetails := getMenuCacheEntry(win32MenuID)
|
||||
wailsMenuID := wailsMenuItemID(menuItemDetails.item.ID)
|
||||
|
||||
//println("Got click from menu id", win32MenuID, "- wails menu ID", wailsMenuID)
|
||||
//spew.Dump(menuItemDetails)
|
||||
|
||||
switch menuItemDetails.item.Type {
|
||||
case menu.CheckboxType:
|
||||
|
||||
// Determine if the menu is set or not
|
||||
res, _, err := win32GetMenuState.Call(uintptr(menuItemDetails.parent), uintptr(id), uintptr(MF_BYCOMMAND))
|
||||
if int(res) == -1 {
|
||||
checkFatal(err)
|
||||
}
|
||||
|
||||
flag := MF_CHECKED
|
||||
if uint32(res) == MF_CHECKED {
|
||||
flag = MF_UNCHECKED
|
||||
}
|
||||
|
||||
for _, menuid := range globalCheckboxCache.win32MenuIDsForWailsMenuID(wailsMenuID) {
|
||||
//println("setting menuid", menuid, "with flag", flag)
|
||||
menuItemDetails := getMenuCacheEntry(menuid)
|
||||
res, _, err = win32CheckMenuItem.Call(uintptr(menuItemDetails.parent), uintptr(menuid), uintptr(flag))
|
||||
if int(res) == -1 {
|
||||
checkFatal(err)
|
||||
}
|
||||
}
|
||||
case menu.RadioType:
|
||||
err := selectRadioItemFromWailsMenuID(wailsMenuID, win32MenuID)
|
||||
checkFatal(err)
|
||||
}
|
||||
|
||||
// Print the click error - it's not fatal
|
||||
err := menuManager.ProcessClick(menuItemDetails.item.ID, "", string(menuItemDetails.menuType), "")
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ struct Application{
|
||||
int frame;
|
||||
char *startupURL;
|
||||
bool webviewIsTranparent;
|
||||
bool windowBackgroundIsTranslucent;
|
||||
bool WindowIsTranslucent;
|
||||
COREWEBVIEW2_COLOR backgroundColour;
|
||||
bool disableWindowIcon;
|
||||
|
||||
@@ -55,6 +55,10 @@ struct Application{
|
||||
// placeholders
|
||||
char* bindings;
|
||||
char* initialCode;
|
||||
|
||||
// DPI
|
||||
UINT dpix;
|
||||
UINT dpiy;
|
||||
};
|
||||
|
||||
#define ON_MAIN_THREAD(code) dispatch( [=]{ code; } )
|
||||
@@ -75,11 +79,17 @@ void loadAssets(struct Application* app);
|
||||
// called when the application assets have been loaded into the DOM
|
||||
void completed(struct Application* app);
|
||||
|
||||
// Processes the given keycode
|
||||
void processKeyPress(UINT key);
|
||||
|
||||
// Callback
|
||||
extern "C" {
|
||||
void DisableWindowIcon(struct Application* app);
|
||||
void messageFromWindowCallback(const char *);
|
||||
void* GetWindowHandle(struct Application*);
|
||||
void createApplicationMenu(HWND hwnd);
|
||||
void menuClicked(UINT id);
|
||||
void handleKeypressInGo(UINT, BYTE);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -85,13 +85,12 @@ void DeleteMenu(Menu *menu) {
|
||||
menu->processedMenu = NULL;
|
||||
}
|
||||
|
||||
// Release the vector memory
|
||||
vec_deinit(&menu->callbackDataCache);
|
||||
|
||||
// Free nsmenu if we have it
|
||||
if ( menu->menu != NULL ) {
|
||||
msg_reg(menu->menu, s("release"));
|
||||
// Release the callback data memory + vector
|
||||
int i; MenuItemCallbackData* callbackData;
|
||||
vec_foreach(&menu->callbackDataCache, callbackData, i) {
|
||||
free(callbackData);
|
||||
}
|
||||
vec_deinit(&menu->callbackDataCache);
|
||||
|
||||
free(menu);
|
||||
}
|
||||
@@ -376,7 +375,7 @@ id createMenu(id title) {
|
||||
id menu = ALLOC("NSMenu");
|
||||
msg_id(menu, s("initWithTitle:"), title);
|
||||
msg_bool(menu, s("setAutoenablesItems:"), NO);
|
||||
// msg(menu, s("autorelease"));
|
||||
msg_reg(menu, s("autorelease"));
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -562,6 +561,7 @@ id processRadioMenuItem(Menu *menu, id parentmenu, const char *title, const char
|
||||
id processCheckboxMenuItem(Menu *menu, id parentmenu, const char *title, const char *menuid, bool disabled, bool checked, const char *key) {
|
||||
|
||||
id item = ALLOC("NSMenuItem");
|
||||
msg_reg(item, s("autorelease"));
|
||||
|
||||
// Store the item in the menu item map
|
||||
hashmap_put(&menu->menuItemMap, (char*)menuid, strlen(menuid), item);
|
||||
@@ -573,7 +573,6 @@ id processCheckboxMenuItem(Menu *menu, id parentmenu, const char *title, const c
|
||||
msg_id(item, s("setRepresentedObject:"), wrappedId);
|
||||
((id(*)(id, SEL, id, SEL, id))objc_msgSend)(item, s("initWithTitle:action:keyEquivalent:"), str(title), s("menuItemCallback:"), str(key));
|
||||
msg_bool(item, s("setEnabled:"), !disabled);
|
||||
msg_reg(item, s("autorelease"));
|
||||
msg_int(item, s("setState:"), (checked ? NSControlStateValueOn : NSControlStateValueOff));
|
||||
msg_id(parentmenu, s("addItem:"), item);
|
||||
return item;
|
||||
@@ -727,6 +726,7 @@ id createAttributedString(const char* title, const char* fontName, int fontSize,
|
||||
|
||||
id processTextMenuItem(Menu *menu, id parentMenu, const char *title, const char *menuid, bool disabled, const char *acceleratorkey, const char **modifiers, const char* tooltip, const char* image, const char* fontName, int fontSize, const char* RGBA, bool templateImage, bool alternate, JsonNode* styledLabel) {
|
||||
id item = ALLOC("NSMenuItem");
|
||||
msg_reg(item, s("autorelease"));
|
||||
|
||||
// Create a MenuItemCallbackData
|
||||
MenuItemCallbackData *callback = CreateMenuItemCallbackData(menu, item, menuid, Text);
|
||||
@@ -763,7 +763,6 @@ id processTextMenuItem(Menu *menu, id parentMenu, const char *title, const char
|
||||
//msg_id(item, s("setTitle:"), str(title));
|
||||
|
||||
msg_bool(item, s("setEnabled:"), !disabled);
|
||||
msg_reg(item, s("autorelease"));
|
||||
|
||||
// Process modifiers
|
||||
if( modifiers != NULL && !alternate) {
|
||||
|
||||
@@ -155,6 +155,10 @@ void UpdateTrayMenuInPlace(TrayMenu* currentMenu, TrayMenu* newMenu) {
|
||||
|
||||
// Delete the old menu
|
||||
DeleteMenu(currentMenu->menu);
|
||||
if( currentMenu->delegate != NULL ) {
|
||||
msg_reg(currentMenu->delegate, s("release"));
|
||||
currentMenu->delegate = NULL;
|
||||
}
|
||||
|
||||
// Set the new one
|
||||
currentMenu->menu = newMenu->menu;
|
||||
@@ -176,11 +180,12 @@ void UpdateTrayMenuInPlace(TrayMenu* currentMenu, TrayMenu* newMenu) {
|
||||
|
||||
void DeleteTrayMenu(TrayMenu* trayMenu) {
|
||||
|
||||
// printf("Freeing TrayMenu:\n");
|
||||
// DumpTrayMenu(trayMenu);
|
||||
|
||||
// Delete the menu
|
||||
DeleteMenu(trayMenu->menu);
|
||||
if( trayMenu->delegate != NULL ) {
|
||||
msg_reg(trayMenu->delegate, s("release"));
|
||||
trayMenu->delegate = NULL;
|
||||
}
|
||||
|
||||
// Free JSON
|
||||
if (trayMenu->processedJSON != NULL ) {
|
||||
@@ -195,8 +200,21 @@ void DeleteTrayMenu(TrayMenu* trayMenu) {
|
||||
trayMenu->statusbaritem = NULL;
|
||||
}
|
||||
|
||||
if ( trayMenu->delegate != NULL ) {
|
||||
// Free the tray menu memory
|
||||
MEMFREE(trayMenu);
|
||||
}
|
||||
void DeleteTrayMenuKeepStatusBarItem(TrayMenu* trayMenu) {
|
||||
|
||||
// Delete the menu
|
||||
DeleteMenu(trayMenu->menu);
|
||||
if( trayMenu->delegate != NULL ) {
|
||||
msg_reg(trayMenu->delegate, s("release"));
|
||||
trayMenu->delegate = NULL;
|
||||
}
|
||||
|
||||
// Free JSON
|
||||
if (trayMenu->processedJSON != NULL ) {
|
||||
json_delete(trayMenu->processedJSON);
|
||||
}
|
||||
|
||||
// Free the tray menu memory
|
||||
|
||||
@@ -46,5 +46,6 @@ void LoadTrayIcons();
|
||||
void UnloadTrayIcons();
|
||||
|
||||
void DeleteTrayMenu(TrayMenu* trayMenu);
|
||||
void DeleteTrayMenuKeepStatusBarItem(TrayMenu* trayMenu);
|
||||
|
||||
#endif //TRAYMENU_DARWIN_H
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user