Compare commits

..

91 Commits

Author SHA1 Message Date
Lea Anthony
7dd42f964b Merge pull request #147 from wailsapp/develop
Release v0.17.0
2019-07-02 17:39:41 +10:00
Lea Anthony
078a7a5519 feat: release v0.17.0 2019-07-02 17:38:18 +10:00
Lea Anthony
d811f721ac docs: be explicit about node version 2019-07-01 21:50:16 +10:00
Lea Anthony
26950ba045 chore: version bump 2019-07-01 21:36:07 +10:00
Lea Anthony
80adb70e78 chore: version bump 2019-07-01 21:35:30 +10:00
Lea Anthony
0c042acd4a fix: template name order 2019-07-01 21:35:06 +10:00
Lea Anthony
0ad0c4151a feat: use slicer v1.3.2 2019-07-01 18:27:10 +10:00
Lea Anthony
65a8a1e1f7 feat: sort templates by name 2019-07-01 18:26:24 +10:00
Lea Anthony
a2ac8af882 chore: Bump to version v0.16.5-pre 2019-07-01 18:10:26 +10:00
Lea Anthony
52afbd3f15 fix: revert back to my-app 2019-07-01 09:01:07 +10:00
Lea Anthony
ce35ee5ca8 Merge branch 'bh90210-118-angular-support' into develop 2019-07-01 08:58:37 +10:00
Lea Anthony
74c64c6420 chore: misc updates for template 2019-07-01 08:57:42 +10:00
Lea Anthony
678328b7aa Merge branch '118-angular-support' of git://github.com/bh90210/wails into bh90210-118-angular-support 2019-06-30 18:11:35 +10:00
Lea Anthony
345c8bc094 fix: linting fixes 2019-06-30 17:16:38 +10:00
Lea Anthony
44386490c8 chore: add default case to bridge switch 2019-06-29 23:03:46 +10:00
bh90210
87158a342a feat: angular template 2019-06-29 15:45:48 +03:00
Lea Anthony
0b43fae32a docs: updated contributors 2019-06-29 21:43:19 +10:00
Lea Anthony
89f7a95167 Merge pull request #141 from wailsapp/138-Template-dependency-checker
feat: initial support for template dependencies
2019-06-27 19:56:57 +10:00
Lea Anthony
c5be3e5634 feat: initial support for template dependencies 2019-06-27 09:05:46 +10:00
Lea Anthony
7156740f6c fix: typo 2019-06-27 08:46:01 +10:00
Lea Anthony
2d29b626c7 chore: version bump 2019-06-26 19:50:22 +10:00
Lea Anthony
698145be1e Merge pull request #140 from wailsapp/139-go.mod-should-reflect-current-wails-version
feat: set wails version in go.mod
2019-06-26 19:48:35 +10:00
Lea Anthony
a9188cbfdd feat: set wails version in go.mod 2019-06-26 19:46:51 +10:00
Lea Anthony
d07cca0278 chore: version bump 2019-06-25 18:49:18 +10:00
Lea Anthony
60d1dc51ad Merge pull request #137 from wailsapp/135-Add-Debian-support
135 add debian support
2019-06-25 18:48:24 +10:00
Lea Anthony
105073e412 fix: add Debian support across tooling 2019-06-25 18:32:25 +10:00
Lea Anthony
9d1f1fff47 feat: debian support 2019-06-25 18:29:57 +10:00
Lea Anthony
08050ec35e Merge pull request #134 from wailsapp/133-Unsupported-Platform-Requests
133 unsupported platform requests
2019-06-25 08:18:06 +10:00
Lea Anthony
bd9751d888 feat: Support distribution support requests 2019-06-25 08:13:20 +10:00
Lea Anthony
7d171b0907 feat: initial support for platform requests 2019-06-24 09:11:06 +10:00
Lea Anthony
5b8f311465 Merge pull request #130 from wailsapp/123-Unify-Runtime-APIs
fix: linting
2019-06-22 08:47:25 +10:00
Lea Anthony
801465ac51 fix: linting 2019-06-22 08:45:46 +10:00
Lea Anthony
a84e2ae9b3 Merge pull request #129 from wailsapp/123-Unify-Runtime-APIs
feat: unify runtime API signatures
2019-06-22 08:43:23 +10:00
Lea Anthony
9496d1d47f Merge pull request #126 from bh90210/121-react-template-build-error
fix(react template): reverting bugfix + code clean-up
2019-06-22 08:39:16 +10:00
Lea Anthony
36e575e0a2 feat: unify runtime API signatures 2019-06-22 08:36:11 +10:00
ktc
70ccb8942b fix(react template): reverting bugfix + code clean-up 2019-06-19 20:09:23 +03:00
Lea Anthony
d3cd3d43bd chore: version bump 2019-06-19 21:04:27 +10:00
Lea Anthony
9116f0d06c Merge pull request #124 from wailsapp/116-Add-browser-methods-to-runtime
116 add browser methods to runtime
2019-06-19 21:01:53 +10:00
Lea Anthony
2c91e26add docs: guardrails badge 2019-06-19 21:01:00 +10:00
Lea Anthony
f1647443dc chore: add .jshintrc file to indicate es6 2019-06-19 20:54:36 +10:00
Lea Anthony
b6b6ce2d4a fix: linting fix 2019-06-19 20:53:04 +10:00
Lea Anthony
abcc869537 feat: added OpenFile 2019-06-19 20:49:39 +10:00
Lea Anthony
3e02e1676a Merge pull request #122 from bh90210/121-react-template-build-error
fix(react template): build bugfix
2019-06-19 08:31:57 +10:00
Lea Anthony
5c8a4de446 fix: version 2019-06-19 08:29:15 +10:00
Lea Anthony
7cabef946e feat: initial support for browser.openURL for f/e 2019-06-19 08:28:31 +10:00
ktc
f2519e5af2 fix(react template): build bugfix 2019-06-18 13:57:45 +03:00
Lea Anthony
63f1767755 Merge pull request #120 from wailsapp/develop
Release v0.16.0
2019-06-18 08:25:24 +10:00
Lea Anthony
5b002e88b7 feat: v0.16.0 release 2019-06-18 08:18:49 +10:00
Lea Anthony
3723e70e6f Merge pull request #117 from bh90210/master
react template
2019-06-16 17:31:02 +10:00
admin_3.exe
7c08ddbb07 Merge branch 'develop' into master 2019-06-16 10:20:36 +03:00
Lea Anthony
c8027f5b81 feat: react template 2019-06-16 17:13:40 +10:00
ktc
393e418e68 react template 2019-06-15 14:52:47 +03:00
Lea Anthony
dcc3e5fa79 Merge pull request #113 from wailsapp/112-deprecate-backend-injection-of-css-js
112 deprecate backend injection of css js
2019-05-30 08:46:21 +10:00
Lea Anthony
f4e6c407ba chore: remove old JS/CSS api 2019-05-30 08:43:26 +10:00
Lea Anthony
e718a56ed9 docs: updated contributors 2019-05-27 18:43:33 +10:00
Lea Anthony
068443f3fd Merge pull request #110 from ocelotsloth/develop
CMD: LINUX: Arch Linux detection without lsb-release
2019-05-27 18:41:26 +10:00
Mark Stenglein
1efc8cb934 CMD: LINUX: Arch Linux detection without lsb-release
The existing distribution detection does not work on Arch Linux
without the `lsb-release` package installed. This patch adds
detection using `/etc/os-release` in the same way that f9a1881
uses for Fedora and CentOS detection.

I changed the if statement that Bryn Sinclair used to a case
statement to avoid extra if-else-if statements.

I also needed to add a trim statement to remove the `"` characters
that are present in Arch Linux's `/etc/os-release` file.
2019-05-26 20:30:05 -04:00
Lea Anthony
1ce0620620 Merge pull request #107 from wailsapp/develop
Release v0.15.0
2019-05-26 14:03:47 +10:00
Lea Anthony
249a35f90f chore: release v0.15.0 2019-05-26 13:56:27 +10:00
Lea Anthony
d003de3270 chore: remove old package-lock.json 2019-05-26 13:46:51 +10:00
Lea Anthony
9cb2ed10b5 Update CONTRIBUTORS.md 2019-05-26 13:32:55 +10:00
Lea Anthony
4a376f1b67 fix: windows spinner 2019-05-25 12:22:20 +10:00
Lea Anthony
c540f3902c fix: polyfill for windows 2019-05-25 12:19:03 +10:00
Lea Anthony
accc04ef90 chore: version bump 2019-05-25 11:30:01 +10:00
Lea Anthony
d54bd3dc54 Merge pull request #106 from wailsapp/105-create-vuetify-template
Create vuetify template
2019-05-25 11:20:37 +10:00
Lea Anthony
a54bbb4e14 chore: linting fixes 2019-05-25 11:17:39 +10:00
Lea Anthony
6b1b999546 feat: add vuetify template 2019-05-25 11:13:34 +10:00
Lea Anthony
a5aeafc4bc chore: version bump 2019-05-25 09:28:21 +10:00
Lea Anthony
39ea5cc456 Update bug_report.md 2019-05-24 08:17:05 +10:00
Lea Anthony
a225b8d50a Update bug_report.md 2019-05-24 08:13:56 +10:00
Lea Anthony
e0036b1cbb Update bug_report.md 2019-05-24 08:11:18 +10:00
Lea Anthony
9a5833f7c9 Merge pull request #102 from wailsapp/98-use-snap-command
fix: use snap command for linux
2019-05-23 08:58:00 +10:00
Lea Anthony
06a1372e80 fix: use snap command for linux 2019-05-23 08:57:11 +10:00
Lea Anthony
7a16cf74f0 docs: mandate go 1.12 2019-05-22 19:25:09 +10:00
Lea Anthony
4239c89b76 Merge pull request #100 from wailsapp/99-update-issue-template
fix: align with new bug template
2019-05-22 19:14:46 +10:00
Lea Anthony
29ea5cc74d fix: slign with new bug template 2019-05-22 19:13:17 +10:00
Lea Anthony
fa27be083d Update bug_report.md 2019-05-22 19:09:50 +10:00
Lea Anthony
9be56c47e4 chore: reset version 2019-05-22 08:35:38 +10:00
Lea Anthony
249720b0cc chore: version bump 2019-05-22 08:30:24 +10:00
Lea Anthony
3553cb6694 Merge pull request #97 from wailsapp/92-build-on-first-init
92 build on first init
2019-05-22 07:27:19 +10:00
Lea Anthony
3c0fa4c55e chore: lint fixes 2019-05-22 07:25:42 +10:00
Lea Anthony
c07a4b6c16 Merge branch 'develop' into 92-build-on-first-init 2019-05-22 00:56:30 +10:00
Lea Anthony
8175eb4446 chore: version bump 2019-05-22 00:50:28 +10:00
Lea Anthony
eeab418c90 fix: version issue 2019-05-22 00:43:56 +10:00
Lea Anthony
0eb59d823e fix: version craziness 2019-05-22 00:42:17 +10:00
Lea Anthony
f07705268d feat: moar spinners 2019-05-20 23:53:14 +10:00
Lea Anthony
63fef39854 feat: build on init 2019-05-20 23:40:17 +10:00
Lea Anthony
3ea45da2c8 chore: version bump v0.14.5-pre 2019-05-20 20:47:35 +10:00
Lea Anthony
eb0d9f3ba4 Merge pull request #96 from wailsapp/91-create-developer-tooling
91 create developer tooling
2019-05-20 18:58:43 +10:00
Lea Anthony
ddcc103f37 Update README.md 2019-05-19 13:56:58 +10:00
Lea Anthony
b849964562 docs: fix awesomego link 2019-05-12 22:18:19 +10:00
103 changed files with 2371 additions and 11520 deletions

