Compare commits

..

2 Commits

Author SHA1 Message Date
Lea Anthony
f63df796fd Merge pull request #90 from fishfishfish2104/v0.14.0-pre
Fixed Manjaro not being detected as arch
2019-05-17 12:46:57 +10:00
fred2104
cd370f0a39 Fixed Manjaro not being detected as arch 2019-05-17 13:40:34 +12:00
181 changed files with 12727 additions and 12269 deletions

42
.chglog/CHANGELOG.tpl.md Executable file
View File

@@ -0,0 +1,42 @@
{{ if .Versions -}}
<a name="unreleased"></a>
## [Unreleased]
{{ if .Unreleased.CommitGroups -}}
{{ range .Unreleased.CommitGroups -}}
### {{ .Title }}
{{ range .Commits -}}
- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
{{ end }}
{{ end -}}
{{ end -}}
{{ end -}}
{{ range .Versions }}
<a name="{{ .Tag.Name }}"></a>
## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }}
{{ range .CommitGroups -}}
### {{ .Title }}
{{ range .Commits -}}
- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
{{ end }}
{{ end -}}
{{- if .NoteGroups -}}
{{ range .NoteGroups -}}
### {{ .Title }}
{{ range .Notes }}
{{ .Body }}
{{ end }}
{{ end -}}
{{ end -}}
{{ end -}}
{{- if .Versions }}
[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD
{{ range .Versions -}}
{{ if .Tag.Previous -}}
[{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}
{{ end -}}
{{ end -}}
{{ end -}}

27
.chglog/config.yml Executable file
View File

@@ -0,0 +1,27 @@
style: github
template: CHANGELOG.tpl.md
info:
title: CHANGELOG
repository_url: https://github.com/wailsapp/wails
options:
commits:
# filters:
# Type:
# - feat
# - fix
# - perf
# - refactor
commit_groups:
# title_maps:
# feat: Features
# fix: Bug Fixes
# perf: Performance Improvements
# refactor: Code Refactoring
header:
pattern: "^(\\w*)\\:\\s(.*)$"
pattern_maps:
- Type
- Subject
notes:
keywords:
- BREAKING CHANGE

View File

@@ -1 +0,0 @@
runtime/assets/default.html

View File

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

2
.gitignore vendored
View File

@@ -16,4 +16,4 @@ examples/**/example*
cmd/wails/wails cmd/wails/wails
.DS_Store .DS_Store
tmp tmp
node_modules/ dist

View File

@@ -1,6 +0,0 @@
jshint:
config_file: .jshintrc
eslint:
enabled: true
config_file: .eslintrc
ignore_file: .eslintignore

View File

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

23
.vscode/launch.json vendored
View File

@@ -5,33 +5,12 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "Wails Init", "name": "Launch",
"type": "go", "type": "go",
"request": "launch", "request": "launch",
"mode": "auto", "mode": "auto",
"program": "${workspaceFolder}/cmd/wails/main.go", "program": "${workspaceFolder}/cmd/wails/main.go",
"env": {}, "env": {},
"cwd": "/tmp",
"args": [
"init",
"-name",
"runtime",
"-dir",
"runtime",
"-output",
"runtime",
"-template",
"vuebasic"
]
},
{
"name": "Wails Update Pre",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/wails/main.go",
"env": {},
"cwd": "/tmp",
"args": [ "args": [
"update", "update",
"-pre" "-pre"

View File

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

View File

@@ -1,28 +1,19 @@
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
2019-05-29 **v0.14.11-pre** <a name="v0.13.0"></a>
* Windows fix for spinner ## [v0.13.0] - 2019-05-12
2019-05-29 **v0.14.10-pre** ### Feat
* Windows fix for Vuetify - revamped 'update' system
- no need for explicit GO111MODULE=on
2019-05-29 **v0.14.9-pre** ### Fix
* Vuetify project template 🎉 - documentation typo fixes
- windows init project
- windows 10 colour
- leave windows assets on -p flag
- show prerequisite errors
2019-05-29 **v0.14.8-pre** ### Docs
* Updated Ubuntu npm install command - updated contributors
- added awesomego logo
2019-05-22 **v0.14.7-pre** - added Redhat distro
* 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,10 +8,5 @@ Wails is what it is because of the time and effort given by these great people.
* [Adrian Lanzafame](https://github.com/lanzafame) * [Adrian Lanzafame](https://github.com/lanzafame)
* [0xflotus](https://github.com/0xflotus) * [0xflotus](https://github.com/0xflotus)
* [Michael D Henderson](https://github.com/mdhender) * [Michael D Henderson](https://github.com/mdhender)
* [fred2104](https://github.com/fishfishfish2104) * [fred2104] (https://github.com/fishfishfish2104)
* [intelwalk](https://github.com/intelwalk) * [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)
* [fallendusk](https://github.com/fallendusk)
* [Florian Didran](https://github.com/fdidron)

View File

@@ -9,8 +9,7 @@
<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://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://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://houndci.com"><img src="https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg"/></a>
<a href="https://github.com/avelino/awesome-go" rel="nofollow"><img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome"></a> <a href="https://github.com/sindresorhus/awesome" 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> </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! 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!
@@ -19,7 +18,6 @@ The traditional method of providing web interfaces to Go programs is via a built
- Use standard Go libraries/frameworks for the backend - Use standard Go libraries/frameworks for the backend
- Use any frontend technology to build your UI - 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 - Expose Go methods/functions to the frontend via a single bind command
- Uses native rendering engines - no embedded browser - Uses native rendering engines - no embedded browser
- Shared events system - Shared events system
@@ -35,7 +33,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: 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.12 - Go 1.11 or above
- npm - npm
### MacOS ### MacOS
@@ -46,7 +44,7 @@ Make sure you have the xcode command line tools installed. This can be done by r
### Linux ### Linux
#### Ubuntu 18.04, Debian 9, Zorin 15 #### Ubuntu 18.04
`sudo apt install pkg-config build-essential libgtk-3-dev libwebkit2gtk-4.0-dev` `sudo apt install pkg-config build-essential libgtk-3-dev libwebkit2gtk-4.0-dev`
@@ -66,8 +64,6 @@ Windows requires gcc and related tooling. The recommended download is from [http
## Installation ## 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: Installation is as simple as running the following command:
<pre style='color:white'> <pre style='color:white'>
@@ -99,7 +95,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!). * [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. * [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. A huge thank you to each and every one of you! And without [these people](CONTRIBUTORS.md), it wouldn't be what it is today.
Special Mentions: Special Mentions:

75
app.go
View File

@@ -2,12 +2,6 @@ package wails
import ( import (
"github.com/wailsapp/wails/cmd" "github.com/wailsapp/wails/cmd"
"github.com/wailsapp/wails/lib/binding"
"github.com/wailsapp/wails/lib/event"
"github.com/wailsapp/wails/lib/interfaces"
"github.com/wailsapp/wails/lib/ipc"
"github.com/wailsapp/wails/lib/logger"
"github.com/wailsapp/wails/lib/renderer"
) )
// -------------------------------- Compile time Flags ------------------------------ // -------------------------------- Compile time Flags ------------------------------
@@ -19,15 +13,20 @@ var BuildMode = cmd.BuildModeProd
// App defines the main application struct // App defines the main application struct
type App struct { type App struct {
config *AppConfig // The Application configuration object config *AppConfig // The Application configuration object
cli *cmd.Cli // In debug mode, we have a cli cli *cmd.Cli // In debug mode, we have a cli
renderer interfaces.Renderer // The renderer is what we will render the app to renderer Renderer // The renderer is what we will render the app to
logLevel string // The log level of the app logLevel string // The log level of the app
ipc interfaces.IPCManager // Handles the IPC calls ipc *ipcManager // Handles the IPC calls
log *logger.CustomLogger // Logger log *CustomLogger // Logger
bindingManager interfaces.BindingManager // Handles binding of Go code to renderer bindingManager *bindingManager // Handles binding of Go code to renderer
eventManager interfaces.EventManager // Handles all the events eventManager *eventManager // Handles all the events
runtime interfaces.Runtime // The runtime object for registered structs 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 // CreateApp creates the application window with the given configuration
@@ -40,14 +39,14 @@ func CreateApp(optionalConfig ...*AppConfig) *App {
result := &App{ result := &App{
logLevel: "info", logLevel: "info",
renderer: renderer.NewWebView(), renderer: &webViewRenderer{},
ipc: ipc.NewManager(), ipc: newIPCManager(),
bindingManager: binding.NewManager(), bindingManager: newBindingManager(),
eventManager: event.NewManager(), eventManager: newEventManager(),
log: logger.NewCustomLogger("App"), log: newCustomLogger("App"),
} }
appconfig, err := newConfig(userConfig) appconfig, err := newAppConfig(userConfig)
if err != nil { if err != nil {
result.log.Fatalf("Cannot use custom HTML: %s", err.Error()) result.log.Fatalf("Cannot use custom HTML: %s", err.Error())
} }
@@ -81,14 +80,14 @@ func (a *App) Run() error {
func (a *App) start() error { func (a *App) start() error {
// Set the log level // Set the log level
logger.SetLogLevel(a.logLevel) setLogLevel(a.logLevel)
// Log starup // Log starup
a.log.Info("Starting") a.log.Info("Starting")
// Check if we are to run in bridge mode // Check if we are to run in headless mode
if BuildMode == cmd.BuildModeBridge { if BuildMode == cmd.BuildModeBridge {
a.renderer = &renderer.Bridge{} a.renderer = &Headless{}
} }
// Initialise the renderer // Initialise the renderer
@@ -98,20 +97,26 @@ func (a *App) start() error {
} }
// Start event manager and give it our renderer // Start event manager and give it our renderer
a.eventManager.Start(a.renderer) a.eventManager.start(a.renderer)
// Start the IPC Manager and give it the event manager and binding manager // Start the IPC Manager and give it the event manager and binding manager
a.ipc.Start(a.eventManager, a.bindingManager) a.ipc.start(a.eventManager, a.bindingManager)
// Create the runtime // Create the runtime
a.runtime = NewRuntime(a.eventManager, a.renderer) a.runtime = newRuntime(a.eventManager, a.renderer)
// Start binding manager and give it our renderer // Start binding manager and give it our renderer
err = a.bindingManager.Start(a.renderer, a.runtime) err = a.bindingManager.start(a.renderer, a.runtime)
if err != nil { if err != nil {
return err return err
} }
// Inject CSS
a.renderer.AddCSSList(a.cssCache)
// Inject JS
a.renderer.AddJSList(a.jsCache)
// Run the renderer // Run the renderer
return a.renderer.Run() return a.renderer.Run()
} }
@@ -119,5 +124,17 @@ func (a *App) start() error {
// Bind allows the user to bind the given object // Bind allows the user to bind the given object
// with the application // with the application
func (a *App) Bind(object interface{}) { func (a *App) Bind(object interface{}) {
a.bindingManager.Bind(object) 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)
} }

View File

@@ -11,9 +11,10 @@ func (app *App) setupCli() *cmd.Cli {
result := cmd.NewCli(app.config.Title, "Debug build") result := cmd.NewCli(app.config.Title, "Debug build")
result.Version(cmd.Version) result.Version(cmd.Version)
// Setup cli to handle loglevel // Setup cli to handle loglevel and headless flags
result. result.
StringFlag("loglevel", "Sets the log level [debug|info|error|panic|fatal]. Default debug", &app.logLevel). StringFlag("loglevel", "Sets the log level [debug|info|error|panic|fatal]. Default debug", &app.logLevel).
// BoolFlag("headless", "Runs the app in headless mode", &app.headless).
Action(app.start) Action(app.start)
// Banner // Banner

97
app_config.go Normal file
View File

@@ -0,0 +1,97 @@
package wails
import (
"strings"
"github.com/dchest/htmlmin"
"github.com/leaanthony/mewn"
)
// AppConfig is the configuration structure used when creating a Wails App object
type AppConfig struct {
Width, Height int
Title string
defaultHTML string
HTML string
JS string
CSS string
Colour string
Resizable bool
DisableInspector bool
isHTMLFragment bool
}
func (a *AppConfig) merge(in *AppConfig) error {
if in.CSS != "" {
a.CSS = in.CSS
}
if in.Title != "" {
a.Title = in.Title
}
if in.HTML != "" {
minified, err := htmlmin.Minify([]byte(in.HTML), &htmlmin.Options{
MinifyScripts: true,
})
if err != nil {
return err
}
inlineHTML := string(minified)
inlineHTML = strings.Replace(inlineHTML, "'", "\\'", -1)
inlineHTML = strings.Replace(inlineHTML, "\n", " ", -1)
a.HTML = strings.TrimSpace(inlineHTML)
// Deduce whether this is a full html page or a fragment
// The document is determined to be a fragment if an HTML
// tag exists and is located before the first div tag
HTMLTagIndex := strings.Index(a.HTML, "<html")
DivTagIndex := strings.Index(a.HTML, "<div")
if HTMLTagIndex == -1 {
a.isHTMLFragment = true
} else {
if DivTagIndex < HTMLTagIndex {
a.isHTMLFragment = true
}
}
}
if in.Colour != "" {
a.Colour = in.Colour
}
if in.JS != "" {
a.JS = in.JS
}
if in.Width != 0 {
a.Width = in.Width
}
if in.Height != 0 {
a.Height = in.Height
}
a.Resizable = in.Resizable
a.DisableInspector = in.DisableInspector
return nil
}
// Creates the default configuration
func newAppConfig(userConfig *AppConfig) (*AppConfig, error) {
result := &AppConfig{
Width: 800,
Height: 600,
Resizable: true,
Title: "My Wails App",
Colour: "#FFF", // White by default
HTML: mewn.String("./wailsruntimeassets/default/default.html"),
}
if userConfig != nil {
err := result.merge(userConfig)
if err != nil {
return nil, err
}
}
return result, nil
}

View File

@@ -1,4 +1,4 @@
package binding package wails
import ( import (
"bytes" "bytes"
@@ -6,8 +6,6 @@ import (
"fmt" "fmt"
"reflect" "reflect"
"runtime" "runtime"
"github.com/wailsapp/wails/lib/logger"
) )
type boundFunction struct { type boundFunction struct {
@@ -16,7 +14,7 @@ type boundFunction struct {
functionType reflect.Type functionType reflect.Type
inputs []reflect.Type inputs []reflect.Type
returnTypes []reflect.Type returnTypes []reflect.Type
log *logger.CustomLogger log *CustomLogger
hasErrorReturnType bool hasErrorReturnType bool
} }
@@ -32,7 +30,7 @@ func newBoundFunction(object interface{}) (*boundFunction, error) {
fullName: name, fullName: name,
function: objectValue, function: objectValue,
functionType: objectType, functionType: objectType,
log: logger.NewCustomLogger(name), log: newCustomLogger(name),
} }
err := result.processParameters() err := result.processParameters()
@@ -57,7 +55,7 @@ func (b *boundFunction) processParameters() error {
b.inputs[index] = param b.inputs[index] = param
typ := param typ := param
index := index index := index
b.log.DebugFields("Input param", logger.Fields{ b.log.DebugFields("Input param", Fields{
"index": index, "index": index,
"name": name, "name": name,
"kind": kind, "kind": kind,

View File

@@ -1,46 +1,45 @@
package binding package wails
import ( import (
"fmt" "fmt"
"reflect" "reflect"
"unicode" "unicode"
"github.com/wailsapp/wails/lib/logger"
"github.com/wailsapp/wails/lib/messages"
"github.com/wailsapp/wails/lib/interfaces"
) )
// Manager handles method binding /**
type Manager struct {
binding:
Name() // Full name (package+name)
Call(params)
**/
type bindingManager struct {
methods map[string]*boundMethod methods map[string]*boundMethod
functions map[string]*boundFunction functions map[string]*boundFunction
internalMethods *internalMethods
initMethods []*boundMethod initMethods []*boundMethod
log *logger.CustomLogger log *CustomLogger
renderer interfaces.Renderer renderer Renderer
runtime interfaces.Runtime // The runtime object to pass to bound structs runtime *Runtime // The runtime object to pass to bound structs
objectsToBind []interface{} objectsToBind []interface{}
bindPackageNames bool // Package name should be considered when binding bindPackageNames bool // Package name should be considered when binding
} }
// NewManager creates a new Manager struct func newBindingManager() *bindingManager {
func NewManager() interfaces.BindingManager { result := &bindingManager{
result := &Manager{ methods: make(map[string]*boundMethod),
methods: make(map[string]*boundMethod), functions: make(map[string]*boundFunction),
functions: make(map[string]*boundFunction), log: newCustomLogger("Bind"),
log: logger.NewCustomLogger("Bind"),
internalMethods: newInternalMethods(),
} }
return result return result
} }
// BindPackageNames sets a flag to indicate package names should be considered when binding // Sets flag to indicate package names should be considered when binding
func (b *Manager) BindPackageNames() { func (b *bindingManager) BindPackageNames() {
b.bindPackageNames = true b.bindPackageNames = true
} }
// Start the binding manager func (b *bindingManager) start(renderer Renderer, runtime *Runtime) error {
func (b *Manager) Start(renderer interfaces.Renderer, runtime interfaces.Runtime) error {
b.log.Info("Starting") b.log.Info("Starting")
b.renderer = renderer b.renderer = renderer
b.runtime = runtime b.runtime = runtime
@@ -53,7 +52,7 @@ func (b *Manager) Start(renderer interfaces.Renderer, runtime interfaces.Runtime
return err return err
} }
func (b *Manager) initialise() error { func (b *bindingManager) initialise() error {
var err error var err error
// var binding *boundMethod // var binding *boundMethod
@@ -91,7 +90,7 @@ func (b *Manager) initialise() error {
} }
// bind the given struct method // bind the given struct method
func (b *Manager) bindMethod(object interface{}) error { func (b *bindingManager) bindMethod(object interface{}) error {
objectType := reflect.TypeOf(object) objectType := reflect.TypeOf(object)
baseName := objectType.String() baseName := objectType.String()
@@ -141,7 +140,7 @@ func (b *Manager) bindMethod(object interface{}) error {
} }
// bind the given function object // bind the given function object
func (b *Manager) bindFunction(object interface{}) error { func (b *bindingManager) bindFunction(object interface{}) error {
newFunction, err := newBoundFunction(object) newFunction, err := newBoundFunction(object)
if err != nil { if err != nil {
@@ -158,18 +157,13 @@ func (b *Manager) bindFunction(object interface{}) error {
return nil return nil
} }
// Bind saves the given object to be bound at start time // Save the given object to be bound at start time
func (b *Manager) Bind(object interface{}) { func (b *bindingManager) bind(object interface{}) {
// Store binding // Store binding
b.objectsToBind = append(b.objectsToBind, object) b.objectsToBind = append(b.objectsToBind, object)
} }
func (b *Manager) processInternalCall(callData *messages.CallData) (interface{}, error) { func (b *bindingManager) processFunctionCall(callData *callData) (interface{}, error) {
// Strip prefix
return b.internalMethods.processCall(callData)
}
func (b *Manager) processFunctionCall(callData *messages.CallData) (interface{}, error) {
// Return values // Return values
var result []reflect.Value var result []reflect.Value
var err error var err error
@@ -198,7 +192,7 @@ func (b *Manager) processFunctionCall(callData *messages.CallData) (interface{},
return result[0].Interface(), nil return result[0].Interface(), nil
} }
func (b *Manager) processMethodCall(callData *messages.CallData) (interface{}, error) { func (b *bindingManager) processMethodCall(callData *callData) (interface{}, error) {
// Return values // Return values
var result []reflect.Value var result []reflect.Value
var err error var err error
@@ -232,8 +226,8 @@ func (b *Manager) processMethodCall(callData *messages.CallData) (interface{}, e
return nil, nil return nil, nil
} }
// ProcessCall processes the given call request // process an incoming call request
func (b *Manager) ProcessCall(callData *messages.CallData) (result interface{}, err error) { func (b *bindingManager) processCall(callData *callData) (result interface{}, err error) {
b.log.Debugf("Wanting to call %s", callData.BindingName) b.log.Debugf("Wanting to call %s", callData.BindingName)
// Determine if this is function call or method call by the number of // Determine if this is function call or method call by the number of
@@ -260,8 +254,6 @@ func (b *Manager) ProcessCall(callData *messages.CallData) (result interface{},
result, err = b.processFunctionCall(callData) result, err = b.processFunctionCall(callData)
case 2: case 2:
result, err = b.processMethodCall(callData) result, err = b.processMethodCall(callData)
case 3:
result, err = b.processInternalCall(callData)
default: default:
result = nil result = nil
err = fmt.Errorf("Invalid binding name '%s'", callData.BindingName) err = fmt.Errorf("Invalid binding name '%s'", callData.BindingName)
@@ -271,7 +263,7 @@ func (b *Manager) ProcessCall(callData *messages.CallData) (result interface{},
// callWailsInitMethods calls all of the WailsInit methods that were // callWailsInitMethods calls all of the WailsInit methods that were
// registered with the runtime object // registered with the runtime object
func (b *Manager) callWailsInitMethods() error { func (b *bindingManager) callWailsInitMethods() error {
// Create reflect value for runtime object // Create reflect value for runtime object
runtimeValue := reflect.ValueOf(b.runtime) runtimeValue := reflect.ValueOf(b.runtime)
params := []reflect.Value{runtimeValue} params := []reflect.Value{runtimeValue}

View File

@@ -1,12 +1,10 @@
package binding package wails
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"reflect" "reflect"
"github.com/wailsapp/wails/lib/logger"
) )
type boundMethod struct { type boundMethod struct {
@@ -15,7 +13,7 @@ type boundMethod struct {
method reflect.Value method reflect.Value
inputs []reflect.Type inputs []reflect.Type
returnTypes []reflect.Type returnTypes []reflect.Type
log *logger.CustomLogger log *CustomLogger
hasErrorReturnType bool // Indicates if there is an error return type hasErrorReturnType bool // Indicates if there is an error return type
isWailsInit bool isWailsInit bool
} }
@@ -29,7 +27,7 @@ func newBoundMethod(name string, fullName string, method reflect.Value, objectTy
} }
// Setup logger // Setup logger
result.log = logger.NewCustomLogger(result.fullName) result.log = newCustomLogger(result.fullName)
// Check if Parameters are valid // Check if Parameters are valid
err := result.processParameters() err := result.processParameters()
@@ -59,7 +57,7 @@ func (b *boundMethod) processParameters() error {
b.inputs[index] = param b.inputs[index] = param
typ := param typ := param
index := index index := index
b.log.DebugFields("Input param", logger.Fields{ b.log.DebugFields("Input param", Fields{
"index": index, "index": index,
"name": name, "name": name,
"kind": kind, "kind": kind,
@@ -168,10 +166,10 @@ func (b *boundMethod) setInputValue(index int, typ reflect.Type, val interface{}
reflect.Map, reflect.Map,
reflect.Ptr, reflect.Ptr,
reflect.Slice: reflect.Slice:
b.log.Debug("Converting nil to type") logger.Debug("Converting nil to type")
result = reflect.ValueOf(val).Convert(typ) result = reflect.ValueOf(val).Convert(typ)
default: default:
b.log.Debug("Cannot convert nil to type, returning error") logger.Debug("Cannot convert nil to type, returning error")
return reflect.Zero(typ), fmt.Errorf("Unable to use null value for parameter %d of method %s", index+1, b.fullName) return reflect.Zero(typ), fmt.Errorf("Unable to use null value for parameter %d of method %s", index+1, b.fullName)
} }
} else { } else {

View File

@@ -96,7 +96,6 @@ type Command struct {
flagCount int flagCount int
log *Logger log *Logger
helpFlag bool helpFlag bool
hidden bool
} }
// NewCommand creates a new Command // NewCommand creates a new Command
@@ -107,7 +106,6 @@ func NewCommand(name string, description string, app *Cli, parentCommandPath str
SubCommandsMap: make(map[string]*Command), SubCommandsMap: make(map[string]*Command),
App: app, App: app,
log: NewLogger(), log: NewLogger(),
hidden: false,
} }
// Set up command path // Set up command path
@@ -214,9 +212,6 @@ func (c *Command) PrintHelp() {
c.log.White("Available commands:") c.log.White("Available commands:")
fmt.Println("") fmt.Println("")
for _, subcommand := range c.SubCommands { for _, subcommand := range c.SubCommands {
if subcommand.isHidden() {
continue
}
spacer := strings.Repeat(" ", 3+c.longestSubcommand-len(subcommand.Name)) spacer := strings.Repeat(" ", 3+c.longestSubcommand-len(subcommand.Name))
isDefault := "" isDefault := ""
if subcommand.isDefaultCommand() { if subcommand.isDefaultCommand() {
@@ -242,16 +237,6 @@ func (c *Command) isDefaultCommand() bool {
return c.App.defaultCommand == c return c.App.defaultCommand == c
} }
// isHidden returns true if the command is a hidden command
func (c *Command) isHidden() bool {
return c.hidden
}
// Hidden hides the command from the Help system
func (c *Command) Hidden() {
c.hidden = true
}
// Command - Defines a subcommand // Command - Defines a subcommand
func (c *Command) Command(name, description string) *Command { func (c *Command) Command(name, description string) *Command {
result := NewCommand(name, description, c.App, c.CommandPath) result := NewCommand(name, description, c.App, c.CommandPath)

File diff suppressed because one or more lines are too long

View File

@@ -1,19 +1,13 @@
package cmd package cmd
import ( import (
"bytes"
"crypto/md5" "crypto/md5"
"encoding/json"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
"path"
"path/filepath" "path/filepath"
"runtime"
"github.com/leaanthony/slicer"
) )
// FSHelper - Wrapper struct for File System utility commands // FSHelper - Wrapper struct for File System utility commands
@@ -110,33 +104,11 @@ func (fs *FSHelper) RemoveFiles(files []string) error {
return nil return nil
} }
// Dir holds information about a directory
type Dir struct {
localPath string
fullPath string
}
// 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))
return &Dir{
localPath: dir,
fullPath: fullPath,
}, err
}
// GetSubdirs will return a list of FQPs to subdirectories in the given directory // GetSubdirs will return a list of FQPs to subdirectories in the given directory
func (d *Dir) GetSubdirs() (map[string]string, error) { func (fs *FSHelper) GetSubdirs(dir string) (map[string]string, error) {
// Read in the directory information // Read in the directory information
fileInfo, err := ioutil.ReadDir(d.fullPath) fileInfo, err := ioutil.ReadDir(dir)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -148,65 +120,25 @@ func (d *Dir) GetSubdirs() (map[string]string, error) {
// map["directoryName"] = "path/to/directoryName" // map["directoryName"] = "path/to/directoryName"
for _, file := range fileInfo { for _, file := range fileInfo {
if file.IsDir() { if file.IsDir() {
subdirs[file.Name()] = filepath.Join(d.fullPath, file.Name()) subdirs[file.Name()] = filepath.Join(dir, file.Name())
} }
} }
return subdirs, nil return subdirs, nil
} }
// GetAllFilenames returns all filename in and below this directory
func (d *Dir) GetAllFilenames() (*slicer.StringSlicer, error) {
result := slicer.String()
err := filepath.Walk(d.fullPath, func(dir string, info os.FileInfo, err error) error {
if dir == d.fullPath {
return nil
}
if err != nil {
return err
}
// Don't copy template metadata
result.Add(dir)
return nil
})
return result, err
}
// MkDir creates the given directory. // MkDir creates the given directory.
// Returns error on failure // Returns error on failure
func (fs *FSHelper) MkDir(dir string) error { func (fs *FSHelper) MkDir(dir string) error {
return os.Mkdir(dir, 0700) return os.Mkdir(dir, 0700)
} }
// SaveAsJSON saves the JSON representation of the given data to the given filename
func (fs *FSHelper) SaveAsJSON(data interface{}, filename string) error {
var buf bytes.Buffer
e := json.NewEncoder(&buf)
e.SetEscapeHTML(false)
e.SetIndent("", " ")
e.Encode(data)
err := ioutil.WriteFile(filename, buf.Bytes(), 0755)
if err != nil {
return err
}
return nil
}
// LoadAsString will attempt to load the given file and return // LoadAsString will attempt to load the given file and return
// its contents as a string // its contents as a string
func (fs *FSHelper) LoadAsString(filename string) (string, error) { func (fs *FSHelper) LoadAsString(filename string) (string, error) {
bytes, err := fs.LoadAsBytes(filename) bytes, err := ioutil.ReadFile(filename)
return string(bytes), err return string(bytes), err
} }
// LoadAsBytes returns the contents of the file as a byte slice
func (fs *FSHelper) LoadAsBytes(filename string) ([]byte, error) {
return ioutil.ReadFile(filename)
}
// FileMD5 returns the md5sum of the given file // FileMD5 returns the md5sum of the given file
func (fs *FSHelper) FileMD5(filename string) (string, error) { func (fs *FSHelper) FileMD5(filename string) (string, error) {
f, err := os.Open(filename) f, err := os.Open(filename)

View File

@@ -9,7 +9,7 @@ import (
"runtime" "runtime"
"time" "time"
"github.com/leaanthony/mewn" mewn "github.com/leaanthony/mewn"
"github.com/leaanthony/slicer" "github.com/leaanthony/slicer"
"github.com/leaanthony/spinner" "github.com/leaanthony/spinner"
) )
@@ -249,8 +249,8 @@ func InstallFrontendDeps(projectDir string, projectOptions *ProjectOptions, forc
ioutil.WriteFile(md5sumFile, []byte(packageJSONMD5), 0644) ioutil.WriteFile(md5sumFile, []byte(packageJSONMD5), 0644)
} }
// Install the runtime // Install the bridge library
err = InstallRuntime(caller, projectDir, projectOptions) err = InstallBridge(caller, projectDir, projectOptions)
if err != nil { if err != nil {
return err return err
} }
@@ -263,29 +263,22 @@ func InstallFrontendDeps(projectDir string, projectOptions *ProjectOptions, forc
return nil return nil
} }
// InstallRuntime installs the correct runtime for the type of build // InstallBridge installs the relevant bridge javascript library
func InstallRuntime(caller string, projectDir string, projectOptions *ProjectOptions) error { func InstallBridge(caller string, projectDir string, projectOptions *ProjectOptions) error {
if caller == "build" { bridgeFile := "wailsbridge.prod.js"
return InstallProdRuntime(projectDir, projectOptions) if caller == "serve" {
bridgeFile = "wailsbridge.js"
} }
return InstallBridge(projectDir, projectOptions) // Copy bridge to project
} bridgeAssets := mewn.Group("../wailsruntimeassets/bridge/")
bridgeFileData := bridgeAssets.Bytes(bridgeFile)
// InstallBridge installs the relevant bridge javascript library bridgeFileTarget := filepath.Join(projectDir, projectOptions.FrontEnd.Dir, projectOptions.FrontEnd.Bridge, "wailsbridge.js")
func InstallBridge(projectDir string, projectOptions *ProjectOptions) error { err := fs.CreateFile(bridgeFileTarget, bridgeFileData)
bridgeFileData := mewn.String("../runtime/assets/bridge.js") if err != nil {
bridgeFileTarget := filepath.Join(projectDir, projectOptions.FrontEnd.Dir, "node_modules", "@wailsapp", "runtime", "main.js") return err
err := fs.CreateFile(bridgeFileTarget, []byte(bridgeFileData)) }
return err return nil
}
// InstallProdRuntime installs the production runtime
func InstallProdRuntime(projectDir string, projectOptions *ProjectOptions) error {
prodInit := mewn.String("../runtime/js/runtime/init.js")
bridgeFileTarget := filepath.Join(projectDir, projectOptions.FrontEnd.Dir, "node_modules", "@wailsapp", "runtime", "main.js")
err := fs.CreateFile(bridgeFileTarget, []byte(prodInit))
return err
} }
// ServeProject attempts to serve up the current project so that it may be connected to // ServeProject attempts to serve up the current project so that it may be connected to

View File

@@ -3,12 +3,9 @@ package cmd
import ( import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/url"
"os" "os"
"runtime" "regexp"
"strings" "strings"
"github.com/pkg/browser"
) )
// LinuxDistribution is of type int // LinuxDistribution is of type int
@@ -23,12 +20,6 @@ const (
Arch Arch
// RedHat linux distribution // RedHat linux distribution
RedHat RedHat
// Debian distribution
Debian
// Gentoo distribution
Gentoo
// Zorin distribution
Zorin
) )
// DistroInfo contains all the information relating to a linux distribution // DistroInfo contains all the information relating to a linux distribution
@@ -38,7 +29,6 @@ type DistroInfo struct {
Release string Release string
Codename string Codename string
DistributorID string DistributorID string
DiscoveredBy string
} }
// GetLinuxDistroInfo returns information about the running linux distribution // GetLinuxDistroInfo returns information about the running linux distribution
@@ -53,7 +43,7 @@ func GetLinuxDistroInfo() *DistroInfo {
if err != nil { if err != nil {
return result return result
} }
result.DiscoveredBy = "lsb"
for _, line := range strings.Split(stdout, "\n") { for _, line := range strings.Split(stdout, "\n") {
if strings.Contains(line, ":") { if strings.Contains(line, ":") {
// Iterate lines a // Iterate lines a
@@ -66,16 +56,10 @@ func GetLinuxDistroInfo() *DistroInfo {
switch value { switch value {
case "Ubuntu": case "Ubuntu":
result.Distribution = Ubuntu result.Distribution = Ubuntu
case "Arch", "ManjaroLinux": case "Arch":
result.Distribution = Arch
case "ManjaroLinux":
result.Distribution = Arch result.Distribution = Arch
case "Debian":
result.Distribution = Debian
case "Gentoo":
result.Distribution = Gentoo
case "Zorin":
result.Distribution = Zorin
case "Fedora":
result.Distribution = RedHat
} }
case "Description": case "Description":
result.Description = value result.Description = value
@@ -83,67 +67,27 @@ func GetLinuxDistroInfo() *DistroInfo {
result.Release = value result.Release = value
case "Codename": case "Codename":
result.Codename = value result.Codename = value
} }
} }
} }
// check if /etc/os-release exists // check if /etc/os-release exists
} else if _, err := os.Stat("/etc/os-release"); !os.IsNotExist(err) { } else if _, err := os.Stat("/etc/os-release"); !os.IsNotExist(err) {
// Default value
osName := "Unknown"
version := ""
// read /etc/os-release // read /etc/os-release
osRelease, _ := ioutil.ReadFile("/etc/os-release") osRelease, _ := ioutil.ReadFile("/etc/os-release")
// Split into lines // compile a regex to find NAME=distro
lines := strings.Split(string(osRelease), "\n") re := regexp.MustCompile(`^NAME=(.*)\n`)
// Iterate lines // extract the distro name
for _, line := range lines { osName := string(re.FindSubmatch(osRelease)[1])
// Split each line by the equals char // Check distro name against list of RedHat distros
splitLine := strings.SplitN(line, "=", 2) if osName == "Fedora" || osName == "CentOS" {
// Check we have //if it matches set result.Distribution to RedHat
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 result.Distribution = RedHat
case "CentOS":
result.Distribution = RedHat
case "Arch Linux":
result.Distribution = Arch
case "Debian GNU/Linux":
result.Distribution = Debian
case "Gentoo/Linux":
result.Distribution = Gentoo
default:
result.Distribution = Unknown
result.DistributorID = osName
} }
} }
return result return result
} }
// EqueryInstalled uses equery to see if a package is installed
func EqueryInstalled(packageName string) (bool, error) {
program := NewProgramHelper()
equery := program.FindProgram("equery")
if equery == nil {
return false, fmt.Errorf("cannont check dependencies: equery not found")
}
_, _, exitCode, _ := equery.Run("l", packageName)
return exitCode == 0, nil
}
// DpkgInstalled uses dpkg to see if a package is installed // DpkgInstalled uses dpkg to see if a package is installed
func DpkgInstalled(packageName string) (bool, error) { func DpkgInstalled(packageName string) (bool, error) {
program := NewProgramHelper() program := NewProgramHelper()
@@ -176,45 +120,3 @@ func RpmInstalled(packageName string) (bool, error) {
_, _, exitCode, _ := rpm.Run("--query", packageName) _, _, exitCode, _ := rpm.Run("--query", packageName)
return exitCode == 0, nil 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,10 +49,11 @@ func getRequiredProgramsLinux() *Prerequisites {
result := &Prerequisites{} result := &Prerequisites{}
distroInfo := GetLinuxDistroInfo() distroInfo := GetLinuxDistroInfo()
switch distroInfo.Distribution { switch distroInfo.Distribution {
case Ubuntu, Debian, Zorin: case Ubuntu:
result.Add(newPrerequisite("gcc", "Please install with `sudo apt install build-essentials` and try again")) 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("pkg-config", "Please install with `sudo apt install pkg-config` and try again"))
result.Add(newPrerequisite("npm", "Please install with `sudo snap install node --channel=12/stable --classic` and try again")) result.Add(newPrerequisite("npm", "Please install with `sudo apt install npm` and try again"))
default: default:
result.Add(newPrerequisite("gcc", "Please install with your system package manager and try again")) 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")) result.Add(newPrerequisite("pkg-config", "Please install with your system package manager and try again"))
@@ -93,12 +94,9 @@ func getRequiredLibrariesLinux() (*Prerequisites, error) {
result := &Prerequisites{} result := &Prerequisites{}
distroInfo := GetLinuxDistroInfo() distroInfo := GetLinuxDistroInfo()
switch distroInfo.Distribution { switch distroInfo.Distribution {
case Ubuntu, Debian, Zorin: case Ubuntu:
result.Add(newPrerequisite("libgtk-3-dev", "Please install with `sudo apt install libgtk-3-dev` and try again")) result.Add(newPrerequisite("libgtk-3-dev", "Please install with `sudo apt install libgtk-3-dev` and try again"))
result.Add(newPrerequisite("libwebkit2gtk-4.0-dev", "Please install with `sudo apt install libwebkit2gtk-4.0-dev` and try again")) result.Add(newPrerequisite("libwebkit2gtk-4.0-dev", "Please install with `sudo apt install libwebkit2gtk-4.0-dev` and try again"))
case Gentoo:
result.Add(newPrerequisite("gtk+:3", "Please install with `sudo emerge gtk+:3` and try again"))
result.Add(newPrerequisite("webkit-gtk", "Please install with `sudo emerge webkit-gtk` and try again"))
case Arch: case Arch:
result.Add(newPrerequisite("gtk3", "Please install with `sudo pacman -S gtk3` and try again")) result.Add(newPrerequisite("gtk3", "Please install with `sudo pacman -S gtk3` and try again"))
result.Add(newPrerequisite("webkit2gtk", "Please install with `sudo pacman -S webkit2gtk` and try again")) result.Add(newPrerequisite("webkit2gtk", "Please install with `sudo pacman -S webkit2gtk` and try again"))

View File

@@ -117,15 +117,14 @@ func (p *ProgramHelper) RunCommandArray(args []string, dir ...string) error {
} }
args = args[1:] args = args[1:]
var stderr string var stderr string
var stdout string // fmt.Printf("RunCommandArray = %s %+v\n", program, args)
if len(dir) > 0 { if len(dir) > 0 {
stdout, stderr, err = p.shell.RunInDirectory(dir[0], program, args...) _, stderr, err = p.shell.RunInDirectory(dir[0], program, args...)
} else { } else {
stdout, stderr, err = p.shell.Run(program, args...) _, stderr, err = p.shell.Run(program, args...)
} }
if err != nil { if err != nil {
fmt.Println(stderr) fmt.Println(stderr)
fmt.Println(stdout)
} }
return err return err
} }

View File

@@ -7,7 +7,6 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"sort"
"strings" "strings"
"github.com/leaanthony/slicer" "github.com/leaanthony/slicer"
@@ -51,6 +50,12 @@ func NewProjectHelper() *ProjectHelper {
// GenerateProject generates a new project using the options given // GenerateProject generates a new project using the options given
func (ph *ProjectHelper) GenerateProject(projectOptions *ProjectOptions) error { func (ph *ProjectHelper) GenerateProject(projectOptions *ProjectOptions) error {
// exists := ph.templates.TemplateExists(projectOptions.Template)
// if !exists {
// return fmt.Errorf("template '%s' is invalid", projectOptions.Template)
// }
// Calculate project path // Calculate project path
projectPath, err := filepath.Abs(projectOptions.OutputDirectory) projectPath, err := filepath.Abs(projectOptions.OutputDirectory)
if err != nil { if err != nil {
@@ -85,6 +90,8 @@ func (ph *ProjectHelper) GenerateProject(projectOptions *ProjectOptions) error {
// ph.GenerateWindowsResourceConfig(projectOptions) // 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 return nil
} }
@@ -144,13 +151,11 @@ type ProjectOptions struct {
log *Logger log *Logger
templates *TemplateHelper templates *TemplateHelper
selectedTemplate *TemplateDetails selectedTemplate *TemplateDetails
WailsVersion string
} }
// Defaults sets the default project template // Defaults sets the default project template
func (po *ProjectOptions) Defaults() { func (po *ProjectOptions) Defaults() {
po.Template = "vuebasic" po.Template = "vuebasic"
po.WailsVersion = Version
} }
// PromptForInputs asks the user to input project details // PromptForInputs asks the user to input project details
@@ -168,49 +173,19 @@ func (po *ProjectOptions) PromptForInputs() error {
// Process Templates // Process Templates
templateList := slicer.Interface() templateList := slicer.Interface()
options := slicer.String() options := slicer.String()
templateDetails, err := po.templates.GetTemplateDetails() for _, templateDetails := range po.templates.TemplateList.details {
if err != nil { templateList.Add(templateDetails)
return err options.Add(fmt.Sprintf("%s - %s", templateDetails.Metadata.Name, templateDetails.Metadata.ShortDescription))
} }
if po.Template != "" { templateIndex := 0
// Check template is valid if given
if templateDetails[po.Template] == nil {
keys := make([]string, 0, len(templateDetails))
for k := range templateDetails {
keys = append(keys, k)
}
return fmt.Errorf("invalid template name '%s'. Valid options: %s", po.Template, strings.Join(keys, ", "))
}
po.selectedTemplate = templateDetails[po.Template]
} else {
keys := make([]string, 0) if len(options.AsSlice()) > 1 {
for k := range templateDetails { templateIndex = PromptSelection("Please select a template", options.AsSlice(), 0)
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))
}
templateIndex := 0
if len(options.AsSlice()) > 1 {
templateIndex = PromptSelection("Please select a template", options.AsSlice(), 0)
}
if len(templateList.AsSlice()) == 0 {
return fmt.Errorf("aborting: no templates found")
}
// After selection do this....
po.selectedTemplate = templateList.AsSlice()[templateIndex].(*TemplateDetails)
} }
fmt.Println("Template: " + po.selectedTemplate.Metadata.Name) // After selection do this....
po.selectedTemplate = templateList.AsSlice()[templateIndex].(*TemplateDetails)
// Setup NPM Project name // Setup NPM Project name
po.NPMProjectName = strings.ToLower(strings.Replace(po.Name, " ", "_", -1)) po.NPMProjectName = strings.ToLower(strings.Replace(po.Name, " ", "_", -1))
@@ -291,6 +266,7 @@ func processProjectName(po *ProjectOptions) {
po.Name = Prompt("The name of the project", "My Project") po.Name = Prompt("The name of the project", "My Project")
} }
fmt.Println("Project Name: " + po.Name) fmt.Println("Project Name: " + po.Name)
} }
func processBinaryName(po *ProjectOptions) { func processBinaryName(po *ProjectOptions) {

View File

@@ -68,17 +68,6 @@ func (s *SystemHelper) ConfigFileIsValid() bool {
return err == nil return err == nil
} }
// GetAuthor returns a formatted string of the user's name and email
func (s *SystemHelper) GetAuthor() (string, error) {
var config *SystemConfig
config, err := s.LoadConfig()
if err != nil {
return "", err
}
return fmt.Sprintf("%s <%s>", config.Name, config.Email), nil
}
// BackupConfig attempts to backup the system config file // BackupConfig attempts to backup the system config file
func (s *SystemHelper) BackupConfig() (string, error) { func (s *SystemHelper) BackupConfig() (string, error) {
now := strconv.FormatInt(time.Now().UTC().UnixNano(), 10) now := strconv.FormatInt(time.Now().UTC().UnixNano(), 10)
@@ -272,7 +261,7 @@ func CheckDependencies(logger *Logger) (bool, error) {
distroInfo := GetLinuxDistroInfo() distroInfo := GetLinuxDistroInfo()
for _, library := range *requiredLibraries { for _, library := range *requiredLibraries {
switch distroInfo.Distribution { switch distroInfo.Distribution {
case Ubuntu, Zorin, Debian: case Ubuntu:
installed, err := DpkgInstalled(library.Name) installed, err := DpkgInstalled(library.Name)
if err != nil { if err != nil {
return false, err return false, err
@@ -295,6 +284,7 @@ func CheckDependencies(logger *Logger) (bool, error) {
logger.Green("Library '%s' installed.", library.Name) logger.Green("Library '%s' installed.", library.Name)
} }
case RedHat: case RedHat:
installed, err := RpmInstalled(library.Name) installed, err := RpmInstalled(library.Name)
if err != nil { if err != nil {
return false, err return false, err
@@ -305,19 +295,8 @@ func CheckDependencies(logger *Logger) (bool, error) {
} else { } else {
logger.Green("Library '%s' installed.", library.Name) logger.Green("Library '%s' installed.", library.Name)
} }
case Gentoo:
installed, err := EqueryInstalled(library.Name)
if err != nil {
return false, err
}
if !installed {
errors = true
logger.Error("Library '%s' not found. %s", library.Name, library.Help)
} else {
logger.Green("Library '%s' installed.", library.Name)
}
default: default:
return false, RequestSupportForDistribution(distroInfo, library.Name) return false, fmt.Errorf("unable to check libraries on distribution '%s'. Please ensure that the '%s' equivalent is installed", distroInfo.DistributorID, library.Name)
} }
} }
} }

View File

@@ -3,206 +3,115 @@ package cmd
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt"
"io/ioutil"
"log" "log"
"path/filepath" "path/filepath"
"regexp"
"strings" "strings"
"text/template" "text/template"
"github.com/kennygrant/sanitize" mewn "github.com/leaanthony/mewn"
mewnlib "github.com/leaanthony/mewn/lib"
"github.com/leaanthony/slicer" "github.com/leaanthony/slicer"
) )
// TemplateMetadata holds all the metadata for a Wails template // TemplateMetadata holds all the metadata for a Wails template
type TemplateMetadata struct { type TemplateMetadata struct {
Name string `json:"name"` Name string `json:"name"`
Version string `json:"version"` ShortDescription string `json:"shortdescription"`
ShortDescription string `json:"shortdescription"` Description string `json:"description"`
Description string `json:"description"` Install string `json:"install"`
Install string `json:"install"` Build string `json:"build"`
Build string `json:"build"` Author string `json:"author"`
Author string `json:"author"` Created string `json:"created"`
Created string `json:"created"` FrontendDir string `json:"frontenddir"`
FrontendDir string `json:"frontenddir"` Serve string `json:"serve"`
Serve string `json:"serve"` Bridge string `json:"bridge"`
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 // TemplateDetails holds information about a specific template
type TemplateDetails struct { type TemplateDetails struct {
Name string BasePath string
Path string Path string
Metadata *TemplateMetadata Metadata *TemplateMetadata
fs *FSHelper }
// TemplateList is a list of available templates
type TemplateList struct {
details map[string]*TemplateDetails
}
// NewTemplateList creates a new TemplateList object
func NewTemplateList(filenames *mewnlib.FileGroup) *TemplateList {
// Iterate each template and store information
result := &TemplateList{details: make(map[string]*TemplateDetails)}
entries := slicer.String()
entries.AddSlice(filenames.Entries())
// Find all template.json files
metadataFiles := entries.Filter(func(filename string) bool {
match, _ := regexp.MatchString("(.)+template.json$", filename)
return match
})
// Load each metadata file
metadataFiles.Each(func(filename string) {
fileData := filenames.Bytes(filename)
var metadata TemplateMetadata
err := json.Unmarshal(fileData, &metadata)
if err != nil {
log.Fatalf("corrupt metadata for template: %s", filename)
}
path := strings.Split(filename, "/")[0]
thisTemplate := &TemplateDetails{Path: path, Metadata: &metadata}
result.details[filename] = thisTemplate
})
return result
}
// Template holds details about a Wails template
type Template struct {
Name string
Path string
Description string
} }
// TemplateHelper is a utility object to help with processing templates // TemplateHelper is a utility object to help with processing templates
type TemplateHelper struct { type TemplateHelper struct {
templateDir *Dir TemplateList *TemplateList
fs *FSHelper Files *mewnlib.FileGroup
metadataFilename string
} }
// NewTemplateHelper creates a new template helper // NewTemplateHelper creates a new template helper
func NewTemplateHelper() *TemplateHelper { func NewTemplateHelper() *TemplateHelper {
files := mewn.Group("./templates")
templateDir, err := fs.LocalDir("./templates")
if err != nil {
log.Fatal("Unable to find the template directory. Please reinstall Wails.")
}
return &TemplateHelper{ return &TemplateHelper{
templateDir: templateDir, TemplateList: NewTemplateList(files),
metadataFilename: "template.json", Files: files,
} }
} }
// IsValidTemplate returns true if the given tempalte name resides on disk
func (t *TemplateHelper) IsValidTemplate(templateName string) bool {
pathToTemplate := filepath.Join(t.templateDir.fullPath, templateName)
return t.fs.DirExists(pathToTemplate)
}
// SanitizeFilename sanitizes the given string to make a valid filename
func (t *TemplateHelper) SanitizeFilename(name string) string {
return sanitize.Name(name)
}
// CreateNewTemplate creates a new template based on the given directory name and string
func (t *TemplateHelper) CreateNewTemplate(dirname string, details *TemplateMetadata) (string, error) {
// Check if this template has already been created
if t.IsValidTemplate(dirname) {
return "", fmt.Errorf("cannot create template in directory '%s' - already exists", dirname)
}
targetDir := filepath.Join(t.templateDir.fullPath, dirname)
err := t.fs.MkDir(targetDir)
if err != nil {
return "", err
}
targetMetadata := filepath.Join(targetDir, t.metadataFilename)
err = t.fs.SaveAsJSON(details, targetMetadata)
return targetDir, err
}
// LoadMetadata loads the template's 'metadata.json' file
func (t *TemplateHelper) LoadMetadata(dir string) (*TemplateMetadata, error) {
templateFile := filepath.Join(dir, t.metadataFilename)
result := &TemplateMetadata{}
if !t.fs.FileExists(templateFile) {
return nil, nil
}
rawJSON, err := ioutil.ReadFile(templateFile)
if err != nil {
return nil, err
}
err = json.Unmarshal(rawJSON, &result)
return result, err
}
// GetTemplateDetails returns a map of Template structs containing details
// of the found templates
func (t *TemplateHelper) GetTemplateDetails() (map[string]*TemplateDetails, error) {
// Get the subdirectory details
templateDirs, err := t.templateDir.GetSubdirs()
if err != nil {
return nil, err
}
result := make(map[string]*TemplateDetails)
for name, dir := range templateDirs {
result[name] = &TemplateDetails{
Path: dir,
}
_ = &TemplateMetadata{}
metadata, err := t.LoadMetadata(dir)
if err != nil {
return nil, err
}
result[name].Metadata = metadata
if metadata.Name != "" {
result[name].Name = metadata.Name
} else {
// Ignore bad templates?
result[name] = nil
}
}
return result, nil
}
// GetTemplateFilenames returns all the filenames of the given template
func (t *TemplateHelper) GetTemplateFilenames(template *TemplateDetails) (*slicer.StringSlicer, error) {
// Get the subdirectory details
templateDir, err := t.fs.Directory(template.Path)
if err != nil {
return nil, err
}
return templateDir.GetAllFilenames()
}
// InstallTemplate installs the template given in the project options to the // InstallTemplate installs the template given in the project options to the
// project path given // project path given
func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *ProjectOptions) error { 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 // Get template files
templateFilenames, err := t.GetTemplateFilenames(projectOptions.selectedTemplate)
if err != nil {
return err
}
templatePath := projectOptions.selectedTemplate.Path templatePath := projectOptions.selectedTemplate.Path
// Save the version templateFilenames := slicer.String()
projectOptions.WailsVersion = Version templateFilenames.AddSlice(projectOptions.templates.Files.Entries())
templateJSONFilename := filepath.Join(templatePath, t.metadataFilename) templateJSONFilename := filepath.Join(templatePath, "template.json")
templateFiles := templateFilenames.Filter(func(filename string) bool { templateFiles := templateFilenames.Filter(func(filename string) bool {
filename = filepath.FromSlash(filename) filename = filepath.FromSlash(filename)
return strings.HasPrefix(filename, templatePath) && filename != templateJSONFilename return strings.HasPrefix(filename, templatePath) && filename != templateJSONFilename
}) })
var err error
templateFiles.Each(func(templateFile string) { templateFiles.Each(func(templateFile string) {
// Setup filenames // Setup filenames
@@ -211,14 +120,11 @@ func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *Pro
if err != nil { if err != nil {
return return
} }
filedata, err := t.fs.LoadAsBytes(templateFile) filedata := projectOptions.templates.Files.Bytes(templateFile)
if err != nil {
return
}
// If file is a template, process it // If file is a template, process it
if strings.HasSuffix(templateFile, ".template") { if strings.HasSuffix(templateFile, ".template") {
templateData := string(filedata) templateData := projectOptions.templates.Files.String(templateFile)
tmpl := template.New(templateFile) tmpl := template.New(templateFile)
tmpl.Parse(templateData) tmpl.Parse(templateData)
var tpl bytes.Buffer var tpl bytes.Buffer

View File

@@ -1,13 +0,0 @@
# 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

@@ -1,47 +0,0 @@
# 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

@@ -1,27 +0,0 @@
# 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

@@ -1,121 +0,0 @@
{
"$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

@@ -1,12 +0,0 @@
# 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

@@ -1,32 +0,0 @@
// @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

@@ -1,23 +0,0 @@
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

@@ -1,11 +0,0 @@
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

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

View File

@@ -1,32 +0,0 @@
// 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

@@ -1,51 +0,0 @@
{
"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",
"@wailsapp/runtime": "^1.0.0",
"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

@@ -1,13 +0,0 @@
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

@@ -1,14 +0,0 @@
<!--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

@@ -1,35 +0,0 @@
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

@@ -1,19 +0,0 @@
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

@@ -1,20 +0,0 @@
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

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

View File

@@ -1,16 +0,0 @@
// 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.

Before

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -1,14 +0,0 @@
<!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

@@ -1,18 +0,0 @@
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 Wails from '@wailsapp/runtime';
if (environment.production) {
enableProdMode();
}
Wails.Init(() => {
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
});

View File

@@ -1,63 +0,0 @@
/**
* 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

@@ -1,24 +0,0 @@
/* 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

@@ -1,20 +0,0 @@
// 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

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

View File

@@ -1,23 +0,0 @@
{
"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

@@ -1,18 +0,0 @@
{
"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

@@ -1,92 +0,0 @@
{
"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

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

View File

@@ -1,27 +0,0 @@
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

@@ -1,20 +0,0 @@
{
"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

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

View File

@@ -1,23 +0,0 @@
# 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

@@ -1,68 +0,0 @@
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

@@ -1,34 +0,0 @@
{
"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",
"@wailsapp/runtime": "^1.0.0"
},
"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.

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -1,38 +0,0 @@
<!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

@@ -1,15 +0,0 @@
{
"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

@@ -1,33 +0,0 @@
.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

@@ -1,21 +0,0 @@
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

@@ -1,9 +0,0 @@
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

@@ -1,48 +0,0 @@
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

@@ -1,13 +0,0 @@
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

@@ -1,10 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import Wails from '@wailsapp/runtime';
Wails.Init(() => {
ReactDOM.render(<App />, document.getElementById('app'));
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 KiB

View File

@@ -1,135 +0,0 @@
// 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

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

View File

@@ -1,27 +0,0 @@
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

@@ -1,14 +0,0 @@
{
"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

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

File diff suppressed because it is too large Load Diff

View File

@@ -9,8 +9,7 @@
}, },
"dependencies": { "dependencies": {
"core-js": "^2.6.4", "core-js": "^2.6.4",
"vue": "^2.5.22", "vue": "^2.5.22"
"@wailsapp/runtime": "^1.0.0"
}, },
"devDependencies": { "devDependencies": {
"@vue/cli-plugin-babel": "^3.4.0", "@vue/cli-plugin-babel": "^3.4.0",

View File

@@ -1,13 +1,13 @@
import Vue from 'vue'; import Vue from "vue";
import App from './App.vue'; import App from "./App.vue";
Vue.config.productionTip = false; Vue.config.productionTip = false;
Vue.config.devtools = true; Vue.config.devtools = true;
import Wails from '@wailsapp/runtime'; import Bridge from "./wailsbridge";
Wails.Init(() => { Bridge.Start(() => {
new Vue({ new Vue({
render: h => h(App) render: h => h(App)
}).$mount('#app'); }).$mount("#app");
}); });

View File

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

View File

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

View File

@@ -1,21 +0,0 @@
.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

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

View File

@@ -1,53 +0,0 @@
{
"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",
"@wailsapp/runtime": "^1.0.0"
},
"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

@@ -1,60 +0,0 @@
<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.

Before

Width:  |  Height:  |  Size: 301 KiB

View File

@@ -1,83 +0,0 @@
<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

@@ -1,21 +0,0 @@
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 Wails from '@wailsapp/runtime';
Wails.Init(() => {
new Vue({
render: h => h(App)
}).$mount('#app');
});

View File

@@ -1,43 +0,0 @@
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

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

View File

@@ -1,27 +0,0 @@
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

@@ -1,14 +0,0 @@
{
"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 package cmd
// Version - Wails version // Version - Wails version
const Version = "v0.17.5-pre" const Version = "v0.14.0-pre"

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