mirror of
https://github.com/taigrr/wails.git
synced 2026-04-04 14:12:40 -07:00
Compare commits
9 Commits
v1.0.2-pre
...
v1.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd6745bef0 | ||
|
|
8a14cc9a4c | ||
|
|
8a7c098041 | ||
|
|
030bd629df | ||
|
|
cad65f8f3f | ||
|
|
0c790bb08c | ||
|
|
fa1bc016fe | ||
|
|
5fc41949ae | ||
|
|
3d13368043 |
32
.github/workflows/latest-pre.yml
vendored
Normal file
32
.github/workflows/latest-pre.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
name: latest pre-release
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '**-pre**'
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: Test Build Latest Pre-Release
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
|
||||
- name: Set up Go 1.12
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.12
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Get dependencies
|
||||
run: |
|
||||
go get -v -d ./...
|
||||
- name: Build
|
||||
run: go build -v ./cmd/wails
|
||||
|
||||
- name: Test
|
||||
run: ./wails version
|
||||
32
.github/workflows/pr.yml
vendored
Normal file
32
.github/workflows/pr.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
name: pr
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- develop
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: Test Build PR
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
|
||||
- name: Set up Go 1.12
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.12
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Get dependencies
|
||||
run: |
|
||||
go get -v -d ./...
|
||||
- name: Build
|
||||
run: go build -v ./cmd/wails
|
||||
|
||||
- name: Test
|
||||
run: ./wails version
|
||||
34
.github/workflows/release.yml
vendored
Normal file
34
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
name: release
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- '!**pre**'
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: Test Build Latest Release
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
|
||||
- name: Set up Go 1.12
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.12
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Get dependencies
|
||||
run: |
|
||||
go get -v -d ./...
|
||||
- name: Build
|
||||
run: go build -v ./cmd/wails
|
||||
|
||||
- name: Test
|
||||
run: ./wails version
|
||||
@@ -11,7 +11,8 @@
|
||||
<a href="https://app.fossa.io/projects/git%2Bgithub.com%2Fwailsapp%2Fwails?ref=badge_shield" alt="FOSSA Status"><img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwailsapp%2Fwails.svg?type=shield"/></a>
|
||||
<a href="https://houndci.com"><img src="https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg"/></a>
|
||||
<a href="https://github.com/avelino/awesome-go" rel="nofollow"><img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome"></a>
|
||||
<a href="https://dev.azure.com/leaanthony/Wails/_build/latest?definitionId=1&branchName=master" rel="nofollow"><img src="https://dev.azure.com/leaanthony/Wails/_apis/build/status/wailsapp.wails?branchName=master" alt="Pipelines"></a>
|
||||
<a href="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" rel="nofollow"><img src="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" alt="Release Pipelines"></a>
|
||||
<a href="https://github.com/wailsapp/wails/workflows/latest-pre/badge.svg?branch=masterr" rel="nofollow"><img src="https://github.com/wailsapp/wails/workflows/latest-pre/badge.svg?branch=master" alt="Pre-Release Pipelines"></a>
|
||||
</p>
|
||||
|
||||
The traditional method of providing web interfaces to Go programs is via a built-in web server. Wails offers a different approach: it provides the ability to wrap both Go code and a web frontend into a single binary. Tools are provided to make this easy for you by handling project creation, compilation and bundling. All you have to do is get creative!
|
||||
|
||||
2
app.go
2
app.go
@@ -97,7 +97,7 @@ func (a *App) start() error {
|
||||
|
||||
// Check if we are to run in bridge mode
|
||||
if BuildMode == cmd.BuildModeBridge {
|
||||
a.renderer = &renderer.Bridge{}
|
||||
a.renderer = renderer.NewBridge()
|
||||
}
|
||||
|
||||
// Initialise the renderer
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
# avoid double trigger by applying some rules
|
||||
# start a pipeline when push to 'master' branch
|
||||
trigger:
|
||||
- master
|
||||
# or when pull request on 'develop' branch
|
||||
pr:
|
||||
- develop
|
||||
|
||||
# for now there is only one stage 'Build'
|
||||
# in the future we could use multistage strategy for releases
|
||||
stages:
|
||||
- stage: Build
|
||||
|
||||
# there are 3 jobs
|
||||
# one for each os
|
||||
jobs:
|
||||
- deployment: Linux
|
||||
displayName: Lin
|
||||
variables:
|
||||
GOPATH: '$(Agent.BuildDirectory)/gopath' # Go workspace path
|
||||
GOROOT: '$(Agent.BuildDirectory)/go' # Go installation path
|
||||
GOBIN: '$(GOPATH)/bin' # Go binaries path
|
||||
GOMODULE: 'on'
|
||||
modulePath: '$(Agent.BuildDirectory)/wails' # Path to the module's code
|
||||
pool:
|
||||
vmImage: 'Ubuntu-16.04'
|
||||
environment: 'linux-dev'
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- checkout: self # self represents the repo where the initial Pipelines YAML file was found
|
||||
clean: true # whether to fetch clean each time
|
||||
path: wails # path to check out source code, relative to the agent's build directory (e.g. \_work\1)
|
||||
# go version 1.12.7
|
||||
- script: |
|
||||
wget "https://storage.googleapis.com/golang/go1.12.7.linux-amd64.tar.gz" --output-document "$(Agent.BuildDirectory)/go1.12.7.tar.gz"
|
||||
tar -C '$(Agent.BuildDirectory)' -xzf "$(Agent.BuildDirectory)/go1.12.7.tar.gz"
|
||||
displayName: 'Install Go 1.12.7 Linux'
|
||||
- script: |
|
||||
mkdir -p '$(GOBIN)'
|
||||
mkdir -p '$(GOPATH)/pkg'
|
||||
mkdir -p '$(GOROOT)'
|
||||
shopt -s extglob
|
||||
shopt -s dotglob
|
||||
echo '##vso[task.prependpath]$(GOBIN)'
|
||||
echo '##vso[task.prependpath]$(GOROOT)/bin'
|
||||
displayName: 'Set up the Go workspace'
|
||||
- script: |
|
||||
go version
|
||||
go get -v -d ./...
|
||||
cd cmd/wails
|
||||
go install
|
||||
workingDirectory: '$(modulePath)'
|
||||
displayName: 'Get dependencies, then build'
|
||||
- script: |
|
||||
wails version
|
||||
workingDirectory: '$(modulePath)'
|
||||
displayName: 'Check we have output'
|
||||
|
||||
- deployment: Mac
|
||||
displayName: Mac
|
||||
variables:
|
||||
GOPATH: '$(Agent.BuildDirectory)/gopath' # Go workspace path
|
||||
GOROOT: '$(Agent.BuildDirectory)/go' # Go installation path
|
||||
GOBIN: '$(GOPATH)/bin' # Go binaries path
|
||||
GOMODULE: 'on'
|
||||
modulePath: '$(Agent.BuildDirectory)/wails' # Path to the module's code
|
||||
pool:
|
||||
vmImage: 'macOS-10.14'
|
||||
environment: 'mac-dev'
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- checkout: self # self represents the repo where the initial Pipelines YAML file was found
|
||||
clean: true # whether to fetch clean each time
|
||||
path: wails # path to check out source code, relative to the agent's build directory (e.g. \_work\1)
|
||||
# go version 1.12.7
|
||||
- script: |
|
||||
wget "https://storage.googleapis.com/golang/go1.12.7.darwin-amd64.tar.gz" --output-document "$(Agent.BuildDirectory)/go1.12.7.tar.gz"
|
||||
tar -C '$(Agent.BuildDirectory)' -xzf "$(Agent.BuildDirectory)/go1.12.7.tar.gz"
|
||||
displayName: 'Install Go 1.12.7 Linux'
|
||||
- script: |
|
||||
mkdir -p '$(GOBIN)'
|
||||
mkdir -p '$(GOPATH)/pkg'
|
||||
mkdir -p '$(GOROOT)'
|
||||
shopt -s extglob
|
||||
shopt -s dotglob
|
||||
echo '##vso[task.prependpath]$(GOBIN)'
|
||||
echo '##vso[task.prependpath]$(GOROOT)/bin'
|
||||
displayName: 'Set up the Go workspace'
|
||||
- script: |
|
||||
go version
|
||||
go get -v -d ./...
|
||||
cd cmd/wails
|
||||
go install
|
||||
workingDirectory: '$(modulePath)'
|
||||
displayName: 'Get dependencies, then build'
|
||||
- script: |
|
||||
wails version
|
||||
workingDirectory: '$(modulePath)'
|
||||
displayName: 'Check we have output'
|
||||
|
||||
- deployment: Win
|
||||
displayName: Win
|
||||
variables:
|
||||
GOMODULE: 'on'
|
||||
modulePath: '$(Agent.BuildDirectory)/wails' # Path to the module's code
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
environment: 'win-dev'
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- checkout: self # self represents the repo where the initial Pipelines YAML file was found
|
||||
clean: true # whether to fetch clean each time
|
||||
path: wails # path to check out source code, relative to the agent's build directory (e.g. \_work\1)
|
||||
# Go tool installer
|
||||
# Find in cache or download a specific version of Go and add it to the PATH
|
||||
- task: GoTool@0
|
||||
inputs:
|
||||
version: '1.12.7'
|
||||
goPath: '$(Agent.BuildDirectory)/go'
|
||||
goBin: '$(Agent.BuildDirectory)/go/bin'
|
||||
displayName: 'Set up the Go workspace'
|
||||
- script: |
|
||||
go version
|
||||
go get -v -d ./...
|
||||
cd cmd/wails
|
||||
go install
|
||||
workingDirectory: '$(modulePath)'
|
||||
displayName: 'Get dependencies, then build'
|
||||
- script: |
|
||||
wails version
|
||||
workingDirectory: '$(Agent.BuildDirectory)/go/bin'
|
||||
displayName: 'Check we have output'
|
||||
@@ -1,138 +0,0 @@
|
||||
# avoid double trigger by applying some rules
|
||||
# start a pipeline when push to 'master' branch
|
||||
trigger:
|
||||
- master
|
||||
# or when pull request on 'develop' branch
|
||||
pr:
|
||||
- develop
|
||||
|
||||
# for now there is only one stage 'Build'
|
||||
# in the future we could use multistage strategy for releases
|
||||
stages:
|
||||
- stage: Build
|
||||
|
||||
# there are 3 jobs
|
||||
# one for each os
|
||||
jobs:
|
||||
- deployment: Linux
|
||||
displayName: Lin
|
||||
variables:
|
||||
GOPATH: '$(Agent.BuildDirectory)/gopath' # Go workspace path
|
||||
GOROOT: '$(Agent.BuildDirectory)/go' # Go installation path
|
||||
GOBIN: '$(GOPATH)/bin' # Go binaries path
|
||||
GOMODULE: 'on'
|
||||
modulePath: '$(Agent.BuildDirectory)/wails' # Path to the module's code
|
||||
pool:
|
||||
vmImage: 'Ubuntu-16.04'
|
||||
environment: 'linux-dev'
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- checkout: self # self represents the repo where the initial Pipelines YAML file was found
|
||||
clean: true # whether to fetch clean each time
|
||||
path: wails # path to check out source code, relative to the agent's build directory (e.g. \_work\1)
|
||||
# go version 1.12.7
|
||||
- script: |
|
||||
wget "https://storage.googleapis.com/golang/go1.12.7.linux-amd64.tar.gz" --output-document "$(Agent.BuildDirectory)/go1.12.7.tar.gz"
|
||||
tar -C '$(Agent.BuildDirectory)' -xzf "$(Agent.BuildDirectory)/go1.12.7.tar.gz"
|
||||
displayName: 'Install Go 1.12.7 Linux'
|
||||
- script: |
|
||||
mkdir -p '$(GOBIN)'
|
||||
mkdir -p '$(GOPATH)/pkg'
|
||||
mkdir -p '$(GOROOT)'
|
||||
shopt -s extglob
|
||||
shopt -s dotglob
|
||||
echo '##vso[task.prependpath]$(GOBIN)'
|
||||
echo '##vso[task.prependpath]$(GOROOT)/bin'
|
||||
displayName: 'Set up the Go workspace'
|
||||
- script: |
|
||||
go version
|
||||
go get -v -d ./...
|
||||
cd cmd/wails
|
||||
go install
|
||||
workingDirectory: '$(modulePath)'
|
||||
displayName: 'Get dependencies, then build'
|
||||
- script: |
|
||||
wails version
|
||||
workingDirectory: '$(modulePath)'
|
||||
displayName: 'Check we have output'
|
||||
|
||||
- deployment: Mac
|
||||
displayName: Mac
|
||||
variables:
|
||||
GOPATH: '$(Agent.BuildDirectory)/gopath' # Go workspace path
|
||||
GOROOT: '$(Agent.BuildDirectory)/go' # Go installation path
|
||||
GOBIN: '$(GOPATH)/bin' # Go binaries path
|
||||
GOMODULE: 'on'
|
||||
modulePath: '$(Agent.BuildDirectory)/wails' # Path to the module's code
|
||||
pool:
|
||||
vmImage: 'macOS-10.14'
|
||||
environment: 'mac-dev'
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- checkout: self # self represents the repo where the initial Pipelines YAML file was found
|
||||
clean: true # whether to fetch clean each time
|
||||
path: wails # path to check out source code, relative to the agent's build directory (e.g. \_work\1)
|
||||
# go version 1.12.7
|
||||
- script: |
|
||||
wget "https://storage.googleapis.com/golang/go1.12.7.darwin-amd64.tar.gz" --output-document "$(Agent.BuildDirectory)/go1.12.7.tar.gz"
|
||||
tar -C '$(Agent.BuildDirectory)' -xzf "$(Agent.BuildDirectory)/go1.12.7.tar.gz"
|
||||
displayName: 'Install Go 1.12.7 Linux'
|
||||
- script: |
|
||||
mkdir -p '$(GOBIN)'
|
||||
mkdir -p '$(GOPATH)/pkg'
|
||||
mkdir -p '$(GOROOT)'
|
||||
shopt -s extglob
|
||||
shopt -s dotglob
|
||||
echo '##vso[task.prependpath]$(GOBIN)'
|
||||
echo '##vso[task.prependpath]$(GOROOT)/bin'
|
||||
displayName: 'Set up the Go workspace'
|
||||
- script: |
|
||||
go version
|
||||
go get -v -d ./...
|
||||
cd cmd/wails
|
||||
go install
|
||||
workingDirectory: '$(modulePath)'
|
||||
displayName: 'Get dependencies, then build'
|
||||
- script: |
|
||||
wails version
|
||||
workingDirectory: '$(modulePath)'
|
||||
displayName: 'Check we have output'
|
||||
|
||||
- deployment: Win
|
||||
displayName: Win
|
||||
variables:
|
||||
GOMODULE: 'on'
|
||||
modulePath: '$(Agent.BuildDirectory)/wails' # Path to the module's code
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
environment: 'win-dev'
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- checkout: self # self represents the repo where the initial Pipelines YAML file was found
|
||||
clean: true # whether to fetch clean each time
|
||||
path: wails # path to check out source code, relative to the agent's build directory (e.g. \_work\1)
|
||||
# Go tool installer
|
||||
# Find in cache or download a specific version of Go and add it to the PATH
|
||||
- task: GoTool@0
|
||||
inputs:
|
||||
version: '1.12.7'
|
||||
goPath: '$(Agent.BuildDirectory)/go'
|
||||
goBin: '$(Agent.BuildDirectory)/go/bin'
|
||||
displayName: 'Set up the Go workspace'
|
||||
- script: |
|
||||
go version
|
||||
go get -v -d ./...
|
||||
cd cmd/wails
|
||||
go install
|
||||
workingDirectory: '$(modulePath)'
|
||||
displayName: 'Get dependencies, then build'
|
||||
- script: |
|
||||
wails version
|
||||
workingDirectory: '$(Agent.BuildDirectory)/go/bin'
|
||||
displayName: 'Check we have output'
|
||||
78
cmd/gomod.go
Normal file
78
cmd/gomod.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
)
|
||||
|
||||
func GetWailsVersion() (*semver.Version, error) {
|
||||
var FS = NewFSHelper()
|
||||
var result *semver.Version
|
||||
|
||||
// Load file
|
||||
var err error
|
||||
goModFile, err := filepath.Abs(filepath.Join(".", "go.mod"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Unable to load go.mod at %s", goModFile)
|
||||
}
|
||||
goMod, err := FS.LoadAsString(goModFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Unable to load go.mod")
|
||||
}
|
||||
|
||||
// Find wails version
|
||||
versionRegexp := regexp.MustCompile(`.*github.com/wailsapp/wails.*(v\d+.\d+.\d+(?:-pre\d+)?)`)
|
||||
versions := versionRegexp.FindStringSubmatch(goMod)
|
||||
|
||||
if len(versions) != 2 {
|
||||
return nil, fmt.Errorf("Unable to determine Wails version")
|
||||
}
|
||||
|
||||
version := versions[1]
|
||||
result, err = semver.NewVersion(version)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Unable to parse Wails version: %s", version)
|
||||
}
|
||||
return result, nil
|
||||
|
||||
}
|
||||
|
||||
func GetCurrentVersion() (*semver.Version, error) {
|
||||
result, err := semver.NewVersion(Version)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Unable to parse Wails version: %s", Version)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func GoModOutOfSync() (bool, error) {
|
||||
gomodversion, err := GetWailsVersion()
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
currentVersion, err := GetCurrentVersion()
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
result := !currentVersion.Equal(gomodversion)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func UpdateGoModVersion() error {
|
||||
currentVersion, err := GetCurrentVersion()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
currentVersionString := currentVersion.String()
|
||||
|
||||
requireLine := "-require=github.com/wailsapp/wails@v" + currentVersionString
|
||||
|
||||
// Issue: go mod edit -require=github.com/wailsapp/wails@1.0.2-pre5
|
||||
helper := NewProgramHelper()
|
||||
command := []string{"go", "mod", "edit", requireLine}
|
||||
return helper.RunCommandArray(command)
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package cmd
|
||||
|
||||
// Version - Wails version
|
||||
const Version = "v1.0.2-pre5"
|
||||
const Version = "v1.0.2"
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
@@ -183,35 +182,13 @@ func checkProjectDirectory() error {
|
||||
|
||||
func getWailsVersion() (*semver.Version, error) {
|
||||
checkSpinner.Start("Get Wails Version")
|
||||
var result *semver.Version
|
||||
|
||||
// Load file
|
||||
var err error
|
||||
goModFile, err = filepath.Abs(filepath.Join(".", "go.mod"))
|
||||
result, err := cmd.GetWailsVersion()
|
||||
|
||||
if err != nil {
|
||||
checkSpinner.Error()
|
||||
return nil, fmt.Errorf("Unable to load go.mod at %s", goModFile)
|
||||
checkSpinner.Error(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
goMod, err = migrateFS.LoadAsString(goModFile)
|
||||
if err != nil {
|
||||
checkSpinner.Error()
|
||||
return nil, fmt.Errorf("Unable to load go.mod")
|
||||
}
|
||||
|
||||
// Find wails version
|
||||
versionRegexp := regexp.MustCompile(`.*github.com/wailsapp/wails.*(v\d+.\d+.\d+)`)
|
||||
versions := versionRegexp.FindStringSubmatch(goMod)
|
||||
|
||||
if len(versions) != 2 {
|
||||
return nil, fmt.Errorf("Unable to determine Wails version")
|
||||
}
|
||||
|
||||
version := versions[1]
|
||||
result, err = semver.NewVersion(version)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Unable to parse Wails version: %s", version)
|
||||
}
|
||||
checkSpinner.Success("Found Wails Version: " + version)
|
||||
return result, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -106,6 +106,27 @@ func init() {
|
||||
projectOptions.SetTypescriptDefsFilename(typescriptFilename)
|
||||
}
|
||||
|
||||
// Update go.mod if it is out of sync with current version
|
||||
outofsync, err := cmd.GoModOutOfSync()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gomodVersion, err := cmd.GetWailsVersion()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if outofsync {
|
||||
syncMessage := fmt.Sprintf("Updating go.mod (Wails version %s => %s)", gomodVersion, cmd.Version)
|
||||
buildSpinner := spinner.NewSpinner(syncMessage)
|
||||
buildSpinner.Start()
|
||||
err := cmd.UpdateGoModVersion()
|
||||
if err != nil {
|
||||
buildSpinner.Error(err.Error())
|
||||
return err
|
||||
}
|
||||
buildSpinner.Success()
|
||||
}
|
||||
|
||||
err = cmd.BuildApplication(projectOptions.BinaryName, forceRebuild, buildMode, packageApp, projectOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
2
go.mod
2
go.mod
@@ -32,4 +32,4 @@ require (
|
||||
gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22
|
||||
)
|
||||
|
||||
go 1.13
|
||||
go 1.12
|
||||
|
||||
@@ -114,6 +114,7 @@ func (b *Manager) generateTypescriptDefinitions() error {
|
||||
var output strings.Builder
|
||||
|
||||
for structname, methodList := range b.structList {
|
||||
structname = strings.SplitN(structname, ".", 2)[1]
|
||||
output.WriteString(fmt.Sprintf("Interface %s {\n", structname))
|
||||
for _, method := range methodList {
|
||||
output.WriteString(fmt.Sprintf("\t%s: (...args : any[]) => Promise\n", method))
|
||||
@@ -125,6 +126,7 @@ func (b *Manager) generateTypescriptDefinitions() error {
|
||||
output.WriteString("Interface Backend {\n")
|
||||
|
||||
for structname := range b.structList {
|
||||
structname = strings.SplitN(structname, ".", 2)[1]
|
||||
output.WriteString(fmt.Sprintf("\t%[1]s: %[1]s\n", structname))
|
||||
}
|
||||
output.WriteString("}\n")
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package interfaces
|
||||
|
||||
// CallbackFunc defines the signature of a function required to be provided to the
|
||||
// Dispatch function so that the response may be returned
|
||||
type CallbackFunc func(string) error
|
||||
|
||||
// IPCManager is the event manager interface
|
||||
type IPCManager interface {
|
||||
BindRenderer(Renderer)
|
||||
Dispatch(message string)
|
||||
Dispatch(message string, f CallbackFunc)
|
||||
Start(eventManager EventManager, bindingManager BindingManager)
|
||||
Shutdown()
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ type Renderer interface {
|
||||
|
||||
// Binding
|
||||
NewBinding(bindingName string) error
|
||||
Callback(data string) error
|
||||
|
||||
// Events
|
||||
NotifyEvent(eventData *messages.EventData) error
|
||||
|
||||
@@ -135,10 +135,10 @@ func (i *Manager) Start(eventManager interfaces.EventManager, bindingManager int
|
||||
// Dispatch receives JSON encoded messages from the renderer.
|
||||
// It processes the message to ensure that it is valid and places
|
||||
// the processed message on the message queue
|
||||
func (i *Manager) Dispatch(message string) {
|
||||
func (i *Manager) Dispatch(message string, cb interfaces.CallbackFunc) {
|
||||
|
||||
// Create a new IPC Message
|
||||
incomingMessage, err := newIPCMessage(message, i.SendResponse)
|
||||
incomingMessage, err := newIPCMessage(message, i.SendResponse(cb))
|
||||
if err != nil {
|
||||
i.log.ErrorFields("Could not understand incoming message! ", map[string]interface{}{
|
||||
"message": message,
|
||||
@@ -158,17 +158,19 @@ func (i *Manager) Dispatch(message string) {
|
||||
}
|
||||
|
||||
// SendResponse sends the given response back to the frontend
|
||||
func (i *Manager) SendResponse(response *ipcResponse) error {
|
||||
// It sends the data back to the correct renderer by way of the provided callback function
|
||||
func (i *Manager) SendResponse(cb interfaces.CallbackFunc) func(i *ipcResponse) error {
|
||||
|
||||
// Serialise the Message
|
||||
data, err := response.Serialise()
|
||||
if err != nil {
|
||||
fmt.Printf(err.Error())
|
||||
return err
|
||||
return func(response *ipcResponse) error {
|
||||
// Serialise the Message
|
||||
data, err := response.Serialise()
|
||||
if err != nil {
|
||||
fmt.Printf(err.Error())
|
||||
return err
|
||||
}
|
||||
return cb(data)
|
||||
}
|
||||
|
||||
// Call back to the front end
|
||||
return i.renderer.Callback(data)
|
||||
}
|
||||
|
||||
// Shutdown is called when exiting the Application
|
||||
|
||||
@@ -1,262 +1,10 @@
|
||||
package renderer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/dchest/htmlmin"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/leaanthony/mewn"
|
||||
"github.com/wailsapp/wails/lib/interfaces"
|
||||
"github.com/wailsapp/wails/lib/logger"
|
||||
"github.com/wailsapp/wails/lib/messages"
|
||||
bridge "github.com/wailsapp/wails/lib/renderer/bridge"
|
||||
)
|
||||
|
||||
type messageType int
|
||||
|
||||
const (
|
||||
jsMessage messageType = iota
|
||||
cssMessage
|
||||
htmlMessage
|
||||
notifyMessage
|
||||
bindingMessage
|
||||
callbackMessage
|
||||
wailsRuntimeMessage
|
||||
)
|
||||
|
||||
func (m messageType) toString() string {
|
||||
return [...]string{"j", "s", "h", "n", "b", "c", "w"}[m]
|
||||
}
|
||||
|
||||
// Bridge is a backend that opens a local web server
|
||||
// and renders the files over a websocket
|
||||
type Bridge struct {
|
||||
// Common
|
||||
log *logger.CustomLogger
|
||||
ipcManager interfaces.IPCManager
|
||||
appConfig interfaces.AppConfig
|
||||
eventManager interfaces.EventManager
|
||||
bindingCache []string
|
||||
|
||||
// Bridge specific
|
||||
initialisationJS []string
|
||||
server *http.Server
|
||||
theConnection *websocket.Conn
|
||||
|
||||
// Mutex for writing to the socket
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Initialise the Bridge Renderer
|
||||
func (h *Bridge) Initialise(appConfig interfaces.AppConfig, ipcManager interfaces.IPCManager, eventManager interfaces.EventManager) error {
|
||||
h.ipcManager = ipcManager
|
||||
h.appConfig = appConfig
|
||||
h.eventManager = eventManager
|
||||
ipcManager.BindRenderer(h)
|
||||
h.log = logger.NewCustomLogger("Bridge")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Bridge) evalJS(js string, mtype messageType) error {
|
||||
|
||||
message := mtype.toString() + js
|
||||
|
||||
if h.theConnection == nil {
|
||||
h.initialisationJS = append(h.initialisationJS, message)
|
||||
} else {
|
||||
// Prepend message type to message
|
||||
h.sendMessage(h.theConnection, message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnableConsole not needed for bridge!
|
||||
func (h *Bridge) EnableConsole() {
|
||||
}
|
||||
|
||||
func (h *Bridge) injectCSS(css string) {
|
||||
// Minify css to overcome issues in the browser with carriage returns
|
||||
minified, err := htmlmin.Minify([]byte(css), &htmlmin.Options{
|
||||
MinifyStyles: true,
|
||||
})
|
||||
if err != nil {
|
||||
h.log.Fatal("Unable to minify CSS: " + css)
|
||||
}
|
||||
minifiedCSS := string(minified)
|
||||
minifiedCSS = strings.Replace(minifiedCSS, "\\", "\\\\", -1)
|
||||
minifiedCSS = strings.Replace(minifiedCSS, "'", "\\'", -1)
|
||||
minifiedCSS = strings.Replace(minifiedCSS, "\n", " ", -1)
|
||||
inject := fmt.Sprintf("wails._.InjectCSS('%s')", minifiedCSS)
|
||||
h.evalJS(inject, cssMessage)
|
||||
}
|
||||
|
||||
func (h *Bridge) wsBridgeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
conn, err := websocket.Upgrade(w, r, w.Header(), 1024, 1024)
|
||||
if err != nil {
|
||||
http.Error(w, "Could not open websocket connection", http.StatusBadRequest)
|
||||
}
|
||||
h.theConnection = conn
|
||||
h.log.Infof("Connection from frontend accepted [%p].", h.theConnection)
|
||||
conn.SetCloseHandler(func(int, string) error {
|
||||
h.log.Infof("Connection dropped [%p].", h.theConnection)
|
||||
h.theConnection = nil
|
||||
return nil
|
||||
})
|
||||
go h.start(conn)
|
||||
}
|
||||
|
||||
func (h *Bridge) sendMessage(conn *websocket.Conn, msg string) {
|
||||
|
||||
h.lock.Lock()
|
||||
defer h.lock.Unlock()
|
||||
|
||||
if err := conn.WriteMessage(websocket.TextMessage, []byte(msg)); err != nil {
|
||||
h.log.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Bridge) start(conn *websocket.Conn) {
|
||||
|
||||
// set external.invoke
|
||||
h.log.Infof("Connected to frontend.")
|
||||
|
||||
wailsRuntime := mewn.String("../../runtime/assets/wails.js")
|
||||
h.evalJS(wailsRuntime, wailsRuntimeMessage)
|
||||
|
||||
// Inject bindings
|
||||
for _, binding := range h.bindingCache {
|
||||
h.evalJS(binding, bindingMessage)
|
||||
}
|
||||
|
||||
// Emit that everything is loaded and ready
|
||||
h.eventManager.Emit("wails:ready")
|
||||
|
||||
for {
|
||||
messageType, buffer, err := conn.ReadMessage()
|
||||
if messageType == -1 {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
h.log.Errorf("Error reading message: ", err)
|
||||
continue
|
||||
}
|
||||
|
||||
h.log.Debugf("Got message: %#v\n", string(buffer))
|
||||
|
||||
h.ipcManager.Dispatch(string(buffer))
|
||||
}
|
||||
}
|
||||
|
||||
// Run the app in Bridge mode!
|
||||
func (h *Bridge) Run() error {
|
||||
h.server = &http.Server{Addr: ":34115"}
|
||||
http.HandleFunc("/bridge", h.wsBridgeHandler)
|
||||
|
||||
h.log.Info("Bridge mode started.")
|
||||
h.log.Info("The frontend will connect automatically.")
|
||||
|
||||
err := h.server.ListenAndServe()
|
||||
if err != nil && err != http.ErrServerClosed {
|
||||
h.log.Fatal(err.Error())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// NewBinding creates a new binding with the frontend
|
||||
func (h *Bridge) NewBinding(methodName string) error {
|
||||
h.bindingCache = append(h.bindingCache, methodName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SelectFile is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) SelectFile() string {
|
||||
h.log.Warn("SelectFile() unsupported in bridge mode")
|
||||
return ""
|
||||
}
|
||||
|
||||
// SelectDirectory is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) SelectDirectory() string {
|
||||
h.log.Warn("SelectDirectory() unsupported in bridge mode")
|
||||
return ""
|
||||
}
|
||||
|
||||
// SelectSaveFile is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) SelectSaveFile() string {
|
||||
h.log.Warn("SelectSaveFile() unsupported in bridge mode")
|
||||
return ""
|
||||
}
|
||||
|
||||
// Callback sends a callback to the frontend
|
||||
func (h *Bridge) Callback(data string) error {
|
||||
return h.evalJS(data, callbackMessage)
|
||||
}
|
||||
|
||||
// NotifyEvent notifies the frontend of an event
|
||||
func (h *Bridge) NotifyEvent(event *messages.EventData) error {
|
||||
|
||||
// Look out! Nils about!
|
||||
var err error
|
||||
if event == nil {
|
||||
err = fmt.Errorf("Sent nil event to renderer.webViewRenderer")
|
||||
h.log.Error(err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
// Default data is a blank array
|
||||
data := []byte("[]")
|
||||
|
||||
// Process event data
|
||||
if event.Data != nil {
|
||||
// Marshall the data
|
||||
data, err = json.Marshal(event.Data)
|
||||
if err != nil {
|
||||
h.log.Errorf("Cannot unmarshall JSON data in event: %s ", err.Error())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
message := fmt.Sprintf("window.wails._.Notify('%s','%s')", event.Name, data)
|
||||
return h.evalJS(message, notifyMessage)
|
||||
}
|
||||
|
||||
// SetColour is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) SetColour(colour string) error {
|
||||
h.log.WarnFields("SetColour ignored for Bridge more", logger.Fields{"col": colour})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Fullscreen is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) Fullscreen() {
|
||||
h.log.Warn("Fullscreen() unsupported in bridge mode")
|
||||
}
|
||||
|
||||
// UnFullscreen is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) UnFullscreen() {
|
||||
h.log.Warn("UnFullscreen() unsupported in bridge mode")
|
||||
}
|
||||
|
||||
// SetTitle is currently unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) SetTitle(title string) {
|
||||
h.log.WarnFields("SetTitle() unsupported in bridge mode", logger.Fields{"title": title})
|
||||
}
|
||||
|
||||
// Close is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) Close() {
|
||||
h.log.Debug("Shutting down")
|
||||
err := h.server.Close()
|
||||
if err != nil {
|
||||
h.log.Errorf(err.Error())
|
||||
}
|
||||
// NewBridge returns a new Bridge struct
|
||||
func NewBridge() *bridge.Bridge {
|
||||
return &bridge.Bridge{}
|
||||
}
|
||||
|
||||
214
lib/renderer/bridge/bridge.go
Normal file
214
lib/renderer/bridge/bridge.go
Normal file
@@ -0,0 +1,214 @@
|
||||
package renderer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/wailsapp/wails/lib/interfaces"
|
||||
"github.com/wailsapp/wails/lib/logger"
|
||||
"github.com/wailsapp/wails/lib/messages"
|
||||
)
|
||||
|
||||
type messageType int
|
||||
|
||||
const (
|
||||
jsMessage messageType = iota
|
||||
cssMessage
|
||||
htmlMessage
|
||||
notifyMessage
|
||||
bindingMessage
|
||||
callbackMessage
|
||||
wailsRuntimeMessage
|
||||
)
|
||||
|
||||
func (m messageType) toString() string {
|
||||
return [...]string{"j", "s", "h", "n", "b", "c", "w"}[m]
|
||||
}
|
||||
|
||||
// Bridge is a backend that opens a local web server
|
||||
// and renders the files over a websocket
|
||||
type Bridge struct {
|
||||
// Common
|
||||
log *logger.CustomLogger
|
||||
ipcManager interfaces.IPCManager
|
||||
appConfig interfaces.AppConfig
|
||||
eventManager interfaces.EventManager
|
||||
bindingCache []string
|
||||
|
||||
// Bridge specific
|
||||
server *http.Server
|
||||
|
||||
lock sync.Mutex
|
||||
sessions map[string]session
|
||||
}
|
||||
|
||||
// Initialise the Bridge Renderer
|
||||
func (h *Bridge) Initialise(appConfig interfaces.AppConfig, ipcManager interfaces.IPCManager, eventManager interfaces.EventManager) error {
|
||||
h.sessions = map[string]session{}
|
||||
h.ipcManager = ipcManager
|
||||
h.appConfig = appConfig
|
||||
h.eventManager = eventManager
|
||||
ipcManager.BindRenderer(h)
|
||||
h.log = logger.NewCustomLogger("Bridge")
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnableConsole not needed for bridge!
|
||||
func (h *Bridge) EnableConsole() {
|
||||
}
|
||||
|
||||
func (h *Bridge) wsBridgeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
conn, err := websocket.Upgrade(w, r, w.Header(), 1024, 1024)
|
||||
if err != nil {
|
||||
http.Error(w, "Could not open websocket connection", http.StatusBadRequest)
|
||||
}
|
||||
h.log.Infof("Connection from frontend accepted [%s].", conn.RemoteAddr().String())
|
||||
h.startSession(conn)
|
||||
}
|
||||
|
||||
func (h *Bridge) startSession(conn *websocket.Conn) {
|
||||
s := session{
|
||||
conn: conn,
|
||||
bindingCache: h.bindingCache,
|
||||
ipc: h.ipcManager,
|
||||
log: h.log,
|
||||
eventManager: h.eventManager,
|
||||
}
|
||||
|
||||
conn.SetCloseHandler(func(int, string) error {
|
||||
h.log.Infof("Connection dropped [%s].", s.Identifier())
|
||||
h.eventManager.Emit("wails:bridge:session:closed", s.Identifier())
|
||||
h.lock.Lock()
|
||||
defer h.lock.Unlock()
|
||||
delete(h.sessions, s.Identifier())
|
||||
return nil
|
||||
})
|
||||
|
||||
h.lock.Lock()
|
||||
defer h.lock.Unlock()
|
||||
go s.start(len(h.sessions) == 0)
|
||||
h.sessions[s.Identifier()] = s
|
||||
}
|
||||
|
||||
// Run the app in Bridge mode!
|
||||
func (h *Bridge) Run() error {
|
||||
h.server = &http.Server{Addr: ":34115"}
|
||||
http.HandleFunc("/bridge", h.wsBridgeHandler)
|
||||
|
||||
h.log.Info("Bridge mode started.")
|
||||
h.log.Info("The frontend will connect automatically.")
|
||||
|
||||
err := h.server.ListenAndServe()
|
||||
if err != nil && err != http.ErrServerClosed {
|
||||
h.log.Fatal(err.Error())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// NewBinding creates a new binding with the frontend
|
||||
func (h *Bridge) NewBinding(methodName string) error {
|
||||
h.bindingCache = append(h.bindingCache, methodName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SelectFile is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) SelectFile() string {
|
||||
h.log.Warn("SelectFile() unsupported in bridge mode")
|
||||
return ""
|
||||
}
|
||||
|
||||
// SelectDirectory is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) SelectDirectory() string {
|
||||
h.log.Warn("SelectDirectory() unsupported in bridge mode")
|
||||
return ""
|
||||
}
|
||||
|
||||
// SelectSaveFile is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) SelectSaveFile() string {
|
||||
h.log.Warn("SelectSaveFile() unsupported in bridge mode")
|
||||
return ""
|
||||
}
|
||||
|
||||
// NotifyEvent notifies the frontend of an event
|
||||
func (h *Bridge) NotifyEvent(event *messages.EventData) error {
|
||||
|
||||
// Look out! Nils about!
|
||||
var err error
|
||||
if event == nil {
|
||||
err = fmt.Errorf("Sent nil event to renderer.webViewRenderer")
|
||||
h.log.Error(err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
// Default data is a blank array
|
||||
data := []byte("[]")
|
||||
|
||||
// Process event data
|
||||
if event.Data != nil {
|
||||
// Marshall the data
|
||||
data, err = json.Marshal(event.Data)
|
||||
if err != nil {
|
||||
h.log.Errorf("Cannot unmarshall JSON data in event: %s ", err.Error())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
message := fmt.Sprintf("window.wails._.Notify('%s','%s')", event.Name, data)
|
||||
dead := []session{}
|
||||
for _, session := range h.sessions {
|
||||
err := session.evalJS(message, notifyMessage)
|
||||
if err != nil {
|
||||
h.log.Debugf("Failed to send message to %s - Removing listener : %v", session.Identifier(), err)
|
||||
h.log.Infof("Connection from [%v] unresponsive - dropping", session.Identifier())
|
||||
dead = append(dead, session)
|
||||
}
|
||||
}
|
||||
h.lock.Lock()
|
||||
defer h.lock.Unlock()
|
||||
for _, session := range dead {
|
||||
delete(h.sessions, session.Identifier())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetColour is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) SetColour(colour string) error {
|
||||
h.log.WarnFields("SetColour ignored for Bridge more", logger.Fields{"col": colour})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Fullscreen is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) Fullscreen() {
|
||||
h.log.Warn("Fullscreen() unsupported in bridge mode")
|
||||
}
|
||||
|
||||
// UnFullscreen is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) UnFullscreen() {
|
||||
h.log.Warn("UnFullscreen() unsupported in bridge mode")
|
||||
}
|
||||
|
||||
// SetTitle is currently unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) SetTitle(title string) {
|
||||
h.log.WarnFields("SetTitle() unsupported in bridge mode", logger.Fields{"title": title})
|
||||
}
|
||||
|
||||
// Close is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) Close() {
|
||||
h.log.Debug("Shutting down")
|
||||
err := h.server.Close()
|
||||
if err != nil {
|
||||
h.log.Errorf(err.Error())
|
||||
}
|
||||
}
|
||||
90
lib/renderer/bridge/session.go
Normal file
90
lib/renderer/bridge/session.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package renderer
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/leaanthony/mewn"
|
||||
"github.com/wailsapp/wails/lib/interfaces"
|
||||
"github.com/wailsapp/wails/lib/logger"
|
||||
)
|
||||
|
||||
// TODO Move this back into bridge.go
|
||||
|
||||
// session represents a single websocket session
|
||||
type session struct {
|
||||
bindingCache []string
|
||||
conn *websocket.Conn
|
||||
eventManager interfaces.EventManager
|
||||
log *logger.CustomLogger
|
||||
ipc interfaces.IPCManager
|
||||
|
||||
// Mutex for writing to the socket
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Identifier returns a string identifier for the remote connection.
|
||||
// Taking the form of the client's <ip address>:<port>.
|
||||
func (s *session) Identifier() string {
|
||||
if s.conn != nil {
|
||||
return s.conn.RemoteAddr().String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *session) sendMessage(msg string) error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
if err := s.conn.WriteMessage(websocket.TextMessage, []byte(msg)); err != nil {
|
||||
s.log.Debug(err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *session) start(firstSession bool) {
|
||||
s.log.Infof("Connected to frontend.")
|
||||
|
||||
wailsRuntime := mewn.String("../../runtime/assets/wails.js")
|
||||
s.evalJS(wailsRuntime, wailsRuntimeMessage)
|
||||
|
||||
// Inject bindings
|
||||
for _, binding := range s.bindingCache {
|
||||
s.evalJS(binding, bindingMessage)
|
||||
}
|
||||
s.eventManager.Emit("wails:bridge:session:started", s.Identifier())
|
||||
|
||||
// Emit that everything is loaded and ready
|
||||
if firstSession {
|
||||
s.eventManager.Emit("wails:ready")
|
||||
}
|
||||
|
||||
for {
|
||||
messageType, buffer, err := s.conn.ReadMessage()
|
||||
if messageType == -1 {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
s.log.Errorf("Error reading message: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
s.log.Debugf("Got message: %#v\n", string(buffer))
|
||||
|
||||
s.ipc.Dispatch(string(buffer), s.Callback)
|
||||
}
|
||||
}
|
||||
|
||||
// Callback sends a callback to the frontend
|
||||
func (s *session) Callback(data string) error {
|
||||
return s.evalJS(data, callbackMessage)
|
||||
}
|
||||
|
||||
func (s *session) evalJS(js string, mtype messageType) error {
|
||||
|
||||
// Prepend message type to message
|
||||
return s.sendMessage(mtype.toString() + js)
|
||||
|
||||
}
|
||||
@@ -58,7 +58,7 @@ func (w *WebView) Initialise(config interfaces.AppConfig, ipc interfaces.IPCMana
|
||||
URL: config.GetDefaultHTML(),
|
||||
Debug: !config.GetDisableInspector(),
|
||||
ExternalInvokeCallback: func(_ wv.WebView, message string) {
|
||||
w.ipc.Dispatch(message)
|
||||
w.ipc.Dispatch(message, w.callback)
|
||||
},
|
||||
})
|
||||
|
||||
@@ -299,8 +299,8 @@ func (w *WebView) SelectSaveFile() string {
|
||||
return result
|
||||
}
|
||||
|
||||
// Callback sends a callback to the frontend
|
||||
func (w *WebView) Callback(data string) error {
|
||||
// callback sends a callback to the frontend
|
||||
func (w *WebView) callback(data string) error {
|
||||
callbackCMD := fmt.Sprintf("window.wails._.Callback('%s');", data)
|
||||
return w.evalJS(callbackCMD)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user