Compare commits

..

1 Commits

Author SHA1 Message Date
Travis McLane
ddcaf58a90 runtime.Store => wails.Store 2020-09-04 13:02:11 -05:00
50 changed files with 41 additions and 1028 deletions

7
.gitignore vendored
View File

@@ -16,9 +16,4 @@ examples/**/example*
cmd/wails/wails cmd/wails/wails
.DS_Store .DS_Store
tmp tmp
node_modules/ node_modules/
v2/test/kitchensink/frontend/public
v2/internal/ffenestri/runtime.c
v2/internal/runtime/assets/desktop.js
v2/test/kitchensink/build/darwin/desktop/kitchensink
v2/test/kitchensink/frontend/package.json.md5

View File

@@ -33,8 +33,3 @@ Wails is what it is because of the time and effort given by these great people.
* [artem](https://github.com/Unix4ever) * [artem](https://github.com/Unix4ever)
* [Tim Kipp](https://github.com/timkippdev) * [Tim Kipp](https://github.com/timkippdev)
* [Dmitry Gomzyakov](https://github.com/kyoto44) * [Dmitry Gomzyakov](https://github.com/kyoto44)
* [Arthur Wiebe](https://github.com/artooro)
* [Ilgıt Yıldırım](https://github.com/ilgityildirim)
* [Altynbek](https://github.com/gelleson)
* [Kyle](https://github.com/kmuchmore)
* [Balakrishna Prasad Ganne](https://github.com/aayush420)

View File

@@ -12,6 +12,7 @@
<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/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/wailsapp/wails/workflows/release/badge.svg?branch=master" rel="nofollow"><img src="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" alt="Release Pipelines"></a> <a href="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" rel="nofollow"><img src="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" alt="Release Pipelines"></a>
<a href="https://github.com/wailsapp/wails/workflows/latest-pre/badge.svg?branch=masterr" rel="nofollow"><img src="https://github.com/wailsapp/wails/workflows/latest-pre/badge.svg?branch=master" alt="Pre-Release Pipelines"></a>
</p> </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!

View File

@@ -18,8 +18,6 @@ import (
"github.com/leaanthony/spinner" "github.com/leaanthony/spinner"
) )
const xgoVersion = "1.0.1"
var fs = NewFSHelper() var fs = NewFSHelper()
// ValidateFrontendConfig checks if the frontend config is valid // ValidateFrontendConfig checks if the frontend config is valid
@@ -92,17 +90,16 @@ func InitializeCrossCompilation(verbose bool) error {
} }
var packSpinner *spinner.Spinner var packSpinner *spinner.Spinner
msg := fmt.Sprintf("Pulling wailsapp/xgo:%s docker image... (may take a while)", xgoVersion)
if !verbose { if !verbose {
packSpinner = spinner.New(msg) packSpinner = spinner.New("Pulling wailsapp/xgo:latest docker image... (may take a while)")
packSpinner.SetSpinSpeed(50) packSpinner.SetSpinSpeed(50)
packSpinner.Start() packSpinner.Start()
} else { } else {
println(msg) println("Pulling wailsapp/xgo:latest docker image... (may take a while)")
} }
err := NewProgramHelper(verbose).RunCommandArray([]string{"docker", err := NewProgramHelper(verbose).RunCommandArray([]string{"docker",
"pull", fmt.Sprintf("wailsapp/xgo:%s", xgoVersion)}) "pull", "wailsapp/xgo:latest"})
if err != nil { if err != nil {
if packSpinner != nil { if packSpinner != nil {
@@ -117,7 +114,7 @@ func InitializeCrossCompilation(verbose bool) error {
return nil return nil
} }
// BuildDocker builds the project using the cross compiling wailsapp/xgo:<xgoVersion> container // BuildDocker builds the project using the cross compiling wailsapp/xgo:latest container
func BuildDocker(binaryName string, buildMode string, projectOptions *ProjectOptions) error { func BuildDocker(binaryName string, buildMode string, projectOptions *ProjectOptions) error {
var packSpinner *spinner.Spinner var packSpinner *spinner.Spinner
if buildMode == BuildModeBridge { if buildMode == BuildModeBridge {
@@ -143,31 +140,24 @@ func BuildDocker(binaryName string, buildMode string, projectOptions *ProjectOpt
"-v", fmt.Sprintf("%s:/build", filepath.Join(fs.Cwd(), "build")), "-v", fmt.Sprintf("%s:/build", filepath.Join(fs.Cwd(), "build")),
"-v", fmt.Sprintf("%s:/source", fs.Cwd()), "-v", fmt.Sprintf("%s:/source", fs.Cwd()),
"-e", fmt.Sprintf("LOCAL_USER_ID=%v", userid), "-e", fmt.Sprintf("LOCAL_USER_ID=%v", userid),
"-e", fmt.Sprintf("FLAG_TAGS=%s", projectOptions.Tags),
"-e", fmt.Sprintf("FLAG_LDFLAGS=%s", ldFlags(projectOptions, buildMode)), "-e", fmt.Sprintf("FLAG_LDFLAGS=%s", ldFlags(projectOptions, buildMode)),
"-e", "FLAG_V=false", "-e", "FLAG_V=false",
"-e", "FLAG_X=false", "-e", "FLAG_X=false",
"-e", "FLAG_RACE=false", "-e", "FLAG_RACE=false",
"-e", "FLAG_BUILDMODE=default", "-e", "FLAG_BUILDMODE=default",
"-e", "FLAG_TRIMPATH=false", "-e", "FLAG_TRIMPATH=false",
"-e", fmt.Sprintf("TARGETS=%s/%s", projectOptions.Platform, projectOptions.Architecture), "-e", fmt.Sprintf("TARGETS=%s", projectOptions.Platform+"/"+projectOptions.Architecture),
"-e", "GOPROXY=", "-e", "GOPROXY=",
"-e", "GO111MODULE=on", "-e", "GO111MODULE=on",
"wailsapp/xgo:latest",
".",
} { } {
buildCommand.Add(arg) buildCommand.Add(arg)
} }
if projectOptions.GoPath != "" {
buildCommand.Add("-v")
buildCommand.Add(fmt.Sprintf("%s:/go", projectOptions.GoPath))
}
buildCommand.Add(fmt.Sprintf("wailsapp/xgo:%s", xgoVersion))
buildCommand.Add(".")
compileMessage := fmt.Sprintf( compileMessage := fmt.Sprintf(
"Packing + Compiling project for %s/%s using docker image wailsapp/xgo:%s", "Packing + Compiling project for %s/%s using docker image wailsapp/xgo:latest",
projectOptions.Platform, projectOptions.Architecture, xgoVersion) projectOptions.Platform, projectOptions.Architecture)
if buildMode == BuildModeDebug { if buildMode == BuildModeDebug {
compileMessage += " (Debug Mode)" compileMessage += " (Debug Mode)"
@@ -226,6 +216,10 @@ func BuildNative(binaryName string, forceRebuild bool, buildMode string, project
buildCommand.Add("go") buildCommand.Add("go")
buildCommand.Add("build") buildCommand.Add("build")
if buildMode == BuildModeBridge {
// Ignore errors
buildCommand.Add("-i")
}
if binaryName != "" { if binaryName != "" {
// Alter binary name based on OS // Alter binary name based on OS
@@ -249,10 +243,6 @@ func BuildNative(binaryName string, forceRebuild bool, buildMode string, project
buildCommand.AddSlice([]string{"-ldflags", ldFlags(projectOptions, buildMode)}) buildCommand.AddSlice([]string{"-ldflags", ldFlags(projectOptions, buildMode)})
if projectOptions.Tags != "" {
buildCommand.AddSlice([]string{"--tags", projectOptions.Tags})
}
if projectOptions.Verbose { if projectOptions.Verbose {
fmt.Printf("Command: %v\n", buildCommand.AsSlice()) fmt.Printf("Command: %v\n", buildCommand.AsSlice())
} }
@@ -540,9 +530,6 @@ func InstallProdRuntime(projectDir string, projectOptions *ProjectOptions) error
func ServeProject(projectOptions *ProjectOptions, logger *Logger) error { func ServeProject(projectOptions *ProjectOptions, logger *Logger) error {
go func() { go func() {
time.Sleep(2 * time.Second) time.Sleep(2 * time.Second)
if projectOptions.Platform == "windows" {
logger.Yellow("*** Please note: Windows builds use mshtml which is only compatible with IE11. We strongly recommend only using IE11 when running 'wails serve'! For more information, please read https://wails.app/guides/windows/ ***")
}
logger.Green(">>>>> To connect, you will need to run '" + projectOptions.FrontEnd.Serve + "' in the '" + projectOptions.FrontEnd.Dir + "' directory <<<<<") logger.Green(">>>>> To connect, you will need to run '" + projectOptions.FrontEnd.Serve + "' in the '" + projectOptions.FrontEnd.Dir + "' directory <<<<<")
}() }()
location, err := filepath.Abs(filepath.Join("build", projectOptions.BinaryName)) location, err := filepath.Abs(filepath.Join("build", projectOptions.BinaryName))

View File

@@ -6,7 +6,6 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"runtime"
"sort" "sort"
"strings" "strings"
@@ -151,7 +150,6 @@ type ProjectOptions struct {
Template string `json:"-"` Template string `json:"-"`
BinaryName string `json:"binaryname"` BinaryName string `json:"binaryname"`
FrontEnd *frontend `json:"frontend,omitempty"` FrontEnd *frontend `json:"frontend,omitempty"`
Tags string `json:"tags"`
NPMProjectName string `json:"-"` NPMProjectName string `json:"-"`
system *SystemHelper system *SystemHelper
log *Logger log *Logger
@@ -164,24 +162,6 @@ type ProjectOptions struct {
Platform string Platform string
Architecture string Architecture string
LdFlags string LdFlags string
GoPath string
// Supported platforms
Platforms []string `json:"platforms,omitempty"`
}
// PlatformSupported returns true if the template is supported
// on the current platform
func (po *ProjectOptions) PlatformSupported() bool {
// Default is all platforms supported
if len(po.Platforms) == 0 {
return true
}
// Check that the platform is in the list
platformsSupported := slicer.String(po.Platforms)
return platformsSupported.Contains(runtime.GOOS)
} }
// Defaults sets the default project template // Defaults sets the default project template
@@ -252,16 +232,13 @@ func (po *ProjectOptions) PromptForInputs() error {
for _, k := range keys { for _, k := range keys {
templateDetail := templateDetails[k] templateDetail := templateDetails[k]
templateList.Add(templateDetail) templateList.Add(templateDetail)
if !templateDetail.Metadata.PlatformSupported() {
templateDetail.Metadata.Name = "* " + templateDetail.Metadata.Name
}
options.Add(fmt.Sprintf("%s - %s", templateDetail.Metadata.Name, templateDetail.Metadata.ShortDescription)) options.Add(fmt.Sprintf("%s - %s", templateDetail.Metadata.Name, templateDetail.Metadata.ShortDescription))
} }
templateIndex := 0 templateIndex := 0
if len(options.AsSlice()) > 1 { if len(options.AsSlice()) > 1 {
templateIndex = PromptSelection("Please select a template (* means unsupported on current platform)", options.AsSlice(), 0) templateIndex = PromptSelection("Please select a template", options.AsSlice(), 0)
} }
if len(templateList.AsSlice()) == 0 { if len(templateList.AsSlice()) == 0 {
@@ -272,10 +249,6 @@ func (po *ProjectOptions) PromptForInputs() error {
po.selectedTemplate = templateList.AsSlice()[templateIndex].(*TemplateDetails) po.selectedTemplate = templateList.AsSlice()[templateIndex].(*TemplateDetails)
} }
po.selectedTemplate.Metadata.Name = strings.TrimPrefix(po.selectedTemplate.Metadata.Name, "* ")
if !po.selectedTemplate.Metadata.PlatformSupported() {
println("WARNING: This template is unsupported on this platform!")
}
fmt.Println("Template: " + po.selectedTemplate.Metadata.Name) fmt.Println("Template: " + po.selectedTemplate.Metadata.Name)
// Setup NPM Project name // Setup NPM Project name
@@ -398,9 +371,5 @@ func processTemplateMetadata(templateMetadata *TemplateMetadata, po *ProjectOpti
} }
po.FrontEnd.Serve = templateMetadata.Serve po.FrontEnd.Serve = templateMetadata.Serve
} }
// Save platforms
po.Platforms = templateMetadata.Platforms
return nil return nil
} }

View File

@@ -7,7 +7,6 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"path/filepath" "path/filepath"
"runtime"
"strings" "strings"
"text/template" "text/template"
@@ -30,26 +29,6 @@ type TemplateMetadata struct {
Bridge string `json:"bridge"` Bridge string `json:"bridge"`
WailsDir string `json:"wailsdir"` WailsDir string `json:"wailsdir"`
TemplateDependencies []*TemplateDependency `json:"dependencies,omitempty"` TemplateDependencies []*TemplateDependency `json:"dependencies,omitempty"`
// List of platforms that this template is supported on.
// No value means all platforms. A platform name is the same string
// as `runtime.GOOS` will return, eg: "darwin". NOTE: This is
// case sensitive.
Platforms []string `json:"platforms,omitempty"`
}
// PlatformSupported returns true if this template supports the
// currently running platform
func (m *TemplateMetadata) PlatformSupported() bool {
// Default is all platforms supported
if len(m.Platforms) == 0 {
return true
}
// Check that the platform is in the list
platformsSupported := slicer.String(m.Platforms)
return platformsSupported.Contains(runtime.GOOS)
} }
// TemplateDependency defines a binary dependency for the template // TemplateDependency defines a binary dependency for the template
@@ -149,11 +128,11 @@ func (t *TemplateHelper) GetTemplateDetails() (map[string]*TemplateDetails, erro
result[name] = &TemplateDetails{ result[name] = &TemplateDetails{
Path: dir, Path: dir,
} }
_ = &TemplateMetadata{}
metadata, err := t.LoadMetadata(dir) metadata, err := t.LoadMetadata(dir)
if err != nil { if err != nil {
return nil, err return nil, err
} }
result[name].Metadata = metadata result[name].Metadata = metadata
if metadata.Name != "" { if metadata.Name != "" {
result[name].Name = metadata.Name result[name].Name = metadata.Name

View File

@@ -5,7 +5,7 @@ const routes: Routes = [];
@NgModule({ @NgModule({
imports: [ imports: [
RouterModule.forRoot(routes,{useHash:true}) RouterModule.forRoot(routes)
], ],
exports: [RouterModule] exports: [RouterModule]
}) })

View File

@@ -1,4 +0,0 @@
/node_modules/
/public/build/
.DS_Store

View File

@@ -1,90 +0,0 @@
*Looking for a shareable component template? Go here --> [sveltejs/component-template](https://github.com/sveltejs/component-template)*
---
# svelte app
This is a project template for [Svelte](https://svelte.dev) apps. It lives at https://github.com/sveltejs/template.
To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit):
```bash
npx degit sveltejs/template svelte-app
cd svelte-app
```
*Note that you will need to have [Node.js](https://nodejs.org) installed.*
## Get started
Install the dependencies...
```bash
cd svelte-app
npm install
```
...then start [Rollup](https://rollupjs.org):
```bash
npm run dev
```
Navigate to [localhost:5000](http://localhost:5000). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes.
By default, the server will only respond to requests from localhost. To allow connections from other computers, edit the `sirv` commands in package.json to include the option `--host 0.0.0.0`.
## Building and running in production mode
To create an optimised version of the app:
```bash
npm run build
```
You can run the newly built app with `npm run start`. This uses [sirv](https://github.com/lukeed/sirv), which is included in your package.json's `dependencies` so that the app will work when you deploy to platforms like [Heroku](https://heroku.com).
## Single-page app mode
By default, sirv will only respond to requests that match files in `public`. This is to maximise compatibility with static fileservers, allowing you to deploy your app anywhere.
If you're building a single-page app (SPA) with multiple routes, sirv needs to be able to respond to requests for *any* path. You can make it so by editing the `"start"` command in package.json:
```js
"start": "sirv public --single"
```
## Deploying to the web
### With [Vercel](https://vercel.com)
Install `vercel` if you haven't already:
```bash
npm install -g vercel
```
Then, from within your project folder:
```bash
cd public
vercel deploy --name my-project
```
### With [surge](https://surge.sh/)
Install `surge` if you haven't already:
```bash
npm install -g surge
```
Then, from within your project folder:
```bash
npm run build
surge public my-project.surge.sh
```

View File

@@ -1,31 +0,0 @@
{
"name": "{{.NPMProjectName}}",
"author": "{{.Author.Name}}<{{.Author.Email}}>",
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "sirv public"
},
"devDependencies": {
"@babel/core": "^7.11.6",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.11.5",
"@babel/preset-env": "^7.11.5",
"@rollup/plugin-commonjs": "^14.0.0",
"@rollup/plugin-image": "^2.0.5",
"@rollup/plugin-node-resolve": "^8.0.0",
"core-js": "^3.6.5",
"rollup": "^2.3.4",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-livereload": "^2.0.0",
"rollup-plugin-polyfill": "^3.0.0",
"rollup-plugin-svelte": "^6.0.0",
"rollup-plugin-terser": "^7.0.0",
"svelte": "^3.0.0"
},
"dependencies": {
"sirv-cli": "^1.0.0",
"@wailsapp/runtime": "^1.0.10",
"svelte-simple-modal": "^0.6.0"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>Svelte app</title>
<link rel='icon' type='image/png' href='/favicon.png'>
<link rel='stylesheet' href='/build/bundle.css'>
<script defer src='/build/bundle.js'></script>
</head>
<body>
</body>
</html>

View File

@@ -1,110 +0,0 @@
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
import image from '@rollup/plugin-image';
import babel from 'rollup-plugin-babel';
import polyfill from 'rollup-plugin-polyfill';
const production = !process.env.ROLLUP_WATCH;
function serve() {
let server;
function toExit() {
if (server) server.kill(0);
}
return {
writeBundle() {
if (server) return;
server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
process.on('SIGTERM', toExit);
process.on('exit', toExit);
}
};
}
export default {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/bundle.js'
},
plugins: [
image(),
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
css: css => {
css.write('bundle.css');
}
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte', 'svelte/transition', 'svelte/internal']
}),
commonjs(),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// Credit: https://blog.az.sg/posts/svelte-and-ie11/
babel({
extensions: [ '.js', '.jsx', '.es6', '.es', '.mjs', '.svelte', '.html' ],
runtimeHelpers: true,
exclude: [ 'node_modules/@babel/**', 'node_modules/core-js/**' ],
presets: [
[
'@babel/preset-env',
{
targets: '> 0.25%, not dead, IE 11',
modules: false,
spec: true,
useBuiltIns: 'usage',
forceAllTransforms: true,
corejs: 3,
},
]
],
plugins: [
'@babel/plugin-syntax-dynamic-import',
[
'@babel/plugin-transform-runtime',
{
useESModules: true
}
]
]
}),
polyfill(['@webcomponents/webcomponentsjs']),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};

View File

@@ -1,69 +0,0 @@
<script>
import Modal from 'svelte-simple-modal';
import HelloWorld from './components/HelloWorld.svelte'
import logo from './logo.png';
</script>
<main>
<div class="App">
<header class="App-header">
<Modal>
<img src={logo} class="App-logo" alt="logo" />
<p>Welcome to your new <code>wails/svelte</code> project.</p>
<HelloWorld/>
</Modal>
</header>
</div>
</main>
<style>
:global(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;
}
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.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;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>

View File

@@ -1,18 +0,0 @@
<script>
import { getContext } from 'svelte';
import ModalContent from './ModalContent.svelte'
const { open } = getContext('simple-modal');
const handleOpenModal = () => {
window.backend.basic().then((result) => {
open(ModalContent, { message: result });
});
};
</script>
<main>
<p><button on:click={handleOpenModal}>Hello</button></p>
</main>
<style></style>

View File

@@ -1,7 +0,0 @@
<script>
export let message;
</script>
<p>
{message}
</p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 KiB

View File

@@ -1,13 +0,0 @@
import App from './App.svelte';
import * as Wails from '@wailsapp/runtime';
let app;
Wails.Init(() => {
app = new App({
target: document.body,
});
});
export default app;

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/public/build/bundle.js")
css := mewn.String("./frontend/public/build/bundle.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": "Svelte",
"version": "1.0.0",
"shortdescription": "A basic Svelte template",
"description": "A basic Svelte template",
"install": "npm install",
"build": "npm run build",
"author": "Tim Kipp <timkipp.22.developer@gmail.com>",
"created": "2020-09-06 13:06:10.469848 -0700 PDT m=+213.578828559",
"frontenddir": "frontend",
"serve": "npm run dev",
"bridge": "src",
"wailsdir": ""
}

View File

@@ -2,33 +2,29 @@
html, html,
body { body {
background-color: white; background-color: white;
color: black;
width: 100%; width: 100%;
height: 100%; height: 100%;
margin: 0; margin: 0;
} }
input {
background-color: rgb(254,254,254);
color: black;
}
.container { .container {
display: block; display: block;
width:100%; width:100%;
text-align: center; text-align: center;
margin-top: 1rem; margin-top: 3rem;
font-size: 2rem; font-size: 2rem;
} }
button { button {
font-size: 1rem; font-size: 1rem;
background-color: white; }
color: black;
#newCounter {
color: white;
} }
.result { .result {
margin-top: 1rem; margin-top: 3rem;
text-align: center; text-align: center;
font-size: 2rem; font-size: 2rem;
} }

View File

@@ -4,7 +4,7 @@ const runtime = require('@wailsapp/runtime');
// Main entry point // Main entry point
function start() { function start() {
var mystore = runtime.Store.New('Counter'); var mystore = wails.Store.New('Counter');
// Ensure the default app div is 100% wide/high // Ensure the default app div is 100% wide/high
var app = document.getElementById('app'); var app = document.getElementById('app');
@@ -36,12 +36,12 @@ function start() {
mystore.set(newValue); mystore.set(newValue);
}; };
mystore.subscribe( function(state) { mystore.subscribe( (state) => {
document.getElementById('counter').innerText = state; document.getElementById('counter').innerText = state;
}); });
mystore.set(0); mystore.set(0);
}; };
// We provide our entrypoint as a callback for runtime.Init // We provide our entrypoint as a callback for runtime.Init
runtime.Init(start); runtime.Init(start);

View File

@@ -1,3 +0,0 @@
> 1%
last 2 versions
not dead

View File

@@ -1,29 +0,0 @@
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/typescript/recommended'
],
parserOptions: {
ecmaVersion: 2020
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
},
overrides: [
{
files: [
'**/__tests__/*.{j,t}s?(x)',
'**/tests/unit/**/*.spec.{j,t}s?(x)'
],
env: {
mocha: true
}
}
]
}

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,35 +0,0 @@
# vue basic
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Run your tests
```
npm run test
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@@ -1,37 +0,0 @@
{
"name": "{{.NPMProjectName}}",
"author": "{{.Author.Name}}<{{.Author.Email}}>",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"lint": "vue-cli-service lint"
},
"dependencies": {
"vue": "^3.0.0-0",
"vue-router": "^4.0.0-0",
"regenerator-runtime": "^0.13.7",
"@wailsapp/runtime": "^1.1.1"
},
"devDependencies": {
"@types/chai": "^4.2.12",
"@types/mocha": "^8.0.3",
"@typescript-eslint/eslint-plugin": "^4.3.0",
"@typescript-eslint/parser": "^4.3.0",
"@vue/cli-plugin-eslint": "~4.5.6",
"@vue/cli-plugin-router": "~4.5.6",
"@vue/cli-plugin-typescript": "~4.5.6",
"@vue/cli-plugin-unit-mocha": "~4.5.6",
"@vue/cli-service": "~4.5.6",
"@vue/compiler-sfc": "^3.0.0",
"@vue/eslint-config-typescript": "^5.1.0",
"@vue/test-utils": "^2.0.0-0",
"chai": "^4.2.0",
"eslint": "^7.10.0",
"eslint-plugin-vue": "^7.0.0",
"node-sass": "^4.14.1",
"sass-loader": "^10.0.2",
"typescript": "~4.0.3"
}
}

View File

@@ -1,32 +0,0 @@
<template>
<div id=app>
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view/>
</div>
</template>
<style lang="scss">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

View File

@@ -1,34 +0,0 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'HelloWorld',
props: {
msg: String,
},
});
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

View File

@@ -1,8 +0,0 @@
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import * as Wails from '@wailsapp/runtime';
Wails.Init(() => {
createApp(App).use(router).mount('#app');
});

View File

@@ -1,27 +0,0 @@
import { createRouter, createMemoryHistory, RouteRecordRaw } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
// component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
component: About
}
]
const router = createRouter({
history: createMemoryHistory(),
routes
})
export default router

View File

@@ -1,5 +0,0 @@
declare module '*.vue' {
import { defineComponent } from 'vue'
const component: ReturnType<typeof defineComponent>
export default component
}

View File

@@ -1,5 +0,0 @@
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>

View File

@@ -1,40 +0,0 @@
<template>
<div class="home">
<img @click="getMessage" alt="Vue logo" src="../assets/appicon.png" :style="{ height: '400px' }"/>
<HelloWorld :msg="message" />
</div>
</template>
<script lang="ts">
import { ref, defineComponent } from "vue";
import HelloWorld from "@/components/HelloWorld.vue"; // @ is an alias to /src
interface Backend {
basic(): Promise<string>;
}
declare global {
interface Window {
backend: Backend;
}
}
export default defineComponent({
name: "Home",
components: {
HelloWorld,
},
setup() {
const message = ref("Click the Icon");
const getMessage = () => {
window.backend.basic().then(result => {
message.value = result;
});
}
return { message: message, getMessage: getMessage };
},
});
</script>

View File

@@ -1,14 +0,0 @@
import { expect } from 'chai';
import { describe, it } from 'mocha';
import { shallowMount } from '@vue/test-utils';
import HelloWorld from '@/components/HelloWorld.vue';
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const msg = 'new message';
const wrapper = shallowMount(HelloWorld, {
props: { msg }
});
expect(wrapper.text()).to.include(msg);
});
});

View File

@@ -1,41 +0,0 @@
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env",
"mocha",
"chai"
],
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}

View File

@@ -1,42 +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
}
};

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,15 +0,0 @@
{
"name": "Vue3 Full",
"version": "1.0.0",
"shortdescription": "Vue 3, Vuex, Vue-router, and Webpack4",
"description": "Vue3.0.0 Vuex, Vue-router, and Webpack 4",
"install": "npm install",
"build": "npm run build",
"author": "Kyle Muchmore <kmuchmor@gmail.com>",
"created": "2020-09-24 21:18:55.09417 +0000 UTC m=+90.125590001",
"frontenddir": "frontend",
"serve": "npm run serve",
"bridge": "src",
"wailsdir": "",
"platforms": ["linux", "darwin"]
}

View File

@@ -11,7 +11,7 @@
"core-js": "^3.6.4", "core-js": "^3.6.4",
"regenerator-runtime": "^0.13.3", "regenerator-runtime": "^0.13.3",
"vue": "^2.6.11", "vue": "^2.6.11",
"vuetify": "^2.3.15", "vuetify": "^2.2.15",
"@wailsapp/runtime": "^1.0.10" "@wailsapp/runtime": "^1.0.10"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -24,13 +24,13 @@
<v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon> <v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-toolbar-title>Application</v-toolbar-title> <v-toolbar-title>Application</v-toolbar-title>
</v-app-bar> </v-app-bar>
<v-main> <v-content>
<v-container fluid class="px-0"> <v-container fluid class="px-0">
<v-layout justify-center align-center class="px-0"> <v-layout justify-center align-center class="px-0">
<hello-world></hello-world> <hello-world></hello-world>
</v-layout> </v-layout>
</v-container> </v-container>
</v-main> </v-content>
<v-footer app fixed> <v-footer app fixed>
<span style="margin-left:1em">&copy; You</span> <span style="margin-left:1em">&copy; You</span>
</v-footer> </v-footer>
@@ -57,4 +57,4 @@
.logo { .logo {
width: 16em; width: 16em;
} }
</style> </style>

View File

@@ -1,4 +1,4 @@
package cmd package cmd
// Version - Wails version // Version - Wails version
const Version = "v1.8.1-pre4" const Version = "v1.7.2-pre5"

View File

@@ -26,12 +26,10 @@ func init() {
var packageApp = false var packageApp = false
var forceRebuild = false var forceRebuild = false
var debugMode = false var debugMode = false
var gopath = ""
var typescriptFilename = "" var typescriptFilename = ""
var verbose = false var verbose = false
var platform = "" var platform = ""
var ldflags = "" var ldflags = ""
var tags = ""
buildSpinner := spinner.NewSpinner() buildSpinner := spinner.NewSpinner()
buildSpinner.SetSpinSpeed(50) buildSpinner.SetSpinSpeed(50)
@@ -44,9 +42,7 @@ func init() {
BoolFlag("d", "Build in Debug mode", &debugMode). BoolFlag("d", "Build in Debug mode", &debugMode).
BoolFlag("verbose", "Verbose output", &verbose). BoolFlag("verbose", "Verbose output", &verbose).
StringFlag("t", "Generate Typescript definitions to given file (at runtime)", &typescriptFilename). StringFlag("t", "Generate Typescript definitions to given file (at runtime)", &typescriptFilename).
StringFlag("ldflags", "Extra options for -ldflags", &ldflags). StringFlag("ldflags", "Extra options for -ldflags", &ldflags)
StringFlag("gopath", "Specify your GOPATH location. Mounted to /go during cross-compilation.", &gopath).
StringFlag("tags", "Build tags to pass to the go compiler (quoted and space separated)", &tags)
var b strings.Builder var b strings.Builder
for _, plat := range getSupportedPlatforms() { for _, plat := range getSupportedPlatforms() {
@@ -80,11 +76,6 @@ func init() {
return fmt.Errorf("Unable to find 'project.json'. Please check you are in a Wails project directory") return fmt.Errorf("Unable to find 'project.json'. Please check you are in a Wails project directory")
} }
// Check that this platform is supported
if !projectOptions.PlatformSupported() {
logger.Yellow("WARNING: This project is unsupported on %s - it probably won't work!\n Valid platforms: %s\n", runtime.GOOS, strings.Join(projectOptions.Platforms, ", "))
}
// Set cross-compile // Set cross-compile
projectOptions.Platform = runtime.GOOS projectOptions.Platform = runtime.GOOS
if len(platform) > 0 { if len(platform) > 0 {
@@ -106,10 +97,6 @@ func init() {
// Add ldflags // Add ldflags
projectOptions.LdFlags = ldflags projectOptions.LdFlags = ldflags
projectOptions.GoPath = gopath
// Add tags
projectOptions.Tags = tags
// Validate config // Validate config
// Check if we have a frontend // Check if we have a frontend
@@ -194,10 +181,6 @@ func init() {
return err return err
} }
if projectOptions.Platform == "windows" {
logger.Yellow("*** Please note: Windows builds use mshtml which is only compatible with IE11. For more information, please read https://wails.app/guides/windows/ ***")
}
logger.Yellow("Awesome! Project '%s' built!", projectOptions.Name) logger.Yellow("Awesome! Project '%s' built!", projectOptions.Name)
return nil return nil

View File

@@ -70,7 +70,6 @@ func init() {
} }
logger.Yellow("Awesome! Project '%s' built!", projectOptions.Name) logger.Yellow("Awesome! Project '%s' built!", projectOptions.Name)
return cmd.ServeProject(projectOptions, logger) return cmd.ServeProject(projectOptions, logger)
}) })
} }

View File

@@ -1431,13 +1431,6 @@ struct webview_priv
style = WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU; style = WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU;
} }
// Scale
// Credit: https://github.com/webview/webview/issues/54#issuecomment-379528243
HDC hDC = GetDC(NULL);
w->width = GetDeviceCaps(hDC, 88)*w->width/96.0;
w->height = GetDeviceCaps(hDC, 90)*w->height/96.0;
ReleaseDC(NULL, hDC);
rect.left = 0; rect.left = 0;
rect.top = 0; rect.top = 0;
rect.right = w->width; rect.right = w->width;
@@ -2042,14 +2035,6 @@ struct webview_priv
objc_setAssociatedObject(w->priv.delegate, "webview", (id)(w), objc_setAssociatedObject(w->priv.delegate, "webview", (id)(w),
OBJC_ASSOCIATION_ASSIGN); OBJC_ASSOCIATION_ASSIGN);
CGFloat scale = [[NSScreen mainScreen] backingScaleFactor];
printf("Scale is: %f\n", scale);
if( scale != 1.0f ) {
w->width = w->width / scale;
w->height = w->height / scale;
}
NSRect r = NSMakeRect(0, 0, w->width, w->height); NSRect r = NSMakeRect(0, 0, w->width, w->height);
NSUInteger style = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSUInteger style = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
NSWindowStyleMaskMiniaturizable; NSWindowStyleMaskMiniaturizable;
@@ -2106,7 +2091,6 @@ struct webview_priv
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
w->priv.webview.frameLoadDelegate = w->priv.delegate; w->priv.webview.frameLoadDelegate = w->priv.delegate;
w->priv.webview.UIDelegate = w->priv.delegate; w->priv.webview.UIDelegate = w->priv.delegate;
[w->priv.webview.scrollView setZoomScale:1.0/scale animated:NO];
[[w->priv.window contentView] addSubview:w->priv.webview]; [[w->priv.window contentView] addSubview:w->priv.webview];
[w->priv.window orderFrontRegardless]; [w->priv.window orderFrontRegardless];

View File

@@ -1,6 +1,6 @@
{ {
"name": "@wailsapp/runtime", "name": "@wailsapp/runtime",
"version": "1.1.1", "version": "1.1.0",
"description": "Wails Javascript runtime library", "description": "Wails Javascript runtime library",
"main": "main.js", "main": "main.js",
"types": "runtime.d.ts", "types": "runtime.d.ts",

View File

@@ -45,7 +45,7 @@ type Store struct {
data reflect.Value data reflect.Value
dataType reflect.Type dataType reflect.Type
eventPrefix string eventPrefix string
callbacks []reflect.Value callbacks []func(interface{})
runtime *Runtime runtime *Runtime
notifySynchronously bool notifySynchronously bool
@@ -143,13 +143,10 @@ func (s *Store) notify() {
// Execute callbacks // Execute callbacks
for _, callback := range s.callbacks { for _, callback := range s.callbacks {
// Build args
args := []reflect.Value{s.data}
if s.notifySynchronously { if s.notifySynchronously {
callback.Call(args) callback(s.data)
} else { } else {
go callback.Call(args) go callback(s.data)
} }
} }
@@ -187,50 +184,11 @@ func (s *Store) Set(data interface{}) error {
return nil return nil
} }
// callbackCheck ensures the given function to Subscribe() is
// of the correct signature. Absolutely cannot wait for
// generics to land rather than writing this nonsense.
func (s *Store) callbackCheck(callback interface{}) error {
// Get type
callbackType := reflect.TypeOf(callback)
// Check callback is a function
if callbackType.Kind() != reflect.Func {
return fmt.Errorf("invalid value given to store.Subscribe(). Expected 'func(%s)'", s.dataType.String())
}
// Check input param
if callbackType.NumIn() != 1 {
return fmt.Errorf("invalid number of parameters given in callback function. Expected 1")
}
// Check input data type
if callbackType.In(0) != s.dataType {
return fmt.Errorf("invalid type for input parameter given in callback function. Expected %s, got %s", s.dataType.String(), callbackType.In(0))
}
// Check output param
if callbackType.NumOut() != 0 {
return fmt.Errorf("invalid number of return parameters given in callback function. Expected 0")
}
return nil
}
// Subscribe will subscribe to updates to the store by // Subscribe will subscribe to updates to the store by
// providing a callback. Any updates to the store are sent // providing a callback. Any updates to the store are sent
// to the callback // to the callback
func (s *Store) Subscribe(callback interface{}) { func (s *Store) Subscribe(callback func(interface{})) {
s.callbacks = append(s.callbacks, callback)
err := s.callbackCheck(callback)
if err != nil {
log.Fatal(err)
}
callbackFunc := reflect.ValueOf(callback)
s.callbacks = append(s.callbacks, callbackFunc)
} }
// updaterCheck ensures the given function to Update() is // updaterCheck ensures the given function to Update() is
@@ -286,13 +244,5 @@ func (s *Store) Update(updater interface{}) {
results := reflect.ValueOf(updater).Call(args) results := reflect.ValueOf(updater).Call(args)
// We will only have 1 result. Set the store to it // We will only have 1 result. Set the store to it
err = s.Set(results[0].Interface()) s.Set(results[0].Interface())
if err != nil && s.errorHandler != nil {
s.errorHandler(err)
}
}
// Get returns the value of the data that's kept in the current state / Store
func (s *Store) Get() interface{} {
return s.data.Interface()
} }