mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 07:52:12 +08:00
[windows-x] Dev mode. Auto rebuild/reload. Auto open browser. Disconnect spinner. Base template update. mimecache
This commit is contained in:
parent
c3c88f5e27
commit
b558246d52
@ -6,6 +6,7 @@ import (
|
||||
"github.com/wailsapp/wails/v2/internal/project"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
@ -40,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 {
|
||||
|
||||
@ -56,14 +65,24 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
assetDir := ""
|
||||
command.StringFlag("assetdir", "Serve assets from the given directory", &assetDir)
|
||||
|
||||
// extensions to trigger rebuilds
|
||||
// extensions to trigger rebuilds of application
|
||||
extensions := "go"
|
||||
command.StringFlag("e", "Extensions to trigger rebuilds (comma separated) eg go,js,css,html", &extensions)
|
||||
command.StringFlag("e", "Extensions to trigger rebuilds (comma separated) eg go", &extensions)
|
||||
|
||||
// extensions to trigger reloads in the application
|
||||
reloadEnabled := true
|
||||
command.BoolFlag("r", "Reload on asset changes", &reloadEnabled)
|
||||
|
||||
// extensions to trigger rebuilds
|
||||
showWarnings := false
|
||||
command.BoolFlag("w", "Show warnings", &showWarnings)
|
||||
|
||||
openBrowser := false
|
||||
command.BoolFlag("browser", "Open application in browser", &openBrowser)
|
||||
|
||||
noreload := false
|
||||
command.BoolFlag("noreload", "Disable reload on asset change", &noreload)
|
||||
|
||||
// Verbosity
|
||||
verbosity := 1
|
||||
command.IntFlag("v", "Verbosity level (0 - silent, 1 - default, 2 - verbose)", &verbosity)
|
||||
@ -77,7 +96,6 @@ 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
|
||||
@ -91,6 +109,11 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
return fmt.Errorf("No asset directory provided. Please use -assetdir to indicate which directory contains your built assets.")
|
||||
}
|
||||
|
||||
assetDir, err = filepath.Abs(assetDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if assetDir != "" && assetDir != projectConfig.AssetDirectory {
|
||||
projectConfig.AssetDirectory = assetDir
|
||||
err := projectConfig.Save()
|
||||
@ -115,13 +138,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 {
|
||||
@ -130,7 +152,7 @@ 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, assetDir, true)
|
||||
newProcess, appBinary, err := restartApp(logger, ldflags, compilerCommand, debugBinaryProcess, loglevel, passthruArgs, verbosity, assetDir, true, exitCodeChannel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -139,70 +161,17 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
||||
}
|
||||
|
||||
// open browser
|
||||
err = browser.OpenURL("http://localhost:34115")
|
||||
if err != nil {
|
||||
return err
|
||||
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, assetDir, false)
|
||||
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()
|
||||
@ -227,20 +196,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, ldflags, compilerCommand, debugBinaryProcess, loglevel, passthruArgs, verbosity, 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
|
||||
}
|
||||
}
|
||||
@ -267,26 +304,7 @@ 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, ldflags string, compilerCommand string, debugBinaryProcess *process.Process, loglevel string, passthruArgs []string, verbosity int, assetDir string, firstRun bool) (*process.Process, string, error) {
|
||||
func restartApp(logger *clilogger.CLILogger, ldflags string, compilerCommand string, debugBinaryProcess *process.Process, loglevel string, passthruArgs []string, verbosity int, assetDir string, firstRun bool, exitCodeChannel chan int) (*process.Process, string, error) {
|
||||
|
||||
appBinary, err := buildApp(logger, ldflags, compilerCommand, verbosity)
|
||||
println()
|
||||
@ -322,8 +340,8 @@ func restartApp(logger *clilogger.CLILogger, ldflags string, compilerCommand str
|
||||
if len(passthruArgs) > 0 {
|
||||
args.AddSlice(passthruArgs)
|
||||
}
|
||||
newProcess := process.NewProcess(logger, appBinary, args.AsSlice()...)
|
||||
err = newProcess.Start()
|
||||
newProcess := process.NewProcess(appBinary, args.AsSlice()...)
|
||||
err = newProcess.Start(exitCodeChannel)
|
||||
if err != nil {
|
||||
// Remove binary
|
||||
deleteError := fs.DeleteFile(appBinary)
|
||||
|
@ -6,6 +6,7 @@ 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
|
||||
@ -43,7 +44,7 @@ require (
|
||||
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-20210616045830-e2b7044e8c71
|
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf
|
||||
golang.org/x/tools v0.1.0
|
||||
nhooyr.io/websocket v1.8.6
|
||||
)
|
||||
|
21
v2/go.sum
21
v2/go.sum
@ -11,7 +11,6 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo
|
||||
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 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
|
||||
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=
|
||||
@ -22,10 +21,11 @@ github.com/fasthttp/websocket v0.0.0-20200320073529-1554a54587ab h1:9e2joQGp642w
|
||||
github.com/fasthttp/websocket v0.0.0-20200320073529-1554a54587ab/go.mod h1:smsv/h4PBEBaU0XDTY5UwJTpZv69fQ0FfcLJr21mA6Y=
|
||||
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 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
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=
|
||||
@ -45,7 +45,6 @@ github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4
|
||||
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 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
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=
|
||||
@ -68,13 +67,11 @@ github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgj
|
||||
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 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
|
||||
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 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
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=
|
||||
@ -89,7 +86,6 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl
|
||||
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 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
|
||||
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=
|
||||
@ -99,14 +95,11 @@ github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
|
||||
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 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
|
||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/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 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
|
||||
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=
|
||||
@ -148,7 +141,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLD
|
||||
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 h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
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=
|
||||
@ -163,10 +155,8 @@ github.com/savsgio/gotils v0.0.0-20200117113501-90175b0fbe3f h1:PgA+Olipyj258EIE
|
||||
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 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
@ -210,7 +200,6 @@ 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 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM=
|
||||
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=
|
||||
@ -233,10 +222,10 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
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-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -257,8 +246,9 @@ golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
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 h1:X/2sJAybVknnUnV7AD2HdT6rm2p5BP6eH2j+igduWgk=
|
||||
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=
|
||||
@ -266,7 +256,6 @@ 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 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
||||
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=
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
@ -103,11 +102,11 @@ func (a *DesktopAssetServer) init(assets embed.FS) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.indexFile, err = injectScript(string(indexHTML), `<script src="/wails/runtime.js"></script>`)
|
||||
a.indexFile, err = injectHTML(string(indexHTML), `<script src="/wails/runtime.js"></script>`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.indexFile, err = injectScript(string(a.indexFile), `<script src="/wails/ipc.js"></script>`)
|
||||
a.indexFile, err = injectHTML(string(a.indexFile), `<script src="/wails/ipc.js"></script>`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -130,6 +129,6 @@ func (a *DesktopAssetServer) Load(filename string) ([]byte, string, error) {
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
mimeType := http.DetectContentType(content)
|
||||
mimeType := GetMimetype(filename, content)
|
||||
return content, mimeType, nil
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ It injects a websocket based IPC script into `index.html`.
|
||||
*/
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
@ -53,15 +52,20 @@ func (a *AssetServer) loadFileFromDisk(filename string) ([]byte, error) {
|
||||
}
|
||||
|
||||
func (a *AssetServer) init() error {
|
||||
indexHTML, err := a.loadFileFromDisk("index.html")
|
||||
var err error
|
||||
a.indexFile, err = a.loadFileFromDisk("index.html")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.indexFile, err = injectScript(string(indexHTML), `<script src="/wails/runtime.js"></script>`)
|
||||
a.indexFile, err = injectHTML(string(a.indexFile), `<div id="wails-spinner"></div>`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.indexFile, err = injectScript(string(a.indexFile), `<script src="/wails/ipc.js"></script>`)
|
||||
a.indexFile, err = injectHTML(string(a.indexFile), `<script src="/wails/ipc.js"></script>`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.indexFile, err = injectHTML(string(a.indexFile), `<script src="/wails/runtime.js"></script>`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -84,6 +88,6 @@ func (a *AssetServer) Load(filename string) ([]byte, string, error) {
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
mimeType := http.DetectContentType(content)
|
||||
mimeType := GetMimetype(filename, content)
|
||||
return content, mimeType, nil
|
||||
}
|
||||
|
@ -6,16 +6,16 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func injectScript(input string, script string) ([]byte, error) {
|
||||
splits := strings.Split(input, "<head>")
|
||||
func injectHTML(input string, html string) ([]byte, error) {
|
||||
splits := strings.Split(input, "</body>")
|
||||
if len(splits) != 2 {
|
||||
return nil, fmt.Errorf("unable to locate a </head> tag in your html")
|
||||
return nil, fmt.Errorf("unable to locate a </body> tag in your html")
|
||||
}
|
||||
|
||||
var result bytes.Buffer
|
||||
result.WriteString(splits[0])
|
||||
result.WriteString("<head>")
|
||||
result.WriteString(script)
|
||||
result.WriteString(html)
|
||||
result.WriteString("</body>")
|
||||
result.WriteString(splits[1])
|
||||
return result.Bytes(), nil
|
||||
}
|
||||
|
36
v2/internal/frontend/assetserver/mimecache.go
Normal file
36
v2/internal/frontend/assetserver/mimecache.go
Normal file
@ -0,0 +1,36 @@
|
||||
package assetserver
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
import "github.com/gabriel-vasile/mimetype"
|
||||
|
||||
var (
|
||||
cache = map[string]string{}
|
||||
mutex sync.Mutex
|
||||
)
|
||||
|
||||
func GetMimetype(filename string, data []byte) string {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
|
||||
result := cache[filename]
|
||||
if result != "" {
|
||||
return result
|
||||
}
|
||||
|
||||
detect := mimetype.Detect(data)
|
||||
if detect == nil {
|
||||
result = http.DetectContentType(data)
|
||||
} else {
|
||||
result = detect.String()
|
||||
}
|
||||
|
||||
if result == "" {
|
||||
result = "application/octet-stream"
|
||||
}
|
||||
|
||||
cache[filename] = result
|
||||
return result
|
||||
}
|
@ -41,6 +41,10 @@ type Frontend struct {
|
||||
servingFromDisk bool
|
||||
}
|
||||
|
||||
func (f *Frontend) WindowReload() {
|
||||
f.ExecJS("runtime.WindowReload();")
|
||||
}
|
||||
|
||||
func (f *Frontend) Run(ctx context.Context) error {
|
||||
|
||||
mainWindow := NewWindow(nil, f.frontendOptions)
|
||||
@ -211,9 +215,7 @@ func (f *Frontend) Notify(name string, data ...interface{}) {
|
||||
f.logger.Error(err.Error())
|
||||
return
|
||||
}
|
||||
f.mainWindow.Dispatch(func() {
|
||||
f.chromium.Eval(`window.wails.EventsNotify('` + string(payload) + `');`)
|
||||
})
|
||||
f.ExecJS(`window.wails.EventsNotify('` + string(payload) + `');`)
|
||||
}
|
||||
|
||||
func (f *Frontend) processRequest(req *edge.ICoreWebView2WebResourceRequest, args *edge.ICoreWebView2WebResourceRequestedEventArgs) {
|
||||
@ -288,6 +290,12 @@ func (f *Frontend) startDrag() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Frontend) ExecJS(js string) {
|
||||
f.mainWindow.Dispatch(func() {
|
||||
f.chromium.Eval(js)
|
||||
})
|
||||
}
|
||||
|
||||
func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher) *Frontend {
|
||||
|
||||
result := &Frontend{
|
||||
|
@ -39,9 +39,19 @@ type DevServer struct {
|
||||
desktopFrontend frontend.Frontend
|
||||
}
|
||||
|
||||
func (d *DevServer) WindowReload() {
|
||||
d.broadcast("reload")
|
||||
}
|
||||
|
||||
func (d *DevServer) Run(ctx context.Context) error {
|
||||
d.ctx = ctx
|
||||
|
||||
d.server.Get("/wails/reload", func(fctx *fiber.Ctx) error {
|
||||
d.WindowReload()
|
||||
d.desktopFrontend.WindowReload()
|
||||
return nil
|
||||
})
|
||||
|
||||
d.server.Get("/wails/ipc", websocket.New(func(c *websocket.Conn) {
|
||||
d.newWebsocketSession(c)
|
||||
// websocket.Conn bindings https://pkg.go.dev/github.com/fasthttp/websocket?tab=doc#pkg-index
|
||||
@ -55,14 +65,13 @@ func (d *DevServer) Run(ctx context.Context) error {
|
||||
if mt, msg, err = c.ReadMessage(); err != nil {
|
||||
break
|
||||
}
|
||||
d.logger.Info("[%p] %s", c, msg)
|
||||
//d.logger.Info("[%p] %s", c, msg)
|
||||
if string(msg) == "drag" {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(msg) > 2 && strings.HasPrefix(string(msg), "EE") {
|
||||
d.broadcast(string(msg)[2:])
|
||||
//d.broadcastExcludingSender(string(msg)[2:], c)
|
||||
d.notifyExcludingSender(msg, c)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -272,8 +281,6 @@ func (d *DevServer) newWebsocketSession(c *websocket.Conn) {
|
||||
})
|
||||
d.websocketClients[c] = struct{}{}
|
||||
d.LogInfo(fmt.Sprintf("Websocket client %p connected", c))
|
||||
// Send the starttime to see if the client needs to reload
|
||||
c.WriteMessage(websocket.TextMessage, []byte("T"+d.starttime))
|
||||
}
|
||||
|
||||
type EventNotify struct {
|
||||
@ -322,6 +329,19 @@ func (d *DevServer) broadcastExcludingSender(message string, sender *websocket.C
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DevServer) notifyExcludingSender(eventMessage []byte, sender *websocket.Conn) {
|
||||
message := "n" + string(eventMessage[2:])
|
||||
d.broadcastExcludingSender(message, sender)
|
||||
|
||||
var notifyMessage EventNotify
|
||||
err := json.Unmarshal(eventMessage[2:], ¬ifyMessage)
|
||||
if err != nil {
|
||||
d.logger.Error(err.Error())
|
||||
return
|
||||
}
|
||||
d.desktopFrontend.Notify(notifyMessage.Name, notifyMessage.Data...)
|
||||
}
|
||||
|
||||
func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher, menuManager *menumanager.Manager) *DevServer {
|
||||
result := &DevServer{
|
||||
ctx: ctx,
|
||||
@ -336,7 +356,6 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.
|
||||
}),
|
||||
menuManager: menuManager,
|
||||
websocketClients: make(map[*websocket.Conn]struct{}),
|
||||
starttime: time.Now().String(),
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ type Frontend interface {
|
||||
WindowFullscreen()
|
||||
WindowUnFullscreen()
|
||||
WindowSetColour(colour int)
|
||||
WindowReload()
|
||||
|
||||
// Menus
|
||||
SetApplicationMenu(menu *menu.Menu)
|
||||
|
@ -12,6 +12,7 @@ import * as Log from './log';
|
||||
import {eventListeners, EventsEmit, EventsNotify, EventsOff, EventsOn, EventsOnce, EventsOnMultiple} from './events';
|
||||
import {Callback, callbacks} from './calls';
|
||||
import {SetBindings} from "./bindings";
|
||||
import {WindowReload} from "./window";
|
||||
|
||||
// Backend is where the Go struct wrappers get bound to
|
||||
window.backend = {};
|
||||
@ -23,6 +24,7 @@ window.runtime = {
|
||||
EventsOnMultiple,
|
||||
EventsEmit,
|
||||
EventsOff,
|
||||
WindowReload,
|
||||
};
|
||||
|
||||
// Initialise global if not already
|
||||
|
15
v2/internal/frontend/runtime/desktop/window.js
Normal file
15
v2/internal/frontend/runtime/desktop/window.js
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
_ __ _ __
|
||||
| | / /___ _(_) /____
|
||||
| | /| / / __ `/ / / ___/
|
||||
| |/ |/ / /_/ / / (__ )
|
||||
|__/|__/\__,_/_/_/____/
|
||||
The lightweight framework for web-like apps
|
||||
(c) Lea Anthony 2019-present
|
||||
*/
|
||||
|
||||
/* jshint esversion: 9 */
|
||||
|
||||
export function WindowReload() {
|
||||
window.location.reload();
|
||||
}
|
54
v2/internal/frontend/runtime/dev/Overlay.svelte
Normal file
54
v2/internal/frontend/runtime/dev/Overlay.svelte
Normal file
@ -0,0 +1,54 @@
|
||||
<script>
|
||||
|
||||
import {overlayVisible} from './store'
|
||||
import {fade,} from 'svelte/transition';
|
||||
</script>
|
||||
|
||||
{#if $overlayVisible }
|
||||
<div class="wails-reconnect-overlay" transition:fade="{{ duration: 300 }}">
|
||||
<div class="wails-reconnect-overlay-content">
|
||||
<div class="wails-reconnect-overlay-loadingspinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.wails-reconnect-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
backdrop-filter: blur(2px) saturate(0%) contrast(50%) brightness(25%);
|
||||
z-index: 999999
|
||||
}
|
||||
|
||||
.wails-reconnect-overlay-content {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
margin: 0;
|
||||
background-image: url(data:image/png;base64,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);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center
|
||||
}
|
||||
|
||||
.wails-reconnect-overlay-loadingspinner {
|
||||
pointer-events: none;
|
||||
width: 2.5em;
|
||||
height: 2.5em;
|
||||
border: .4em solid transparent;
|
||||
border-color: #f00 #eee0 #f00 #eee0;
|
||||
border-radius: 50%;
|
||||
animation: loadingspin 1s linear infinite;
|
||||
margin: auto;
|
||||
padding: 2.5em
|
||||
}
|
||||
|
||||
@keyframes loadingspin {
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -10,7 +10,7 @@ let sveltePlugin = {
|
||||
build.onLoad({filter: /\.svelte$/}, async (args) => {
|
||||
// This converts a message in Svelte's format to esbuild's format
|
||||
let convertMessage = ({message, start, end}) => {
|
||||
let location
|
||||
let location;
|
||||
if (start && end) {
|
||||
let lineText = source.split(/\r\n|\r|\n/g)[start.line - 1];
|
||||
let lineEnd = start.line === end.line ? end.column : lineText.length;
|
||||
|
@ -10,6 +10,16 @@ The lightweight framework for web-like apps
|
||||
/* jshint esversion: 6 */
|
||||
|
||||
import {log} from "./log";
|
||||
import Overlay from "./Overlay.svelte";
|
||||
import {hideOverlay, showOverlay} from "./store";
|
||||
|
||||
let components = {};
|
||||
|
||||
// Sets up the overlay
|
||||
components.overlay = new Overlay({
|
||||
target: document.body,
|
||||
anchor: document.querySelector('#wails-spinner'),
|
||||
});
|
||||
|
||||
let websocket = null;
|
||||
let connectTimer;
|
||||
@ -26,7 +36,6 @@ window.onbeforeunload = function () {
|
||||
// ...and attempt to connect
|
||||
connect();
|
||||
|
||||
|
||||
function setupIPCBridge() {
|
||||
window.WailsInvoke = (message) => {
|
||||
websocket.send(message);
|
||||
@ -36,6 +45,7 @@ function setupIPCBridge() {
|
||||
// Handles incoming websocket connections
|
||||
function handleConnect() {
|
||||
log('Connected to backend');
|
||||
hideOverlay();
|
||||
setupIPCBridge();
|
||||
clearInterval(connectTimer);
|
||||
websocket.onclose = handleDisconnect;
|
||||
@ -46,6 +56,7 @@ function handleConnect() {
|
||||
function handleDisconnect() {
|
||||
log('Disconnected from backend');
|
||||
websocket = null;
|
||||
showOverlay();
|
||||
connect();
|
||||
}
|
||||
|
||||
@ -63,100 +74,26 @@ function connect() {
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}, 1000);
|
||||
}, 250);
|
||||
}
|
||||
|
||||
function handleMessage(message) {
|
||||
|
||||
// ignore
|
||||
if (message === "drag") {
|
||||
if (message.data === "reload") {
|
||||
window.runtime.WindowReload();
|
||||
return;
|
||||
}
|
||||
|
||||
// As a bridge we ignore js and css injections
|
||||
switch (message.data[0]) {
|
||||
// Wails library - inject!
|
||||
// case 'b':
|
||||
// message = message.data.slice(1);
|
||||
// addScript(message);
|
||||
// log('Loaded Wails Runtime');
|
||||
//
|
||||
// // We need to now send a message to the backend telling it
|
||||
// // we have loaded (System Start)
|
||||
// window.wailsInvoke('SS');
|
||||
//
|
||||
// // Now wails runtime is loaded, wails for the ready event
|
||||
// // and callback to the main app
|
||||
// // window.wails.Events.On('wails:loaded', function () {
|
||||
// if (callback) {
|
||||
// log('Notifying application');
|
||||
// callback(window.wails);
|
||||
// }
|
||||
// // });
|
||||
// break;
|
||||
// Notifications
|
||||
case 'n':
|
||||
window.wails.EventsNotify(message.data.slice(1));
|
||||
break;
|
||||
// // // Binding
|
||||
// // case 'b':
|
||||
// // const binding = message.data.slice(1);
|
||||
// // //log("Binding: " + binding)
|
||||
// // window.wails._.NewBinding(binding);
|
||||
// // break;
|
||||
// // // Call back
|
||||
case 'c':
|
||||
const callbackData = message.data.slice(1);
|
||||
window.wails.Callback(callbackData);
|
||||
break;
|
||||
|
||||
// Application menu
|
||||
/*
|
||||
case 'M':
|
||||
const menuData = message.data.slice(1);
|
||||
window.appmenu = JSON.parse(menuData);
|
||||
ApplicationMenu.set(window.appmenu);
|
||||
console.log("Set application menu");
|
||||
break;
|
||||
*/
|
||||
case 'T':
|
||||
const serverStartTime = message.data.slice(1);
|
||||
const lastServerStartTime = localStorage.getItem('wails:lastServerStartTime');
|
||||
if (lastServerStartTime === null) {
|
||||
localStorage.setItem('wails:lastServerStartTime', serverStartTime);
|
||||
}
|
||||
if (serverStartTime !== lastServerStartTime) {
|
||||
localStorage.setItem('wails:lastServerStartTime', serverStartTime);
|
||||
location.reload(true);
|
||||
console.log("Reloaded");
|
||||
}
|
||||
break;
|
||||
// // Tray
|
||||
// case 'T':
|
||||
// const trayMessage = message.data.slice(1);
|
||||
// switch (trayMessage[0]) {
|
||||
// case 'S':
|
||||
// // Set tray
|
||||
// const trayJSON = trayMessage.slice(1);
|
||||
// let tray = JSON.parse(trayJSON);
|
||||
// setTray(tray);
|
||||
// break;
|
||||
// case 'U':
|
||||
// // Update label
|
||||
// const updateTrayLabelJSON = trayMessage.slice(1);
|
||||
// let trayLabelData = JSON.parse(updateTrayLabelJSON);
|
||||
// updateTrayLabel(trayLabelData);
|
||||
// break;
|
||||
// case 'D':
|
||||
// // Delete Tray Menu
|
||||
// const id = trayMessage.slice(1);
|
||||
// deleteTrayMenu(id);
|
||||
// break;
|
||||
// default:
|
||||
// log('Unknown tray message: ' + message.data);
|
||||
// }
|
||||
// break;
|
||||
|
||||
default:
|
||||
log('Unknown message: ' + message.data);
|
||||
}
|
||||
|
@ -10,7 +10,6 @@
|
||||
"author": "Lea Anthony <lea.anthony@gmail.com>",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@zerodevx/svelte-toast": "^0.5.1",
|
||||
"esbuild": "^0.12.17",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"svelte": "^3.42.2"
|
||||
|
12
v2/internal/frontend/runtime/dev/store.js
Normal file
12
v2/internal/frontend/runtime/dev/store.js
Normal file
@ -0,0 +1,12 @@
|
||||
import {writable} from 'svelte/store';
|
||||
|
||||
/** Overlay */
|
||||
export const overlayVisible = writable(false);
|
||||
|
||||
export function showOverlay() {
|
||||
overlayVisible.set(true);
|
||||
}
|
||||
|
||||
export function hideOverlay() {
|
||||
overlayVisible.set(false);
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -6,7 +6,7 @@
|
||||
"scripts": {
|
||||
"build": "run-p build:*",
|
||||
"build:ipc-windows": "esbuild desktop/ipc.js --bundle --minify --outfile=ipc_windows.js --define:PLATFORM='windows'",
|
||||
"build:ipc-dev": "esbuild dev/main.js --bundle --minify --outfile=ipc_websocket.js",
|
||||
"build:ipc-dev": "cd dev && npm run build",
|
||||
"build:runtime-desktop-prod": "esbuild desktop/main.js --bundle --minify --outfile=runtime_prod_desktop.js",
|
||||
"build:runtime-desktop-dev": "esbuild desktop/main.js --bundle --sourcemap=inline --outfile=runtime_dev_desktop.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
(()=>{var p=Object.defineProperty;var m=n=>p(n,"__esModule",{value:!0});var I=(n,e)=>{m(n);for(var t in e)p(n,t,{get:e[t],enumerable:!0})};var u={};I(u,{LogDebug:()=>W,LogError:()=>T,LogFatal:()=>C,LogInfo:()=>D,LogLevel:()=>A,LogPrint:()=>R,LogTrace:()=>S,LogWarning:()=>J,SetLogLevel:()=>j});function l(n,e){window.WailsInvoke("L"+n+e)}function S(n){l("T",n)}function R(n){l("P",n)}function W(n){l("D",n)}function D(n){l("I",n)}function J(n){l("W",n)}function T(n){l("E",n)}function C(n){l("F",n)}function j(n){l("S",n)}var A={TRACE:1,DEBUG:2,INFO:3,WARNING:4,ERROR:5};var E=class{constructor(e,t){t=t||-1,this.Callback=o=>(e.apply(null,o),t===-1?!1:(t-=1,t===0))}},s={};function d(n,e,t){s[n]=s[n]||[];let o=new E(e,t);s[n].push(o)}function v(n,e){d(n,e,-1)}function g(n,e){d(n,e,1)}function b(n){let e=n.name;if(s[e]){let t=s[e].slice();for(let o=0;o<s[e].length;o+=1){let i=s[e][o],r=n.data;i.Callback(r)&&t.splice(o,1)}s[e]=t}}function y(n){let e;try{e=JSON.parse(n)}catch(t){let o="Invalid JSON passed to Notify: "+n;throw new Error(o)}b(e)}function L(n){let e={name:n,data:[].slice.apply(arguments).slice(1)};b(e),window.WailsInvoke("EE"+JSON.stringify(e))}function k(n){s.delete(n),window.WailsInvoke("EX"+n)}var a={};function B(){var n=new Uint32Array(1);return window.crypto.getRandomValues(n)[0]}function F(){return Math.random()*9007199254740991}var f;window.crypto?f=B:f=F;function O(n,e,t){return t==null&&(t=0),new Promise(function(o,i){var r;do r=n+"-"+f();while(a[r]);var c;t>0&&(c=setTimeout(function(){i(Error("Call to "+n+" timed out. Request ID: "+r))},t)),a[r]={timeoutHandle:c,reject:i,resolve:o};try{let w={name:n,args:e,callbackID:r};window.WailsInvoke("C"+JSON.stringify(w))}catch(w){console.error(w)}})}function h(n){var e;try{e=JSON.parse(n)}catch(i){let r=`Invalid JSON passed to callback: ${i.message}. Message: ${n}`;throw wails.LogDebug(r),new Error(r)}var t=e.callbackid,o=a[t];if(!o){let i=`Callback '${t}' not registered!!!`;throw console.error(i),new Error(i)}clearTimeout(o.timeoutHandle),delete a[t],e.error?o.reject(e.error):o.resolve(e.result)}window.backend={};function x(n){try{n=JSON.parse(n)}catch(e){console.error(e)}window.backend=window.backend||{},Object.keys(n).forEach(e=>{window.backend[e]=window.backend[e]||{},Object.keys(n[e]).forEach(t=>{window.backend[e][t]=window.backend[e][t]||{},Object.keys(n[e][t]).forEach(o=>{window.backend[e][t][o]=function(){let i=0;function r(){let c=[].slice.call(arguments);return O([e,t,o].join("."),c,i)}return r.setTimeout=function(c){i=c},r.getTimeout=function(){return i},r}()})})})}window.backend={};window.runtime={...u,EventsOn:v,EventsOnce:g,EventsOnMultiple:d,EventsEmit:L,EventsOff:k};window.wails={Callback:h,EventsNotify:y,SetBindings:x,eventListeners:s,callbacks:a};window.wails.SetBindings(window.wailsbindings);delete window.wails.SetBindings;delete window.wailsbindings;window.addEventListener("mousedown",n=>{let e=n.target;for(;e!=null&&!e.hasAttribute("data-wails-no-drag");){if(e.hasAttribute("data-wails-drag")){window.WailsInvoke("drag");break}e=e.parentElement}});})();
|
||||
(()=>{var p=Object.defineProperty;var I=n=>p(n,"__esModule",{value:!0});var S=(n,e)=>{I(n);for(var o in e)p(n,o,{get:e[o],enumerable:!0})};var f={};S(f,{LogDebug:()=>D,LogError:()=>C,LogFatal:()=>j,LogInfo:()=>J,LogLevel:()=>B,LogPrint:()=>W,LogTrace:()=>R,LogWarning:()=>T,SetLogLevel:()=>A});function l(n,e){window.WailsInvoke("L"+n+e)}function R(n){l("T",n)}function W(n){l("P",n)}function D(n){l("D",n)}function J(n){l("I",n)}function T(n){l("W",n)}function C(n){l("E",n)}function j(n){l("F",n)}function A(n){l("S",n)}var B={TRACE:1,DEBUG:2,INFO:3,WARNING:4,ERROR:5};var E=class{constructor(e,o){o=o||-1,this.Callback=t=>(e.apply(null,t),o===-1?!1:(o-=1,o===0))}},s={};function d(n,e,o){s[n]=s[n]||[];let t=new E(e,o);s[n].push(t)}function v(n,e){d(n,e,-1)}function g(n,e){d(n,e,1)}function b(n){let e=n.name;if(s[e]){let o=s[e].slice();for(let t=0;t<s[e].length;t+=1){let i=s[e][t],r=n.data;i.Callback(r)&&o.splice(t,1)}s[e]=o}}function y(n){let e;try{e=JSON.parse(n)}catch(o){let t="Invalid JSON passed to Notify: "+n;throw new Error(t)}b(e)}function L(n){let e={name:n,data:[].slice.apply(arguments).slice(1)};b(e),window.WailsInvoke("EE"+JSON.stringify(e))}function k(n){s.delete(n),window.WailsInvoke("EX"+n)}var a={};function F(){var n=new Uint32Array(1);return window.crypto.getRandomValues(n)[0]}function H(){return Math.random()*9007199254740991}var u;window.crypto?u=F:u=H;function O(n,e,o){return o==null&&(o=0),new Promise(function(t,i){var r;do r=n+"-"+u();while(a[r]);var c;o>0&&(c=setTimeout(function(){i(Error("Call to "+n+" timed out. Request ID: "+r))},o)),a[r]={timeoutHandle:c,reject:i,resolve:t};try{let w={name:n,args:e,callbackID:r};window.WailsInvoke("C"+JSON.stringify(w))}catch(w){console.error(w)}})}function h(n){var e;try{e=JSON.parse(n)}catch(i){let r=`Invalid JSON passed to callback: ${i.message}. Message: ${n}`;throw wails.LogDebug(r),new Error(r)}var o=e.callbackid,t=a[o];if(!t){let i=`Callback '${o}' not registered!!!`;throw console.error(i),new Error(i)}clearTimeout(t.timeoutHandle),delete a[o],e.error?t.reject(e.error):t.resolve(e.result)}window.backend={};function x(n){try{n=JSON.parse(n)}catch(e){console.error(e)}window.backend=window.backend||{},Object.keys(n).forEach(e=>{window.backend[e]=window.backend[e]||{},Object.keys(n[e]).forEach(o=>{window.backend[e][o]=window.backend[e][o]||{},Object.keys(n[e][o]).forEach(t=>{window.backend[e][o][t]=function(){let i=0;function r(){let c=[].slice.call(arguments);return O([e,o,t].join("."),c,i)}return r.setTimeout=function(c){i=c},r.getTimeout=function(){return i},r}()})})})}function m(){window.location.reload()}window.backend={};window.runtime={...f,EventsOn:v,EventsOnce:g,EventsOnMultiple:d,EventsEmit:L,EventsOff:k,WindowReload:m};window.wails={Callback:h,EventsNotify:y,SetBindings:x,eventListeners:s,callbacks:a};window.wails.SetBindings(window.wailsbindings);delete window.wails.SetBindings;delete window.wailsbindings;window.addEventListener("mousedown",n=>{let e=n.target;for(;e!=null&&!e.hasAttribute("data-wails-no-drag");){if(e.hasAttribute("data-wails-drag")){window.WailsInvoke("drag");break}e=e.parentElement}});})();
|
||||
|
@ -3,22 +3,18 @@ package process
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/clilogger"
|
||||
)
|
||||
|
||||
// Process defines a process that can be executed
|
||||
type Process struct {
|
||||
logger *clilogger.CLILogger
|
||||
cmd *exec.Cmd
|
||||
exitChannel chan bool
|
||||
Running bool
|
||||
}
|
||||
|
||||
// NewProcess creates a new process struct
|
||||
func NewProcess(logger *clilogger.CLILogger, cmd string, args ...string) *Process {
|
||||
func NewProcess(cmd string, args ...string) *Process {
|
||||
result := &Process{
|
||||
logger: logger,
|
||||
cmd: exec.Command(cmd, args...),
|
||||
exitChannel: make(chan bool, 1),
|
||||
}
|
||||
@ -28,7 +24,7 @@ func NewProcess(logger *clilogger.CLILogger, cmd string, args ...string) *Proces
|
||||
}
|
||||
|
||||
// Start the process
|
||||
func (p *Process) Start() error {
|
||||
func (p *Process) Start(exitCodeChannel chan int) error {
|
||||
|
||||
err := p.cmd.Start()
|
||||
if err != nil {
|
||||
@ -37,13 +33,14 @@ func (p *Process) Start() error {
|
||||
|
||||
p.Running = true
|
||||
|
||||
go func(cmd *exec.Cmd, running *bool, logger *clilogger.CLILogger, exitChannel chan bool) {
|
||||
logger.Println("Starting process (PID: %d)", cmd.Process.Pid)
|
||||
_ = cmd.Wait()
|
||||
logger.Println("Exiting process (PID: %d)", cmd.Process.Pid)
|
||||
go func(cmd *exec.Cmd, running *bool, exitChannel chan bool, exitCodeChannel chan int) {
|
||||
err := cmd.Wait()
|
||||
if err == nil {
|
||||
exitCodeChannel <- 0
|
||||
}
|
||||
*running = false
|
||||
exitChannel <- true
|
||||
}(p.cmd, &p.Running, p.logger, p.exitChannel)
|
||||
}(p.cmd, &p.Running, p.exitChannel, exitCodeChannel)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -28,6 +28,12 @@ func WindowCenter(ctx context.Context) {
|
||||
appFrontend.WindowCenter()
|
||||
}
|
||||
|
||||
// WindowReload will reload the window contents
|
||||
func WindowReload(ctx context.Context) {
|
||||
appFrontend := getFrontend(ctx)
|
||||
appFrontend.WindowReload()
|
||||
}
|
||||
|
||||
// WindowShow shows the window if hidden
|
||||
func WindowShow(ctx context.Context) {
|
||||
appFrontend := getFrontend(ctx)
|
||||
|
Loading…
Reference in New Issue
Block a user