29
.eslintrc.js Normal file
View File

@@ -0,0 +1,29 @@
module.exports = {
"env": {
"browser": true,
"es6": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2016,
"sourceType": "module",
},
"rules": {
"indent": [
"error",
"tab"
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
};

View File

@@ -7,6 +7,11 @@ assignees: ''
---
#####################################################
If you have a technical issue, please do not open a bug this way!
Please use the `wails issue` command!
#####################################################
**Description**
A clear and concise description of what the bug is.
@@ -24,7 +29,7 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**System Details**
Please paste the output of `wails report` here.
Please provide your platform, GO version and variables, etc
**Additional context**
Add any other context about the problem here.

3
.jshintrc Normal file
View File

@@ -0,0 +1,3 @@
{
"esversion": 6
}

View File

@@ -1,3 +1,4 @@
{
"go.formatTool": "goimports"
"go.formatTool": "goimports",
"eslint.alwaysShowStatus": true
}

View File

@@ -1,19 +1,28 @@
2019-06-18 **v0.16.0**
* React template FTW! - Thanks [admin_3.exe](https://github.com/bh90210)!
* Updated contributors
* Arch Linux detection without lsb-release
* Removed deprecated methods for dealing with JS/CSS in the backend
<a name="v0.13.0"></a>
## [v0.13.0] - 2019-05-12
2019-05-29 **v0.14.11-pre**
* Windows fix for spinner
### Feat
- revamped 'update' system
- no need for explicit GO111MODULE=on
2019-05-29 **v0.14.10-pre**
* Windows fix for Vuetify
### Fix
- documentation typo fixes
- windows init project
- windows 10 colour
- leave windows assets on -p flag
- show prerequisite errors
2019-05-29 **v0.14.9-pre**
* Vuetify project template 🎉
### Docs
- updated contributors
- added awesomego logo
- added Redhat distro
2019-05-29 **v0.14.8-pre**
* Updated Ubuntu npm install command
2019-05-22 **v0.14.7-pre**
* New projects are built automatically when initialised
* Go 1.12 is now a minimum requirement
2019-05-21 **v0.14.6-pre**
* Hotfix for module dependency issue
2019-05-20 **v0.14.5-pre**
* Added developer tooling - New Template Generator
* Documentation fixes - Thanks [admin_3.exe](https://github.com/bh90210)!

View File

@@ -8,5 +8,8 @@ Wails is what it is because of the time and effort given by these great people.
* [Adrian Lanzafame](https://github.com/lanzafame)
* [0xflotus](https://github.com/0xflotus)
* [Michael D Henderson](https://github.com/mdhender)
* [fred2104] (https://github.com/fishfishfish2104)
* [intelwalk] (https://github.com/intelwalk)
* [fred2104](https://github.com/fishfishfish2104)
* [intelwalk](https://github.com/intelwalk)
* [Mark Stenglein](https://github.com/ocelotsloth)
* [admin_3.exe](https://github.com/bh90210)
* [iceleo-com](https://github.com/iceleo-com)

View File

@@ -9,7 +9,8 @@
<a href="https://www.codefactor.io/repository/github/wailsapp/wails"><img src="https://www.codefactor.io/repository/github/wailsapp/wails/badge" alt="CodeFactor" /></a>
<a href="https://github.com/wailsapp/wails/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="CodeFactor" /></a>
<a href="https://houndci.com"><img src="https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg"/></a>
<a href="https://github.com/sindresorhus/awesome" rel="nofollow"><img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome"></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://dashboard.guardrails.io/default/gh/wailsapp/wails"><img src="https://badges.guardrails.io/wailsapp/wails.svg?token=53657bc22ec360d7673c894fdd70568e918ec581d10d84427ed4de5fe1eeff1a"></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!
@@ -18,6 +19,7 @@ The traditional method of providing web interfaces to Go programs is via a built
- Use standard Go libraries/frameworks for the backend
- Use any frontend technology to build your UI
- Quickly create Vue, Vuetify or React frontends for your Go programs
- Expose Go methods/functions to the frontend via a single bind command
- Uses native rendering engines - no embedded browser
- Shared events system
@@ -33,7 +35,7 @@ Wails is currently in Beta. Please make sure you read the [Project Status](https
Wails uses cgo to bind to the native rendering engines so a number of platform dependent libraries are needed as well as an installation of Go. The basic requirements are:
- Go 1.11 or above
- Go 1.12
- npm
### MacOS
@@ -44,7 +46,7 @@ Make sure you have the xcode command line tools installed. This can be done by r
### Linux
#### Ubuntu 18.04
#### Ubuntu 18.04, Debian 9
`sudo apt install pkg-config build-essential libgtk-3-dev libwebkit2gtk-4.0-dev`
@@ -64,6 +66,8 @@ Windows requires gcc and related tooling. The recommended download is from [http
## Installation
**Ensure Go modules are enabled: GO111MODULE=on and go/bin is in your PATH variable.**
Installation is as simple as running the following command:
<pre style='color:white'>
@@ -95,7 +99,7 @@ Without the following people, this project would never have existed:
* [Dustin Krysak](https://wiki.ubuntu.com/bashfulrobot) - His support and feedback has been immense. More patience than you can throw a stick at (Not long now Dustin!).
* [Serge Zaitsev](https://github.com/zserge) - Creator of [Webview](https://github.com/zserge/webview) which Wails uses for the windowing.
And without [these people](CONTRIBUTORS.md), it wouldn't be what it is today.
And without [these people](CONTRIBUTORS.md), it wouldn't be what it is today. A huge thank you to each and every one of you!
Special Mentions:

23
app.go
View File

@@ -22,11 +22,6 @@ type App struct {
bindingManager *bindingManager // Handles binding of Go code to renderer
eventManager *eventManager // Handles all the events
runtime *Runtime // The runtime object for registered structs
// This is a list of all the JS/CSS that needs injecting
// It will get injected in order
jsCache []string
cssCache []string
}
// CreateApp creates the application window with the given configuration
@@ -111,12 +106,6 @@ func (a *App) start() error {
return err
}
// Inject CSS
a.renderer.AddCSSList(a.cssCache)
// Inject JS
a.renderer.AddJSList(a.jsCache)
// Run the renderer
return a.renderer.Run()
}
@@ -126,15 +115,3 @@ func (a *App) start() error {
func (a *App) Bind(object interface{}) {
a.bindingManager.bind(object)
}
// AddJS adds a piece of Javascript to a cache that
// gets injected at runtime
func (a *App) AddJS(js string) {
a.jsCache = append(a.jsCache, js)
}
// AddCSS adds a CSS string to a cache that
// gets injected at runtime
func (a *App) AddCSS(js string) {
a.cssCache = append(a.cssCache, js)
}

65
binding_internal.go Normal file
View File

@@ -0,0 +1,65 @@
package wails
import "strings"
import "fmt"
type internalMethods struct{
log *CustomLogger
browser *RuntimeBrowser
}
func newInternalMethods() *internalMethods {
return &internalMethods{
log: newCustomLogger("InternalCall"),
browser: newRuntimeBrowser(),
}
}
func (i *internalMethods) processCall(callData *callData) (interface{}, error) {
if !strings.HasPrefix(callData.BindingName, ".wails.") {
return nil, fmt.Errorf("Invalid call signature '%s'", callData.BindingName)
}
// Strip prefix
var splitCall = strings.Split(callData.BindingName,".")[2:]
if len(splitCall) != 2 {
return nil, fmt.Errorf("Invalid call signature '%s'", callData.BindingName)
}
group := splitCall[0]
switch group {
case "Browser":
return i.processBrowserCommand(splitCall[1], callData.Data)
default:
return nil, fmt.Errorf("Unknown internal command group '%s'", group)
}
}
func (i *internalMethods) processBrowserCommand(command string, data interface{}) (interface{}, error) {
switch command {
case "OpenURL":
url := data.(string)
// Strip string quotes. Credit: https://stackoverflow.com/a/44222648
if url[0] == '"' {
url = url[1:]
}
if i := len(url)-1; url[i] == '"' {
url = url[:i]
}
i.log.Debugf("Calling Browser.OpenURL with '%s'", url)
return nil, i.browser.OpenURL(url)
case "OpenFile":
filename := data.(string)
// Strip string quotes. Credit: https://stackoverflow.com/a/44222648
if filename[0] == '"' {
filename = filename[1:]
}
if i := len(filename)-1; filename[i] == '"' {
filename = filename[:i]
}
i.log.Debugf("Calling Browser.OpenFile with '%s'", filename)
return nil, i.browser.OpenFile(filename)
default:
return nil, fmt.Errorf("Unknown Browser command '%s'", command)
}
}

View File

@@ -17,6 +17,7 @@ binding:
type bindingManager struct {
methods map[string]*boundMethod
functions map[string]*boundFunction
internalMethods *internalMethods
initMethods []*boundMethod
log *CustomLogger
renderer Renderer
@@ -27,9 +28,10 @@ type bindingManager struct {
func newBindingManager() *bindingManager {
result := &bindingManager{
methods: make(map[string]*boundMethod),
functions: make(map[string]*boundFunction),
log: newCustomLogger("Bind"),
methods: make(map[string]*boundMethod),
functions: make(map[string]*boundFunction),
log: newCustomLogger("Bind"),
internalMethods: newInternalMethods(),
}
return result
}
@@ -163,6 +165,11 @@ func (b *bindingManager) bind(object interface{}) {
b.objectsToBind = append(b.objectsToBind, object)
}
func (b *bindingManager) processInternalCall(callData *callData) (interface{}, error) {
// Strip prefix
return b.internalMethods.processCall(callData)
}
func (b *bindingManager) processFunctionCall(callData *callData) (interface{}, error) {
// Return values
var result []reflect.Value
@@ -254,6 +261,8 @@ func (b *bindingManager) processCall(callData *callData) (result interface{}, er
result, err = b.processFunctionCall(callData)
case 2:
result, err = b.processMethodCall(callData)
case 3:
result, err = b.processInternalCall(callData)
default:
result = nil
err = fmt.Errorf("Invalid binding name '%s'", callData.BindingName)

10
cmd/cmd-mewn.go Normal file

File diff suppressed because one or more lines are too long

View File

@@ -110,16 +110,19 @@ func (fs *FSHelper) RemoveFiles(files []string) error {
return nil
}
// Dir holds information about a directory
type Dir struct {
localPath string
fullPath string
}
func (fs *FSHelper) Dir(dir string) (*Dir, error) {
// Directory creates a new Dir struct with the given directory path
func (fs *FSHelper) Directory(dir string) (*Dir, error) {
fullPath, err := filepath.Abs(dir)
return &Dir{fullPath: fullPath}, err
}
// LocalDir creates a new Dir struct based on a path relative to the caller
func (fs *FSHelper) LocalDir(dir string) (*Dir, error) {
_, filename, _, _ := runtime.Caller(1)
fullPath, err := filepath.Abs(filepath.Join(path.Dir(filename), dir))

View File

@@ -3,9 +3,12 @@ package cmd
import (
"fmt"
"io/ioutil"
"net/url"
"os"
"regexp"
"runtime"
"strings"
"github.com/pkg/browser"
)
// LinuxDistribution is of type int
@@ -20,6 +23,8 @@ const (
Arch
// RedHat linux distribution
RedHat
// Debian distribution
Debian
)
// DistroInfo contains all the information relating to a linux distribution
@@ -29,6 +34,7 @@ type DistroInfo struct {
Release string
Codename string
DistributorID string
DiscoveredBy string
}
// GetLinuxDistroInfo returns information about the running linux distribution
@@ -43,7 +49,7 @@ func GetLinuxDistroInfo() *DistroInfo {
if err != nil {
return result
}
result.DiscoveredBy = "lsb"
for _, line := range strings.Split(stdout, "\n") {
if strings.Contains(line, ":") {
// Iterate lines a
@@ -58,6 +64,8 @@ func GetLinuxDistroInfo() *DistroInfo {
result.Distribution = Ubuntu
case "Arch", "ManjaroLinux":
result.Distribution = Arch
case "Debian":
result.Distribution = Debian
}
case "Description":
result.Description = value
@@ -65,22 +73,49 @@ func GetLinuxDistroInfo() *DistroInfo {
result.Release = value
case "Codename":
result.Codename = value
}
}
}
// check if /etc/os-release exists
} else if _, err := os.Stat("/etc/os-release"); !os.IsNotExist(err) {
// Default value
osName := "Unknown"
version := ""
// read /etc/os-release
osRelease, _ := ioutil.ReadFile("/etc/os-release")
// compile a regex to find NAME=distro
re := regexp.MustCompile(`^NAME=(.*)\n`)
// extract the distro name
osName := string(re.FindSubmatch(osRelease)[1])
// Check distro name against list of RedHat distros
if osName == "Fedora" || osName == "CentOS" {
//if it matches set result.Distribution to RedHat
// Split into lines
lines := strings.Split(string(osRelease), "\n")
// Iterate lines
for _, line := range lines {
// Split each line by the equals char
splitLine := strings.SplitN(line, "=", 2)
// Check we have
if len(splitLine) != 2 {
continue
}
switch splitLine[0] {
case "NAME":
osName = strings.Trim(splitLine[1], "\"")
case "VERSION_ID":
version = strings.Trim(splitLine[1], "\"")
}
}
// Check distro name against list of distros
result.Release = version
result.DiscoveredBy = "os-release"
switch osName {
case "Fedora":
result.Distribution = RedHat
case "CentOS":
result.Distribution = RedHat
case "Arch Linux":
result.Distribution = Arch
case "Debian GNU/Linux":
result.Distribution = Debian
default:
result.Distribution = Unknown
result.DistributorID = osName
}
}
return result
@@ -118,3 +153,45 @@ func RpmInstalled(packageName string) (bool, error) {
_, _, exitCode, _ := rpm.Run("--query", packageName)
return exitCode == 0, nil
}
// RequestSupportForDistribution promts the user to submit a request to support their
// currently unsupported distribution
func RequestSupportForDistribution(distroInfo *DistroInfo, libraryName string) error {
var logger = NewLogger()
defaultError := fmt.Errorf("unable to check libraries on distribution '%s'. Please ensure that the '%s' equivalent is installed", distroInfo.DistributorID, libraryName)
logger.Yellow("Distribution '%s' is not currently supported, but we would love to!", distroInfo.DistributorID)
q := fmt.Sprintf("Would you like to submit a request to support distribution '%s'?", distroInfo.DistributorID)
result := Prompt(q, "yes")
if strings.ToLower(result) != "yes" {
return defaultError
}
title := fmt.Sprintf("Support Distribution '%s'", distroInfo.DistributorID)
var str strings.Builder
gomodule, exists := os.LookupEnv("GO111MODULE")
if !exists {
gomodule = "(Not Set)"
}
str.WriteString("\n| Name | Value |\n| ----- | ----- |\n")
str.WriteString(fmt.Sprintf("| Wails Version | %s |\n", Version))
str.WriteString(fmt.Sprintf("| Go Version | %s |\n", runtime.Version()))
str.WriteString(fmt.Sprintf("| Platform | %s |\n", runtime.GOOS))
str.WriteString(fmt.Sprintf("| Arch | %s |\n", runtime.GOARCH))
str.WriteString(fmt.Sprintf("| GO111MODULE | %s |\n", gomodule))
str.WriteString(fmt.Sprintf("| Distribution ID | %s |\n", distroInfo.DistributorID))
str.WriteString(fmt.Sprintf("| Distribution Version | %s |\n", distroInfo.Release))
str.WriteString(fmt.Sprintf("| Discovered by | %s |\n", distroInfo.DiscoveredBy))
body := fmt.Sprintf("**Description**\nDistribution '%s' is currently unsupported.\n\n**Further Information**\n\n%s\n\n*Please add any extra information here, EG: libraries that are needed to make the distribution work, or commands to install them*", distroInfo.DistributorID, str.String())
fullURL := "https://github.com/wailsapp/wails/issues/new?"
params := "title=" + title + "&body=" + body
fmt.Println("Opening browser to file request.")
browser.OpenURL(fullURL + url.PathEscape(params))
return nil
}

View File

@@ -49,11 +49,10 @@ func getRequiredProgramsLinux() *Prerequisites {
result := &Prerequisites{}
distroInfo := GetLinuxDistroInfo()
switch distroInfo.Distribution {
case Ubuntu:
case Ubuntu, Debian:
result.Add(newPrerequisite("gcc", "Please install with `sudo apt install build-essentials` and try again"))
result.Add(newPrerequisite("pkg-config", "Please install with `sudo apt install pkg-config` and try again"))
result.Add(newPrerequisite("npm", "Please install with `sudo apt install npm` and try again"))
result.Add(newPrerequisite("npm", "Please install with `sudo snap install node --channel=12/stable --classic` and try again"))
default:
result.Add(newPrerequisite("gcc", "Please install with your system package manager and try again"))
result.Add(newPrerequisite("pkg-config", "Please install with your system package manager and try again"))

View File

@@ -7,6 +7,7 @@ import (
"os"
"path/filepath"
"runtime"
"sort"
"strings"
"github.com/leaanthony/slicer"
@@ -84,8 +85,6 @@ func (ph *ProjectHelper) GenerateProject(projectOptions *ProjectOptions) error {
// ph.GenerateWindowsResourceConfig(projectOptions)
// }
ph.log.Yellow("Project '%s' generated in directory '%s'!", projectOptions.Name, projectOptions.OutputDirectory)
ph.log.Yellow("To compile the project, run 'wails build' in the project directory.")
return nil
}
@@ -145,11 +144,13 @@ type ProjectOptions struct {
log *Logger
templates *TemplateHelper
selectedTemplate *TemplateDetails
WailsVersion string
}
// Defaults sets the default project template
func (po *ProjectOptions) Defaults() {
po.Template = "vuebasic"
po.WailsVersion = Version
}
// PromptForInputs asks the user to input project details
@@ -184,7 +185,13 @@ func (po *ProjectOptions) PromptForInputs() error {
po.selectedTemplate = templateDetails[po.Template]
} else {
for _, templateDetail := range templateDetails {
keys := make([]string, 0)
for k := range templateDetails {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
templateDetail := templateDetails[k]
templateList.Add(templateDetail)
options.Add(fmt.Sprintf("%s - %s", templateDetail.Metadata.Name, templateDetail.Metadata.ShortDescription))
}

View File

@@ -272,7 +272,7 @@ func CheckDependencies(logger *Logger) (bool, error) {
distroInfo := GetLinuxDistroInfo()
for _, library := range *requiredLibraries {
switch distroInfo.Distribution {
case Ubuntu:
case Ubuntu, Debian:
installed, err := DpkgInstalled(library.Name)
if err != nil {
return false, err
@@ -295,7 +295,6 @@ func CheckDependencies(logger *Logger) (bool, error) {
logger.Green("Library '%s' installed.", library.Name)
}
case RedHat:
installed, err := RpmInstalled(library.Name)
if err != nil {
return false, err
@@ -307,7 +306,7 @@ func CheckDependencies(logger *Logger) (bool, error) {
logger.Green("Library '%s' installed.", library.Name)
}
default:
return false, fmt.Errorf("unable to check libraries on distribution '%s'. Please ensure that the '%s' equivalent is installed", distroInfo.DistributorID, library.Name)
return false, RequestSupportForDistribution(distroInfo, library.Name)
}
}
}

View File

@@ -16,18 +16,26 @@ import (
// TemplateMetadata holds all the metadata for a Wails template
type TemplateMetadata struct {
Name string `json:"name"`
Version string `json:"version"`
ShortDescription string `json:"shortdescription"`
Description string `json:"description"`
Install string `json:"install"`
Build string `json:"build"`
Author string `json:"author"`
Created string `json:"created"`
FrontendDir string `json:"frontenddir"`
Serve string `json:"serve"`
Bridge string `json:"bridge"`
WailsDir string `json:"wailsdir"`
Name string `json:"name"`
Version string `json:"version"`
ShortDescription string `json:"shortdescription"`
Description string `json:"description"`
Install string `json:"install"`
Build string `json:"build"`
Author string `json:"author"`
Created string `json:"created"`
FrontendDir string `json:"frontenddir"`
Serve string `json:"serve"`
Bridge string `json:"bridge"`
WailsDir string `json:"wailsdir"`
TemplateDependencies []*TemplateDependency `json:"dependencies,omitempty"`
}
// TemplateDependency defines a binary dependency for the template
// EG: ng for angular
type TemplateDependency struct {
Bin string `json:"bin"`
Help string `json:"help"`
}
// TemplateDetails holds information about a specific template
@@ -141,7 +149,7 @@ func (t *TemplateHelper) GetTemplateDetails() (map[string]*TemplateDetails, erro
func (t *TemplateHelper) GetTemplateFilenames(template *TemplateDetails) (*slicer.StringSlicer, error) {
// Get the subdirectory details
templateDir, err := t.fs.Dir(template.Path)
templateDir, err := t.fs.Directory(template.Path)
if err != nil {
return nil, err
}
@@ -152,6 +160,31 @@ func (t *TemplateHelper) GetTemplateFilenames(template *TemplateDetails) (*slice
// project path given
func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *ProjectOptions) error {
// Check dependencies before installing
dependencies := projectOptions.selectedTemplate.Metadata.TemplateDependencies
if dependencies != nil {
programHelper := NewProgramHelper()
logger := NewLogger()
errors := []string{}
for _, dep := range dependencies {
program := programHelper.FindProgram(dep.Bin)
if program == nil {
errors = append(errors, dep.Help)
}
}
if len(errors) > 0 {
mainError := "template dependencies not installed"
if len(errors) == 1 {
mainError = errors[0]
} else {
for _, error := range errors {
logger.Red(error)
}
}
return fmt.Errorf(mainError)
}
}
// Get template files
templateFilenames, err := t.GetTemplateFilenames(projectOptions.selectedTemplate)
if err != nil {
@@ -160,6 +193,9 @@ func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *Pro
templatePath := projectOptions.selectedTemplate.Path
// Save the version
projectOptions.WailsVersion = Version
templateJSONFilename := filepath.Join(templatePath, t.metadataFilename)
templateFiles := templateFilenames.Filter(func(filename string) bool {

View File

@@ -0,0 +1,13 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
max_line_length = off
trim_trailing_whitespace = false

View File

@@ -0,0 +1,47 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
/out-tsc
# Only exists if Bazel was run
/bazel-out
# dependencies
/node_modules
# profiling files
chrome-profiler-events.json
speed-measure-plugin.json
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# System Files
.DS_Store
Thumbs.db
.editorcinfig

View File

@@ -0,0 +1,27 @@
# MyApp
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.0.3.
## Development server
Run `npx ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
## Code scaffolding
Run `npx ng generate component component-name` to generate a new component. You can also use `npx ng generate directive|pipe|service|class|guard|interface|enum|module`.
## Build
Run `npx ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
## Running unit tests
Run `npx ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests
Run `npx ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
## Further help
To get more help on the Angular CLI use `npx ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).

View File

@@ -0,0 +1,121 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"my-app": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "ngx-build-plus:browser",
"options": {
"outputPath": "dist/my-app",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": false,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
}
}
},
"serve": {
"builder": "ngx-build-plus:dev-server",
"options": {
"browserTarget": "my-app:build"
},
"configurations": {
"production": {
"browserTarget": "my-app:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "my-app:build"
}
},
"test": {
"builder": "ngx-build-plus:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "my-app:serve"
},
"configurations": {
"production": {
"devServerTarget": "my-app:serve:production"
}
}
}
}
}
},
"defaultProject": "my-app"
}

View File

@@ -0,0 +1,12 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# You can see what browsers were selected by your queries by running:
# npx browserslist
> 0.5%
last 2 versions
Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'.

View File

@@ -0,0 +1,32 @@
// @ts-check
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter } = require('jasmine-spec-reporter');
/**
* @type { import("protractor").Config }
*/
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};

View File

@@ -0,0 +1,23 @@
import { AppPage } from './app.po';
import { browser, logging } from 'protractor';
describe('workspace-project App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should display welcome message', () => {
page.navigateTo();
expect(page.getTitleText()).toEqual('Welcome to my-app!');
});
afterEach(async () => {
// Assert that there are no errors emitted from the browser
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
expect(logs).not.toContain(jasmine.objectContaining({
level: logging.Level.SEVERE,
} as logging.Entry));
});
});

View File

@@ -0,0 +1,11 @@
import { browser, by, element } from 'protractor';
export class AppPage {
navigateTo() {
return browser.get(browser.baseUrl) as Promise<any>;
}
getTitleText() {
return element(by.css('app-root h1')).getText() as Promise<string>;
}
}

View File

@@ -0,0 +1,13 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"module": "commonjs",
"target": "es5",
"types": [
"jasmine",
"jasminewd2",
"node"
]
}
}

View File

@@ -0,0 +1,32 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, './coverage/my-app'),
reports: ['html', 'lcovonly', 'text-summary'],
fixWebpackSourcePaths: true
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};

View File

@@ -0,0 +1,50 @@
{
"name": "my-app",
"version": "0.0.0",
"scripts": {
"ng": "npx ng",
"start": "npx ng serve --poll=2000",
"build": "npx ng build --single-bundle true --output-hashing none --prod --bundle-styles false",
"test": "npx ng test",
"lint": "npx ng lint",
"e2e": "npx ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^8.0.2",
"@angular/cdk": "^8.0.1",
"@angular/common": "~8.0.1",
"@angular/compiler": "~8.0.1",
"@angular/core": "~8.0.1",
"@angular/forms": "~8.0.1",
"@angular/material": "^8.0.1",
"@angular/platform-browser": "~8.0.1",
"@angular/platform-browser-dynamic": "~8.0.1",
"@angular/router": "~8.0.1",
"ngx-build-plus": "^8.0.3",
"rxjs": "~6.4.0",
"tslib": "^1.9.0",
"zone.js": "~0.9.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.800.0",
"@angular/cli": "~8.0.3",
"@angular/compiler-cli": "~8.0.1",
"@angular/language-service": "~8.0.1",
"@types/node": "~8.9.4",
"@types/jasmine": "~3.3.8",
"@types/jasminewd2": "~2.0.3",
"codelyzer": "^5.0.0",
"jasmine-core": "~3.4.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.1.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.0",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.15.0",
"typescript": "~3.4.3"
}
}

View File

@@ -0,0 +1,13 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [];
@NgModule({
imports: [
RouterModule.forRoot(routes)
],
exports: [RouterModule]
})
export class AppRoutingModule { }

View File

@@ -0,0 +1,14 @@
<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
<img width="300" alt="Angular Logo"
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
<br />
<button (click)="onClickMe()">Hello</button>
<p>{{clickMessage}}</p>
</div>
<router-outlet></router-outlet>

View File

@@ -0,0 +1,35 @@
import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'my-app'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('my-app');
});
it('should render title in a h1 tag', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to my-app!');
});
});

View File

@@ -0,0 +1,19 @@
import { Component } from '@angular/core';
@Component({
selector: '[id="app"]',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'my-app';
clickMessage = '';
onClickMe() {
// @ts-ignore
window.backend.basic().then(result =>
this.clickMessage = result
);
}
}

View File

@@ -0,0 +1,20 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { APP_BASE_HREF } from '@angular/common';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [{provide: APP_BASE_HREF, useValue : '/' }],
bootstrap: [AppComponent]
})
export class AppModule { }

View File

@@ -0,0 +1,3 @@
export const environment = {
production: true
};

View File

@@ -0,0 +1,16 @@
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false
};
/*
* For easier debugging in development mode, you can import the following file
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
*
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>my-app</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<div id="app"></div>
</body>
</html>

View File

@@ -0,0 +1,18 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import 'zone.js'
import Bridge from './wailsbridge';
if (environment.production) {
enableProdMode();
}
Bridge.Start(() => {
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
});

View File

@@ -0,0 +1,63 @@
/**
* This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file.
*
* This file is divided into 2 sections:
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
* file.
*
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
*
* Learn more in https://angular.io/guide/browser-support
*/
/***************************************************************************************************
* BROWSER POLYFILLS
*/
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/**
* Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
*/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/**
* By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags
* because those flags need to be set before `zone.js` being loaded, and webpack
* will put import in the top of bundle, so user need to create a separate file
* in this directory (for example: zone-flags.ts), and put the following flags
* into that file, and then add the following code before importing zone.js.
* import './zone-flags.ts';
*
* The flags allowed in zone-flags.ts are listed here.
*
* The following flags will work for all browsers.
*
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
*
* (window as any).__Zone_enable_cross_context_check = true;
*
*/
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
//import 'zone.js/dist/zone'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/

View File

@@ -0,0 +1,24 @@
/* You can add global styles to this file, and also import other style files */
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background-color: #282c34;
}
p {
color: white
}
h1 {
color: white
}
button {
background-color: white;
color: black;
}

View File

@@ -0,0 +1,20 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/zone-testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
declare const require: any;
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

View File

@@ -0,0 +1,17 @@
/*
Wails Bridge (c) 2019-present Lea Anthony
This prod version is to get around having to rewrite your code
for production. When doing a release build, this file will be used
instead of the full version.
*/
export default {
// The main function
// Passes the main Wails object to the callback if given.
Start: function(callback) {
if (callback) {
window.wails.events.on("wails:ready", callback);
}
}
};

View File

@@ -0,0 +1,14 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": []
},
"include": [
"src/**/*.ts"
],
"exclude": [
"src/test.ts",
"src/**/*.spec.ts"
]
}

View File

@@ -0,0 +1,23 @@
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "esnext",
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2018",
"dom"
]
}
}

View File

@@ -0,0 +1,18 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": [
"jasmine",
"node"
]
},
"files": [
"src/test.ts",
"src/polyfills.ts"
],
"include": [
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}

View File

@@ -0,0 +1,92 @@
{
"extends": "tslint:recommended",
"rules": {
"array-type": false,
"arrow-parens": false,
"deprecation": {
"severity": "warn"
},
"component-class-suffix": true,
"contextual-lifecycle": true,
"directive-class-suffix": true,
"directive-selector": [
true,
"attribute",
"app",
"camelCase"
],
"component-selector": [
true,
"element",
"app",
"kebab-case"
],
"import-blacklist": [
true,
"rxjs/Rx"
],
"interface-name": false,
"max-classes-per-file": false,
"max-line-length": [
true,
140
],
"member-access": false,
"member-ordering": [
true,
{
"order": [
"static-field",
"instance-field",
"static-method",
"instance-method"
]
}
],
"no-consecutive-blank-lines": false,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-empty": false,
"no-inferrable-types": [
true,
"ignore-params"
],
"no-non-null-assertion": true,
"no-redundant-jsdoc": true,
"no-switch-case-fall-through": true,
"no-use-before-declare": true,
"no-var-requires": false,
"object-literal-key-quotes": [
true,
"as-needed"
],
"object-literal-sort-keys": false,
"ordered-imports": false,
"quotemark": [
true,
"single"
],
"trailing-comma": false,
"no-conflicting-lifecycle": true,
"no-host-metadata-property": true,
"no-input-rename": true,
"no-inputs-metadata-property": true,
"no-output-native": true,
"no-output-on-prefix": true,
"no-output-rename": true,
"no-outputs-metadata-property": true,
"template-banana-in-box": true,
"template-no-negated-async": true,
"use-lifecycle-interface": true,
"use-pipe-transform-interface": true
},
"rulesDirectory": [
"codelyzer"
]
}

View File

@@ -0,0 +1,5 @@
module {{.BinaryName}}
require (
github.com/wailsapp/wails {{.WailsVersion}}
)

View File

@@ -0,0 +1,27 @@
package main
import (
"github.com/leaanthony/mewn"
"github.com/wailsapp/wails"
)
func basic() string {
return "World!"
}
func main() {
js := mewn.String("./frontend/dist/my-app/main-es2015.js")
css := mewn.String("./frontend/dist/my-app/styles.css")
app := wails.CreateApp(&wails.AppConfig{
Width: 1024,
Height: 768,
Title: "{{.Name}}",
JS: js,
CSS: css,
Colour: "#131313",
})
app.Bind(basic)
app.Run()
}

View File

@@ -0,0 +1,20 @@
{
"name": "Angular",
"version": "1.0.0",
"shortdescription": "Angular 8 template (Requires node 10.8+)",
"description": "Angular projects w/ @angular/cli - Note: in order to reach the cli use npx like this: npx ng",
"dependencies": [
{
"bin": "npx",
"help": "This template requires 'npx'. Please install with 'npm install -g npx'"
}
],
"install": "npm install",
"build": "npx ng build --single-bundle true --output-hashing none --prod --bundle-styles false",
"author": "bh90210 <ktc@pm.me>",
"created": "2019-06-15 18:23:48.666414555 +0300 EEST m=+223.934866008",
"frontenddir": "frontend",
"serve": "npx ng serve --poll=2000",
"bridge": "src",
"wailsdir": ""
}

View File

@@ -0,0 +1,3 @@
{
"esversion": 6
}

View File

@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View File

@@ -0,0 +1,68 @@
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
## Available Scripts
In the project directory, you can run:
### `npm start`
Runs the app in the development mode.<br>
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
The page will reload if you make edits.<br>
You will also see any lint errors in the console.
### `npm test`
Launches the test runner in the interactive watch mode.<br>
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `npm run build`
Builds the app for production to the `build` folder.<br>
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.<br>
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `npm run eject`
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
### Analyzing the Bundle Size
This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
### Making a Progressive Web App
This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
### Advanced Configuration
This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
### Deployment
This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
### `npm run build` fails to minify
This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify

View File

@@ -0,0 +1,33 @@
{
"name": "{{.NPMProjectName}}",
"author": "{{.Author.Name}}<{{.Author.Email}}>",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.8.6",
"react-dom": "^16.8.6",
"wails-react-scripts": "3.0.1-2",
"react-modal": "3.8.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="app"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

View File

@@ -0,0 +1,15 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@@ -0,0 +1,33 @@
.App {
text-align: center;
}
.App-logo {
animation: App-logo-spin infinite 20s linear;
height: 40vmin;
pointer-events: none;
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

View File

@@ -0,0 +1,21 @@
import React from 'react';
import logo from './logo.png';
import './App.css';
import HelloWorld from './components/HelloWorld';
function App() {
return (
<div id="app" className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Welcome to your new <code>wails/react</code> project.
</p>
<HelloWorld />
</header>
</div>
);
}
export default App;

View File

@@ -0,0 +1,9 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
});

View File

@@ -0,0 +1,48 @@
import React from 'react';
import Modal from 'react-modal';
class HelloWorld extends React.Component {
constructor(props, context) {
super();
this.state = {
showModal: false
};
this.handleOpenModal = this.handleOpenModal.bind(this);
this.handleCloseModal = this.handleCloseModal.bind(this);
}
handleOpenModal () {
this.setState({ showModal: true });
window.backend.basic().then(result =>
this.setState({
result
})
);
}
handleCloseModal () {
this.setState({ showModal: false });
}
render() {
const { result } = this.state;
return (
<div className="App">
<button onClick={this.handleOpenModal} type="button">
Hello
</button>
<Modal
isOpen={this.state.showModal}
contentLabel="Minimal Modal Example"
>
<p>{result}</p>
<button onClick={this.handleCloseModal}>Close Modal</button>
</Modal>
</div>
);
}
}
export default HelloWorld;

View File

@@ -0,0 +1,13 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}

View File

@@ -0,0 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import Bridge from "./wailsbridge";
Bridge.Start(() => {
ReactDOM.render(<App />, document.getElementById('app'));
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

View File

@@ -0,0 +1,135 @@
// This optional code is used to register a service worker.
// register() is not called by default.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on subsequent visits to a page, after all the
// existing tabs open on the page have been closed, since previously cached
// resources are updated in the background.
// To learn more about the benefits of this model and instructions on how to
// opt-in, read https://bit.ly/CRA-PWA
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export function register(config) {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Let's check if a service worker still exists or not.
checkValidServiceWorker(swUrl, config);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit https://bit.ly/CRA-PWA'
);
});
} else {
// Is not localhost. Just register service worker
registerValidSW(swUrl, config);
}
});
}
}
function registerValidSW(swUrl, config) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
if (installingWorker == null) {
return;
}
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the updated precached content has been fetched,
// but the previous service worker will still serve the older
// content until all client tabs are closed.
console.log(
'New content is available and will be used when all ' +
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
);
// Execute callback
if (config && config.onUpdate) {
config.onUpdate(registration);
}
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
// Execute callback
if (config && config.onSuccess) {
config.onSuccess(registration);
}
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl, config) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
const contentType = response.headers.get('content-type');
if (
response.status === 404 ||
(contentType != null && contentType.indexOf('javascript') === -1)
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl, config);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}

View File

@@ -0,0 +1,17 @@
/*
Wails Bridge (c) 2019-present Lea Anthony
This prod version is to get around having to rewrite your code
for production. When doing a release build, this file will be used
instead of the full version.
*/
export default {
// The main function
// Passes the main Wails object to the callback if given.
Start: function (callback) {
if (callback) {
window.wails.Events.On("wails:ready", callback);
}
}
};

View File

@@ -0,0 +1,5 @@
module {{.BinaryName}}
require (
github.com/wailsapp/wails {{.WailsVersion}}
)

View File

@@ -0,0 +1,27 @@
package main
import (
"github.com/leaanthony/mewn"
"github.com/wailsapp/wails"
)
func basic() string {
return "World!"
}
func main() {
js := mewn.String("./frontend/build/static/js/main.js")
css := mewn.String("./frontend/build/static/css/main.css")
app := wails.CreateApp(&wails.AppConfig{
Width: 1024,
Height: 768,
Title: "{{.Name}}",
JS: js,
CSS: css,
Colour: "#131313",
})
app.Bind(basic)
app.Run()
}

View File

@@ -0,0 +1,14 @@
{
"name": "React JS",
"version": "1.0.0",
"shortdescription": "Create React App v3 template",
"description": "Create React App v3 standar tooling",
"install": "npm install",
"build": "npm run build",
"author": "bh90210 <ktc@pm.me>",
"created": "2019-06-07 18:23:48.666414555 +0300 EEST m=+223.934866008",
"frontenddir": "frontend",
"serve": "npm run start",
"bridge": "src",
"wailsdir": ""
}

View File

@@ -0,0 +1,3 @@
{
"esversion": 6
}

File diff suppressed because it is too large Load Diff

View File

@@ -9,9 +9,9 @@
export default {
// The main function
// Passes the main Wails object to the callback if given.
Start: function(callback) {
Start: function (callback) {
if (callback) {
window.wails.events.on("wails:ready", callback);
window.wails.Events.On("wails:ready", callback);
}
}
};

View File

@@ -1 +1,5 @@
module {{.BinaryName}}
module {{.BinaryName}}
require (
github.com/wailsapp/wails {{.WailsVersion}}
)

View File

@@ -0,0 +1,3 @@
{
"esversion": 6
}

View File

@@ -0,0 +1,21 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*

View File

@@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/app'
]
}

View File

@@ -0,0 +1,52 @@
{
"name": "{{.NPMProjectName}}",
"author": "{{.Author.Name}}<{{.Author.Email}}>",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"babel-polyfill": "^6.26.0",
"core-js": "^2.6.4",
"material-design-icons-iconfont": "^5.0.1",
"vue": "^2.5.22",
"vuetify": "^1.5.14"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.4.0",
"@vue/cli-plugin-eslint": "^3.4.0",
"@vue/cli-service": "^3.4.0",
"babel-eslint": "^10.0.1",
"eslint": "^5.8.0",
"eslint-plugin-vue": "^5.0.0",
"eventsource-polyfill": "^0.9.6",
"vue-template-compiler": "^2.5.21",
"webpack-hot-middleware": "^2.24.3"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {},
"parserOptions": {
"parser": "babel-eslint"
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}

View File

@@ -0,0 +1,60 @@
<template>
<v-app id="inspire" dark>
<v-navigation-drawer v-model="drawer" clipped fixed app>
<v-list dense>
<v-list-tile>
<v-list-tile-action>
<v-icon>dashboard</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Dashboard</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile>
<v-list-tile-action>
<v-icon>settings</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Settings</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar app fixed clipped-left>
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
<v-toolbar-title>Application</v-toolbar-title>
</v-toolbar>
<v-content>
<v-container fluid class="px-0">
<v-layout justify-center align-center class="px-0">
<hello-world></hello-world>
</v-layout>
</v-container>
</v-content>
<v-footer app fixed>
<span style="margin-left:1em">&copy; You</span>
</v-footer>
</v-app>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
data: () => ({
drawer: false
}),
components: {
HelloWorld
},
props: {
source: String
}
};
</script>
<style>
.logo {
width: 16em;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

View File

@@ -0,0 +1,83 @@
<template>
<v-container fluid class="px-0">
<v-layout>
<v-flex xs12 sm6 offset-sm3>
<v-card raised="raised" class="pa-4 ma-4">
<v-layout justify-center align-center class="pa-4 ma-4">
<v-img :src="require('../assets/images/logo.png')"></v-img>
</v-layout>
<v-card-actions>
<v-layout justify-center align-center class="px-0">
<v-btn color="blue" dark @click="getMessage">Press Me</v-btn>
</v-layout>
</v-card-actions>
</v-card>
</v-flex>
</v-layout>
<div class="text-xs-center">
<v-dialog v-model="dialog" width="500">
<v-card>
<v-card-title class="headline" primary-title>Message from Go</v-card-title>
<v-card-text>{{message}}</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" flat @click="dialog = false">Awesome</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</v-container>
</template>
<script>
export default {
data() {
return {
message: " ",
raised: true,
dialog: false
};
},
methods: {
getMessage: function() {
var self = this;
window.backend.basic().then(result => {
self.message = result;
self.dialog = true;
});
}
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1 {
margin-top: 2em;
position: relative;
min-height: 5rem;
width: 100%;
}
a:hover {
font-size: 1.7em;
border-color: blue;
background-color: blue;
color: white;
border: 3px solid white;
border-radius: 10px;
padding: 9px;
cursor: pointer;
transition: 500ms;
}
a {
font-size: 1.7em;
border-color: white;
background-color: #121212;
color: white;
border: 3px solid white;
border-radius: 10px;
padding: 9px;
cursor: pointer;
}
</style>

View File

@@ -0,0 +1,21 @@
import 'babel-polyfill';
import Vue from "vue";
// Setup Vuetify
import Vuetify from 'vuetify';
Vue.use(Vuetify);
import 'vuetify/dist/vuetify.min.css';
import 'material-design-icons-iconfont';
import App from "./App.vue";
Vue.config.productionTip = false;
Vue.config.devtools = true;
import Bridge from "./wailsbridge";
Bridge.Start(() => {
new Vue({
render: h => h(App)
}).$mount("#app");
});

View File

@@ -0,0 +1,43 @@
let cssConfig = {};
if (process.env.NODE_ENV == "production") {
cssConfig = {
extract: {
filename: "[name].css",
chunkFilename: "[name].css"
}
};
}
module.exports = {
chainWebpack: config => {
let limit = 9999999999999999;
config.module
.rule("images")
.test(/\.(png|gif|jpg)(\?.*)?$/i)
.use("url-loader")
.loader("url-loader")
.tap(options => Object.assign(options, { limit: limit }));
config.module
.rule("fonts")
.test(/\.(woff2?|eot|ttf|otf|svg)(\?.*)?$/i)
.use("url-loader")
.loader("url-loader")
.options({
limit: limit
});
},
css: cssConfig,
configureWebpack: {
output: {
filename: "[name].js"
},
optimization: {
splitChunks: false
}
},
devServer: {
disableHostCheck: true,
host: "localhost"
}
};

View File

@@ -0,0 +1,5 @@
module {{.BinaryName}}
require (
github.com/wailsapp/wails {{.WailsVersion}}
)

View File

@@ -0,0 +1,27 @@
package main
import (
"github.com/leaanthony/mewn"
"github.com/wailsapp/wails"
)
func basic() string {
return "Hello World!"
}
func main() {
js := mewn.String("./frontend/dist/app.js")
css := mewn.String("./frontend/dist/app.css")
app := wails.CreateApp(&wails.AppConfig{
Width: 1024,
Height: 768,
Title: "{{.Name}}",
JS: js,
CSS: css,
Colour: "#131313",
})
app.Bind(basic)
app.Run()
}

View File

@@ -0,0 +1,14 @@
{
"name": "Vuetify Basic",
"version": "1.0.0",
"shortdescription": "Vuetify + Webpack",
"description": "Basic template using Vuetify and bundled using Webpack",
"install": "npm install",
"build": "npm run build",
"author": "lea <lea.anthony@gmail.com>",
"created": "2019-05-25 09:39:40.009307 +1000 AEST m=+59.539991073",
"frontenddir": "frontend",
"serve": "npm run serve",
"bridge": "src",
"wailsdir": ""
}

View File

@@ -1,4 +1,4 @@
package cmd
// Version - Wails version
const Version = "v0.14.4-pre"
const Version = "v0.17.0"

View File

@@ -96,7 +96,7 @@ func checkLibraries() (errors bool, err error) {
distroInfo := cmd.GetLinuxDistroInfo()
for _, library := range *requiredLibraries {
switch distroInfo.Distribution {
case cmd.Ubuntu:
case cmd.Ubuntu, cmd.Debian:
installed, err := cmd.DpkgInstalled(library.Name)
if err != nil {
return false, err
@@ -108,7 +108,7 @@ func checkLibraries() (errors bool, err error) {
logger.Green("Library '%s' installed.", library.Name)
}
default:
return false, fmt.Errorf("unable to check libraries on distribution '%s'. Please ensure that the '%s' equivalent is installed", distroInfo.DistributorID, library.Name)
return false, cmd.RequestSupportForDistribution(distroInfo, library.Name)
}
}
}

View File

@@ -2,7 +2,10 @@ package main
import (
"fmt"
"os"
"path/filepath"
"github.com/leaanthony/spinner"
"github.com/wailsapp/wails/cmd"
)
@@ -50,11 +53,33 @@ Any flags that are required and not given will be prompted for.`
}
}
genSpinner := spinner.NewSpinner()
genSpinner.SetSpinSpeed(50)
genSpinner.Start("Generating project...")
// Generate the project
err = projectHelper.GenerateProject(projectOptions)
if err != nil {
logger.Error(err.Error())
genSpinner.Error()
return err
}
genSpinner.Success()
// Build the project
cwd, _ := os.Getwd()
projectDir := filepath.Join(cwd, projectOptions.OutputDirectory)
program := cmd.NewProgramHelper()
buildSpinner := spinner.NewSpinner()
buildSpinner.SetSpinSpeed(50)
buildSpinner.Start("Building project (this may take a while)...")
err = program.RunCommandArray([]string{"wails", "build"}, projectDir)
if err != nil {
buildSpinner.Error(err.Error())
return err
}
buildSpinner.Success()
logger.Yellow("Project '%s' built in directory '%s'!", projectOptions.Name, projectOptions.OutputDirectory)
return err
})
}

View File

@@ -64,7 +64,7 @@ To help you in this process, we will ask for some information, add Go/Wails deta
body = "**Description**\n" + (strings.Split(body, "**Description**")[1])
fullURL := "https://github.com/wailsapp/wails/issues/new?"
body = strings.Replace(body, "A clear and concise description of what the bug is.", description, -1)
body = strings.Replace(body, "Please paste the output of `wails report` here.", str.String(), -1)
body = strings.Replace(body, "Please provide your platform, GO version and variables, etc", str.String(), -1)
params := "title=" + title + "&body=" + body
fmt.Println("Opening browser to file issue.")

6
go.mod
View File

@@ -11,9 +11,9 @@ require (
github.com/jackmordaunt/icns v1.0.0
github.com/kennygrant/sanitize v1.2.4
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/leaanthony/mewn v0.10.6
github.com/leaanthony/slicer v1.3.1
github.com/leaanthony/spinner v0.5.0
github.com/leaanthony/mewn v0.10.7
github.com/leaanthony/slicer v1.3.2
github.com/leaanthony/spinner v0.5.3
github.com/masterminds/semver v1.4.2
github.com/mattn/go-colorable v0.1.1 // indirect
github.com/mattn/go-isatty v0.0.7 // indirect

20
go.sum
View File

@@ -15,8 +15,6 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/go-playground/colors v1.2.0 h1:0EdjTXKrr2g1L/LQTYtIqabeHpZuGZz1U4osS1T8+5M=
github.com/go-playground/colors v1.2.0/go.mod h1:miw1R2JIE19cclPxsXqNdzLZsk4DP4iF+m88bRc7kfM=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
@@ -33,12 +31,12 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/leaanthony/mewn v0.10.6 h1:tL8YYcVXGpJJeWlwjd2su88or8Ul+0cQoJPNcICGMto=
github.com/leaanthony/mewn v0.10.6/go.mod h1:i3ygCWW96qVQlGa8sjWnTM0IKAijoFvTwATDIZgK4k0=
github.com/leaanthony/slicer v1.3.1 h1:n2iIV2sxvL/3bpnmVY0vBjXf3yYFWcB6CYLVMrzJxRw=
github.com/leaanthony/slicer v1.3.1/go.mod h1:VMB/HGvr3uR3MRpFWHWAm0w+DHQLzPHYe2pKfpFlQIQ=
github.com/leaanthony/spinner v0.5.0 h1:HQykt/iTy7fmINEREtRbWrt+8j4MxC8dtvWBxEWM9oA=
github.com/leaanthony/spinner v0.5.0/go.mod h1:8TSFz9SL1AUC4XSbEFYE6SfN5Mlus51qYluVGrie9ww=
github.com/leaanthony/mewn v0.10.7 h1:jCcNJyIUOpwj+I5SuATvCugDjHkoo+j6ubEOxxrxmPA=
github.com/leaanthony/mewn v0.10.7/go.mod h1:CRkTx8unLiSSilu/Sd7i1LwrdaAL+3eQ3ses99qGMEQ=
github.com/leaanthony/slicer v1.3.2 h1:kGWWFoyaY5WzwGrUsHXMmGbssuYthP4qYBNlkNpNAB8=
github.com/leaanthony/slicer v1.3.2/go.mod h1:VMB/HGvr3uR3MRpFWHWAm0w+DHQLzPHYe2pKfpFlQIQ=
github.com/leaanthony/spinner v0.5.3 h1:IMTvgdQCec5QA4qRy0wil4XsRP+QcG1OwLWVK/LPZ5Y=
github.com/leaanthony/spinner v0.5.3/go.mod h1:oHlrvWicr++CVV7ALWYi+qHk/XNA91D9IJ48IqmpVUo=
github.com/leaanthony/synx v0.1.0 h1:R0lmg2w6VMb8XcotOwAe5DLyzwjLrskNkwU7LLWsyL8=
github.com/leaanthony/synx v0.1.0/go.mod h1:Iz7eybeeG8bdq640iR+CwYb8p+9EOsgMWghkSRyZcqs=
github.com/leaanthony/wincursor v0.1.0 h1:Dsyp68QcF5cCs65AMBmxoYNEm0n8K7mMchG6a8fYxf8=
@@ -55,21 +53,18 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/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/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/ribice/glice v0.0.0-20181011133736-685f13fa9b12/go.mod h1:A+ednilkKNW0CJGLsrLkq0D49M4EhlCi8gvnkwoZFn0=
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=
@@ -86,12 +81,9 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90Pveol
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3 h1:eH6Eip3UpmR+yM/qI9Ijluzb1bNv/cAU/n+6l8tRSis=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak=
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb h1:pf3XwC90UUdNPYWZdFjhGBE7DUFuK3Ct1zWmZ65QN30=

View File

@@ -12,10 +12,6 @@ type Renderer interface {
// Events
NotifyEvent(eventData *eventData) error
// Injection
AddJSList(js []string)
AddCSSList(css []string)
// Dialog Runtime
SelectFile() string
SelectDirectory() string

View File

@@ -37,10 +37,6 @@ type Headless struct {
appConfig *AppConfig
eventManager *eventManager
bindingCache []string
frameworkJS string
frameworkCSS string
jsCache []string
cssCache []string
// Headless specific
initialisationJS []string
@@ -190,18 +186,6 @@ func (h *Headless) SelectSaveFile() string {
return ""
}
// AddJSList adds a slice of JS strings to the list of js
// files injected at startup
func (h *Headless) AddJSList(jsCache []string) {
h.jsCache = jsCache
}
// AddCSSList adds a slice of CSS strings to the list of css
// files injected at startup
func (h *Headless) AddCSSList(cssCache []string) {
h.cssCache = cssCache
}
// Callback sends a callback to the frontend
func (h *Headless) Callback(data string) error {
return h.evalJS(data, callbackMessage)

View File

@@ -21,13 +21,6 @@ type webViewRenderer struct {
config *AppConfig
eventManager *eventManager
bindingCache []string
frameworkJS string
frameworkCSS string
// This is a list of all the JS/CSS that needs injecting
// It will get injected in order
jsCache []string
cssCache []string
}
// Initialise sets up the WebView
@@ -175,13 +168,13 @@ func (w *webViewRenderer) Run() error {
w.evalJSSync(binding)
}
// Inject Framework
if w.frameworkJS != "" {
w.evalJSSync(w.frameworkJS)
}
if w.frameworkCSS != "" {
w.injectCSS(w.frameworkCSS)
}
// // Inject Framework
// if w.frameworkJS != "" {
// w.evalJSSync(w.frameworkJS)
// }
// if w.frameworkCSS != "" {
// w.injectCSS(w.frameworkCSS)
// }
// Inject user CSS
if w.config.CSS != "" {
@@ -199,16 +192,6 @@ func (w *webViewRenderer) Run() error {
w.injectCSS(defaultCSS)
}
// Inject all the CSS files that have been added
for _, css := range w.cssCache {
w.injectCSS(css)
}
// Inject all the JS files that have been added
for _, js := range w.jsCache {
w.evalJSSync(js)
}
// Inject user JS
if w.config.JS != "" {
outputJS := fmt.Sprintf("%.45s", w.config.JS)
@@ -289,17 +272,6 @@ func (w *webViewRenderer) SelectSaveFile() string {
return result
}
// AddJS adds a piece of Javascript to a cache that
// gets injected at runtime
func (w *webViewRenderer) AddJSList(jsCache []string) {
w.jsCache = jsCache
}
// AddCSSList sets the cssCache to the given list of strings
func (w *webViewRenderer) AddCSSList(cssCache []string) {
w.cssCache = cssCache
}
// Callback sends a callback to the frontend
func (w *webViewRenderer) Callback(data string) error {
callbackCMD := fmt.Sprintf("window.wails._.callback('%s');", data)

View File

@@ -6,6 +6,7 @@ type Runtime struct {
Log *RuntimeLog
Dialog *RuntimeDialog
Window *RuntimeWindow
Browser *RuntimeBrowser
FileSystem *RuntimeFileSystem
}
@@ -15,6 +16,7 @@ func newRuntime(eventManager *eventManager, renderer Renderer) *Runtime {
Log: newRuntimeLog(),
Dialog: newRuntimeDialog(renderer),
Window: newRuntimeWindow(renderer),
Browser: newRuntimeBrowser(),
FileSystem: newRuntimeFileSystem(),
}
}

25
runtime_browser.go Normal file
View File

@@ -0,0 +1,25 @@
package wails
import "github.com/pkg/browser"
// GlobalRuntimeBrowser is the global instance of the RuntimeBrowser object
// Why? Because we need to use it in both the runtime and from the frontend
var GlobalRuntimeBrowser = newRuntimeBrowser()
// RuntimeBrowser exposes browser methods to the runtime
type RuntimeBrowser struct {
}
func newRuntimeBrowser() *RuntimeBrowser {
return &RuntimeBrowser{}
}
// OpenURL opens the given url in the system's default browser
func (r *RuntimeBrowser) OpenURL(url string) error {
return browser.OpenURL(url)
}
// OpenFile opens the given file in the system's default browser
func (r *RuntimeBrowser) OpenFile(filePath string) error {
return browser.OpenFile(filePath)
}

File diff suppressed because one or more lines are too long

View File

@@ -18,197 +18,199 @@
// Bridge object
window.wailsbridge = {
reconnectOverlay: null,
reconnectTimer: 300,
wsURL: "ws://localhost:34115/bridge",
connectionState: null,
config: {},
websocket: null,
callback: null,
overlayHTML:
reconnectOverlay: null,
reconnectTimer: 300,
wsURL: 'ws://localhost:34115/bridge',
connectionState: null,
config: {},
websocket: null,
callback: null,
overlayHTML:
'<div class="wails-reconnect-overlay"><div class="wails-reconnect-overlay-content"><div class="wails-reconnect-overlay-title">Wails Bridge</div><br><div class="wails-reconnect-overlay-loadingspinner"></div><br><div id="wails-reconnect-overlay-message">Waiting for backend</div></div></div>',
overlayCSS:
".wails-reconnect-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.6);font-family:sans-serif;display:none;z-index:999999}.wails-reconnect-overlay-content{padding:20px 30px;text-align:center;width:20em;position:relative;height:14em;border-radius:1em;margin:5% auto 0;background-color:#fff;box-shadow:1px 1px 20px 3px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC8AAAAuCAMAAACPpbA7AAAAqFBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAAAAAAAAEBAQAAAAAAAAAAAAEBAQEBAQDAwMBAQEAAAABAQEAAAAAAAAAAAABAQEAAAAAAAACAgICAgIBAQEAAAAAAAAAAAAAAAAAAAAAAAABAQEAAAACAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQWKCj6oAAAAN3RSTlMALiIqDhkGBAswJjP0GxP6NR4W9/ztjRDMhWU50G9g5eHXvbZ9XEI9xZTcqZl2aldKo55QwoCvZUgzhAAAAs9JREFUSMeNleeWqjAUhU0BCaH3Itiw9zKT93+zG02QK1hm/5HF+jzZJ6fQe6cyXE+jg9X7o9wxuylIIf4Tv2V3+bOrEXnf8dwQ/KQIGDN2/S+4OmVCVXL/ScBnfibxURqIByP/hONE8r8T+bDMlQ98KSl7Y8hzjpS8v1qtDh8u5f8KQpGpfnPPhqG8JeogN37Hq9eaN2xRhIwAaGnvws8F1ShxqK5ob2twYi1FAMD4rXsYtnC/JEiRbl4cUrCWhnMCLRFemXezXbb59QK4WASOsm6n2W1+4CBT2JmtzQ6fsrbGubR/NFbd2g5Y179+5w/GEHaKsHjYCet7CgrXU3txarNC7YxOVJtIj4/ERzMdZfzc31hp+8cD6eGILgarZY9uZ12hAs03vfBD9C171gS5Omz7OcvxALQIn4u8RRBBBcsi9WW2woO9ipLgfzpYlggg3ZRdROUC8KT7QLqq3W9KB5BbdFVg4929kdwp6+qaZnMCCNBdj+NyN1W885Ry/AL3D4AQbsVV4noCiM/C83kyYq80XlDAYQtralOiDzoRAHlotWl8q2tjvYlOgcg1A8jEApZa+C06TBdAz2Qv0wu11I/zZOyJQ6EwGez2P2b8PIQr1hwwnAZsAxwA4UAYOyXUxM/xp6tHAn4GUmPGM9R28oVxgC0e/zQJJI6DyhyZ1r7uzRQhpcW7x7vTaWSzKSG6aep77kroTEl3U81uSVaUTtgEINfC8epx+Q4F9SpplHG84Ek6m4RAq9/TLkOBrxyeuddZhHvGIp1XXfFy3Z3vtwNblKGiDn+J+92vwwABHghj7HnzlS1H5kB49AZvdGCFgiBPq69qfXPr3y++yilF0ON4R8eR7spAsLpZ95NqAW5tab1c4vkZm6aleajchMwYTdILQQTwE2OV411ZM9WztDjPql12caBi6gDpUKmDd4U1XNdQxZ4LIXQ5/Tr4P7I9tYcFrDK3AAAAAElFTkSuQmCC);background-repeat:no-repeat;background-position:center}.wails-reconnect-overlay-title{font-size:2em}.wails-reconnect-overlay-message{font-size:1.3em}.wails-reconnect-overlay-loadingspinner{pointer-events:none;width:2.5em;height:2.5em;border:.4em solid transparent;border-color:#3E67EC #eee #eee;border-radius:50%;animation:loadingspin 1s linear infinite;margin:auto;padding:2.5em}@keyframes loadingspin{100%{transform:rotate(360deg)}}",
log: function (message) {
// eslint-disable-next-line
overlayCSS:
'.wails-reconnect-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.6);font-family:sans-serif;display:none;z-index:999999}.wails-reconnect-overlay-content{padding:20px 30px;text-align:center;width:20em;position:relative;height:14em;border-radius:1em;margin:5% auto 0;background-color:#fff;box-shadow:1px 1px 20px 3px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC8AAAAuCAMAAACPpbA7AAAAqFBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAAAAAAAAEBAQAAAAAAAAAAAAEBAQEBAQDAwMBAQEAAAABAQEAAAAAAAAAAAABAQEAAAAAAAACAgICAgIBAQEAAAAAAAAAAAAAAAAAAAAAAAABAQEAAAACAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQWKCj6oAAAAN3RSTlMALiIqDhkGBAswJjP0GxP6NR4W9/ztjRDMhWU50G9g5eHXvbZ9XEI9xZTcqZl2aldKo55QwoCvZUgzhAAAAs9JREFUSMeNleeWqjAUhU0BCaH3Itiw9zKT93+zG02QK1hm/5HF+jzZJ6fQe6cyXE+jg9X7o9wxuylIIf4Tv2V3+bOrEXnf8dwQ/KQIGDN2/S+4OmVCVXL/ScBnfibxURqIByP/hONE8r8T+bDMlQ98KSl7Y8hzjpS8v1qtDh8u5f8KQpGpfnPPhqG8JeogN37Hq9eaN2xRhIwAaGnvws8F1ShxqK5ob2twYi1FAMD4rXsYtnC/JEiRbl4cUrCWhnMCLRFemXezXbb59QK4WASOsm6n2W1+4CBT2JmtzQ6fsrbGubR/NFbd2g5Y179+5w/GEHaKsHjYCet7CgrXU3txarNC7YxOVJtIj4/ERzMdZfzc31hp+8cD6eGILgarZY9uZ12hAs03vfBD9C171gS5Omz7OcvxALQIn4u8RRBBBcsi9WW2woO9ipLgfzpYlggg3ZRdROUC8KT7QLqq3W9KB5BbdFVg4929kdwp6+qaZnMCCNBdj+NyN1W885Ry/AL3D4AQbsVV4noCiM/C83kyYq80XlDAYQtralOiDzoRAHlotWl8q2tjvYlOgcg1A8jEApZa+C06TBdAz2Qv0wu11I/zZOyJQ6EwGez2P2b8PIQr1hwwnAZsAxwA4UAYOyXUxM/xp6tHAn4GUmPGM9R28oVxgC0e/zQJJI6DyhyZ1r7uzRQhpcW7x7vTaWSzKSG6aep77kroTEl3U81uSVaUTtgEINfC8epx+Q4F9SpplHG84Ek6m4RAq9/TLkOBrxyeuddZhHvGIp1XXfFy3Z3vtwNblKGiDn+J+92vwwABHghj7HnzlS1H5kB49AZvdGCFgiBPq69qfXPr3y++yilF0ON4R8eR7spAsLpZ95NqAW5tab1c4vkZm6aleajchMwYTdILQQTwE2OV411ZM9WztDjPql12caBi6gDpUKmDd4U1XNdQxZ4LIXQ5/Tr4P7I9tYcFrDK3AAAAAElFTkSuQmCC);background-repeat:no-repeat;background-position:center}.wails-reconnect-overlay-title{font-size:2em}.wails-reconnect-overlay-message{font-size:1.3em}.wails-reconnect-overlay-loadingspinner{pointer-events:none;width:2.5em;height:2.5em;border:.4em solid transparent;border-color:#3E67EC #eee #eee;border-radius:50%;animation:loadingspin 1s linear infinite;margin:auto;padding:2.5em}@keyframes loadingspin{100%{transform:rotate(360deg)}}',
log: function (message) {
// eslint-disable-next-line
console.log(
"%c wails bridge %c " + message + " ",
"background: #aa0000; color: #fff; border-radius: 3px 0px 0px 3px; padding: 1px; font-size: 0.7rem",
"background: #009900; color: #fff; border-radius: 0px 3px 3px 0px; padding: 1px; font-size: 0.7rem"
);
}
'%c wails bridge %c ' + message + ' ',
'background: #aa0000; color: #fff; border-radius: 3px 0px 0px 3px; padding: 1px; font-size: 0.7rem',
'background: #009900; color: #fff; border-radius: 0px 3px 3px 0px; padding: 1px; font-size: 0.7rem'
);
}
};
// Adapted from webview - thanks zserge!
function injectCSS(css) {
var elem = document.createElement("style");
elem.setAttribute("type", "text/css");
if (elem.styleSheet) {
elem.styleSheet.cssText = css;
} else {
elem.appendChild(document.createTextNode(css));
}
var head = document.head || document.getElementsByTagName("head")[0];
head.appendChild(elem);
var elem = document.createElement('style');
elem.setAttribute('type', 'text/css');
if (elem.styleSheet) {
elem.styleSheet.cssText = css;
} else {
elem.appendChild(document.createTextNode(css));
}
var head = document.head || document.getElementsByTagName('head')[0];
head.appendChild(elem);
}
// Creates a node in the Dom
function createNode(parent, elementType, id, className, content) {
var d = document.createElement(elementType);
if (id) {
d.id = id;
}
if (className) {
d.className = className;
}
if (content) {
d.innerHTML = content;
}
parent.appendChild(d);
return d;
var d = document.createElement(elementType);
if (id) {
d.id = id;
}
if (className) {
d.className = className;
}
if (content) {
d.innerHTML = content;
}
parent.appendChild(d);
return d;
}
// Sets up the overlay
function setupOverlay() {
var body = document.body;
var wailsBridgeNode = createNode(body, "div", "wails-bridge");
wailsBridgeNode.innerHTML = window.wailsbridge.overlayHTML;
var body = document.body;
var wailsBridgeNode = createNode(body, 'div', 'wails-bridge');
wailsBridgeNode.innerHTML = window.wailsbridge.overlayHTML;
// Inject the overlay CSS
injectCSS(window.wailsbridge.overlayCSS);
// Inject the overlay CSS
injectCSS(window.wailsbridge.overlayCSS);
}
// Start the Wails Bridge
function startBridge() {
// Setup the overlay
setupOverlay();
// Setup the overlay
setupOverlay();
window.wailsbridge.websocket = null;
window.wailsbridge.connectTimer = null;
window.wailsbridge.reconnectOverlay = document.querySelector(
".wails-reconnect-overlay"
);
window.wailsbridge.connectionState = "disconnected";
window.wailsbridge.websocket = null;
window.wailsbridge.connectTimer = null;
window.wailsbridge.reconnectOverlay = document.querySelector(
'.wails-reconnect-overlay'
);
window.wailsbridge.connectionState = 'disconnected';
// Shows the overlay
function showReconnectOverlay() {
window.wailsbridge.reconnectOverlay.style.display = "block";
}
// Shows the overlay
function showReconnectOverlay() {
window.wailsbridge.reconnectOverlay.style.display = 'block';
}
// Hides the overlay
function hideReconnectOverlay() {
window.wailsbridge.reconnectOverlay.style.display = "none";
}
// Hides the overlay
function hideReconnectOverlay() {
window.wailsbridge.reconnectOverlay.style.display = 'none';
}
// Bridge external.invoke
window.external = {
invoke: function (msg) {
window.wailsbridge.websocket.send(msg);
}
};
// Bridge external.invoke
window.external = {
invoke: function (msg) {
window.wailsbridge.websocket.send(msg);
}
};
// Adds a script to the Dom.
// Removes it if second parameter is true.
function addScript(script, remove) {
var s = document.createElement("script");
s.setAttribute('type', 'text/javascript');
s.textContent = script;
document.head.appendChild(s);
// Adds a script to the Dom.
// Removes it if second parameter is true.
function addScript(script, remove) {
var s = document.createElement('script');
s.setAttribute('type', 'text/javascript');
s.textContent = script;
document.head.appendChild(s);
// Remove internal messages from the DOM
if (remove) {
s.parentNode.removeChild(s);
}
}
// Remove internal messages from the DOM
if (remove) {
s.parentNode.removeChild(s);
}
}
// Handles incoming websocket connections
function handleConnect() {
window.wailsbridge.log("Connected to backend");
hideReconnectOverlay();
clearInterval(window.wailsbridge.connectTimer);
window.wailsbridge.websocket.onclose = handleDisconnect;
window.wailsbridge.websocket.onmessage = handleMessage;
window.wailsbridge.connectionState = "connected";
}
// Handles incoming websocket connections
function handleConnect() {
window.wailsbridge.log('Connected to backend');
hideReconnectOverlay();
clearInterval(window.wailsbridge.connectTimer);
window.wailsbridge.websocket.onclose = handleDisconnect;
window.wailsbridge.websocket.onmessage = handleMessage;
window.wailsbridge.connectionState = 'connected';
}
// Handles websocket disconnects
function handleDisconnect() {
window.wailsbridge.log("Disconnected from backend");
window.wailsbridge.websocket = null;
window.wailsbridge.connectionState = "disconnected";
showReconnectOverlay();
connect();
}
// Handles websocket disconnects
function handleDisconnect() {
window.wailsbridge.log('Disconnected from backend');
window.wailsbridge.websocket = null;
window.wailsbridge.connectionState = 'disconnected';
showReconnectOverlay();
connect();
}
// Try to connect to the backend every 300ms (default value).
// Change this value in the main wailsbridge object.
function connect() {
window.wailsbridge.connectTimer = setInterval(function () {
if (window.wailsbridge.websocket == null) {
window.wailsbridge.websocket = new WebSocket(window.wailsbridge.wsURL);
window.wailsbridge.websocket.onopen = handleConnect;
window.wailsbridge.websocket.onerror = function (e) {
e.stopImmediatePropagation();
e.stopPropagation();
e.preventDefault();
window.wailsbridge.websocket = null;
return false;
};
}
}, window.wailsbridge.reconnectTimer);
}
// Try to connect to the backend every 300ms (default value).
// Change this value in the main wailsbridge object.
function connect() {
window.wailsbridge.connectTimer = setInterval(function () {
if (window.wailsbridge.websocket == null) {
window.wailsbridge.websocket = new WebSocket(window.wailsbridge.wsURL);
window.wailsbridge.websocket.onopen = handleConnect;
window.wailsbridge.websocket.onerror = function (e) {
e.stopImmediatePropagation();
e.stopPropagation();
e.preventDefault();
window.wailsbridge.websocket = null;
return false;
};
}
}, window.wailsbridge.reconnectTimer);
}
function handleMessage(message) {
// As a bridge we ignore js and css injections
switch (message.data[0]) {
// Wails library - inject!
case "w":
addScript(message.data.slice(1));
function handleMessage(message) {
// As a bridge we ignore js and css injections
switch (message.data[0]) {
// Wails library - inject!
case 'w':
addScript(message.data.slice(1));
// Now wails runtime is loaded, wails for the ready event
// and callback to the main app
window.wails.events.on("wails:loaded", function () {
window.wailsbridge.log("Wails Ready");
if (window.wailsbridge.callback) {
window.wailsbridge.log("Notifying application");
window.wailsbridge.callback(window.wails);
}
});
window.wailsbridge.log("Loaded Wails Runtime");
break;
// Notifications
case "n":
addScript(message.data.slice(1), true);
break;
// Binding
case "b":
var binding = message.data.slice(1);
//log("Binding: " + binding)
window.wails._.newBinding(binding);
break;
// Call back
case "c":
var callbackData = message.data.slice(1);
window.wails._.callback(callbackData);
break;
}
}
// Now wails runtime is loaded, wails for the ready event
// and callback to the main app
window.wails.Events.On('wails:loaded', function () {
window.wailsbridge.log('Wails Ready');
if (window.wailsbridge.callback) {
window.wailsbridge.log('Notifying application');
window.wailsbridge.callback(window.wails);
}
});
window.wailsbridge.log('Loaded Wails Runtime');
break;
// Notifications
case 'n':
addScript(message.data.slice(1), true);
break;
// Binding
case 'b':
var binding = message.data.slice(1);
//log("Binding: " + binding)
window.wails._.newBinding(binding);
break;
// Call back
case 'c':
var callbackData = message.data.slice(1);
window.wails._.callback(callbackData);
break;
default:
window.wails.Log.Error('Unknown message type received: ' + message.data[0]);
}
}
// Start by showing the overlay...
showReconnectOverlay();
// Start by showing the overlay...
showReconnectOverlay();
// ...and attempt to connect
connect();
// ...and attempt to connect
connect();
}
export default {
// The main function
// Passes the main Wails object to the callback if given.
Start: function (callback) {
// Save the callback
window.wailsbridge.callback = callback;
// The main function
// Passes the main Wails object to the callback if given.
Start: function (callback) {
// Save the callback
window.wailsbridge.callback = callback;
// Start Bridge
startBridge();
}
// Start Bridge
startBridge();
}
};

View File

@@ -7,11 +7,11 @@
*/
export default {
// The main function
// Passes the main Wails object to the callback if given.
Start: function(callback) {
if (callback) {
window.wails.events.on("wails:ready", callback);
}
}
// The main function
// Passes the main Wails object to the callback if given.
Start: function (callback) {
if (callback) {
window.wails.Events.On('wails:ready', callback);
}
}
};

Some files were not shown because too many files have changed in this diff Show More