chore: improve contributor experience (#1264)

* chore: update install commands in setup scripts

* chore(examples/api): add `tauri` script

* chore(contributing.md): update to match new developments

* fix(scripts/setup): typo

* chore(examples): replace communication with helloworld

* remove deno submodule as it was added on accident

* fix(examples/helloword): add __tauri.js to .gitignore

* fix(examples): helloworld example with `cargo run`, change dev path

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
Noah Klayman
2021-02-21 08:48:08 -08:00
committed by GitHub
parent b29c0685bc
commit 1d66d00506
54 changed files with 578 additions and 5676 deletions

View File

@@ -1,19 +1,16 @@
# Tauri Contributing Guide
Hi! We, the maintainers, are really excited that you are interested in contributing to Tauri. Before submitting your contribution though, please make sure to take a moment and read through the following guidelines.
Hi! We, the maintainers, are really excited that you are interested in contributing to Tauri. Before submitting your contribution though, please make sure to take a moment and read through the [Code of Conduct](CODE_OF_CONDUCT.md), as well as the appropriate section for the contribution you intend to make:
- [Code of Conduct](CODE_OF_CONDUCT.md)
- [Issue Reporting Guidelines](#issue-reporting-guidelines)
- [Pull Request Guidelines](#pull-request-guidelines)
- [Development Guide](#development-guide)
- [Project Structure](#project-structure)
- [Financial Contribution](#financial-contribution)
## Issue Reporting Guidelines
- The issue list of this repo is **exclusively** for bug reports and feature requests. Non-conforming issues will be closed immediately.
- For simple beginner questions, you can get quick answers from the [Tauri Discord chat](https://discord.gg/SpmNs4S).
- If you have a question, you can get quick answers from the [Tauri Discord chat](https://discord.gg/SpmNs4S).
- Try to search for your issue, it may have already been answered or even fixed in the development branch (`dev`).
@@ -31,12 +28,6 @@ Hi! We, the maintainers, are really excited that you are interested in contribut
## Pull Request Guidelines
- The `latest` branch is basically just a snapshot of the latest stable release. All development should be done in dedicated branches. **Do not submit PRs against the `latest` branch.**
- Checkout a topic branch from the relevant branch, e.g. `dev`, and merge back against that branch.
- **DO NOT** checkin `dist` in the commits.
- It's OK to have multiple small commits as you work on the PR - we will let GitHub automatically squash it before merging.
- If adding new feature:
@@ -45,40 +36,54 @@ Hi! We, the maintainers, are really excited that you are interested in contribut
- If fixing a bug:
- If you are resolving a special issue, add `(fix: #xxxx[,#xxx])` (#xxxx is the issue id) in your PR title for a better release log, e.g. `fix: update entities encoding/decoding (fix #3899)`.
- Provide detailed description of the bug in the PR. Live demo preferred.
- Provide detailed description of the bug in the PR, or link to an issue that does.
## Development Guide
**NOTE: Tauri is undergoing rapid development right now, and the docs match the latest published version of Tauri. They are horribly out of date when compared with the code in the dev branch. This contributor guide is up-to-date, but it doesn't cover all of Tauri's functions in depth. If you have any questions, don't hesitate to ask in our Discord server.**
### General Setup
First, [join our Discord server](https://discord.gg/SpmNs4S) and let us know that you want to contribute. This way we can point you in the right direction and help ensure your contribution will be as helpful as possible. We also recommend you read the [technical details page](https://tauri.studio/en/docs/getting-started/technical-details) to learn how Tauri works under the hood and familiarize yourself with the codebase.
First, [join our Discord server](https://discord.gg/SpmNs4S) and let us know that you want to contribute. This way we can point you in the right direction and help ensure your contribution will be as helpful as possible.
To set up your machine for development, follow the [Tauri setup guide](https://tauri.studio/en/docs/getting-started/intro#setting-up-your-environment) to get all the tools you need to develop Tauri apps. The only additional tool you may need is [Yarn](https://yarnpkg.com/), it is only required if you are developing the Node CLI/API (`cli/tauri.js` and `api`). Next, clone the Tauri repo. It is structured as a monorepo, which means that all the various Tauri packages are under the same repository. The development process varies depending on what part of Tauri you are contributing to.
To set up your machine for development, follow the [Tauri setup guide](https://tauri.studio/en/docs/getting-started/intro#setting-up-your-environment) to get all the tools you need to develop Tauri apps. The only additional tool you may need is [Yarn](https://yarnpkg.com/), it is only required if you are developing the Node CLI/API (`cli/tauri.js` and `api`). Next, fork and clone this repo. It is structured as a monorepo, which means that all the various Tauri packages are under the same repository. The development process varies depending on what part of Tauri you are contributing to, see the guides below for per-package instructions.
To build all Tauri packages (`@tauri-apps/api`, `Core Rust CLI`, `@tauri-apps/cli`), use the `.scripts/setup.sh` (Linux and macOS) or `.scripts/setup.ps1` (Windows) scripts.
Some Tauri packages will be automatically built when running one of the examples. Others, however, will need to be built beforehand. To build these automatically, run the `.scripts/setup.sh` (Linux and macOS) or `.scripts/setup.ps1` (Windows) script. This will install the Rust and Node.js CLI and build the JS API. After that, you should be able to run all the examples.
### Developing The CLI and API (`tauri.js`)
### Packages Overview
The code for `tauri.js` is located in `[Tauri repo root]/cli/tauri.js`. Open a terminal, `cd` into that directory, and install deps by running `yarn install`. The code for the API (ie notifications, filesystem, etc...) is in `api-src` (not `src/api`), and the code for the CLI (the build, dev, init, etc... commands) is in `src`. There are a few package scripts you should be aware of:
- The JS API (`/api`) contains JS bindings to the builtin Rust functions in the Rust API.
- The Rust API (`/tauri-api`) contains the Rust functions used by the JS API.
- Tauri.js (`/cli/tauri.js`) is the primary CLI for creating and developing Tauri apps.
- The Rust CLI (`/cli/core`) is a new version of the CLI that will replace Tauri.js, but now it only supports build and dev commands. Tauri.js will automatically use the Rust CLI for these commands.
- Tauri Bundler (`/cli/tauri-bundler`) is used by the Rust CLI to package executables into installers.
- Tauri Core (`/tauri`) is the heart of Tauri. It contains the code that starts the app, configures communication between Rust and the Webview, and ties all the other packages together.
- The Macros (`/tauri-macros`) are used by Tauri Core for various functions.
- `build` builds both the API and CLI
- `build:api` builds the API
- `build:webpack` builds the CLI
### Developing The Node.js CLI (Tauri.js)
Tauri.js is a CLI tool that houses the `init`, `info`, `icon`, and `deps` command. It also handles the `build` and `dev` command by forwarding them to the Rust CLI, which will eventually replace this modules completely. The code for Tauri.js is located in `[Tauri repo root]/cli/tauri.js`. There are a few package scripts you should be aware of:
- `build` builds the CLI
- `test` runs the unit and e2e test suite
- `lint` runs ESLint to catch linting errors
- `format` formats code with Prettier to match the style guide
To test your changes, we recommend using the `[Tauri repo root]/tauri/examples/communication` app. It automatically uses the local version of `tauri.js`. You will need to rebuild `tauri.js` after every change by running `yarn build` in the `tauri.js` directory.
To test your changes, we recommend using the API example app, located in `[Tauri repo root]/tauri/examples/api`. Run `yarn install` to install deps, and then `yarn tauri [COMMAND]` to run a command using your local Tauri.js copy. You will need to rebuild Tauri.js after every change by running `yarn build` in the Tauri.js directory.
If you want to use your local code in another app, we recommend using [Yarn link](https://classic.yarnpkg.com/en/docs/cli/link/). First, run `yarn link` in the `tauri.js` directory, then run `yarn link tauri` in your test project's directory. This will link the CLI and API for that project. To run CLI commands, use `yarn tauri [command name]`, ie `yarn tauri build`. You only need to link once, but will need to rebuild every time.
If you want to use your local copy of Tauri.js in another app, we recommend using [Yarn link](https://classic.yarnpkg.com/en/docs/cli/link/). First, make sure you have don't have Tauri.js installed globally by running `npm uninstall -g tauri && yarn global remove tauri`. Then, run `yarn link` in the Tauri.js directory (note that the setup script will do this for you, so you can skip this step if you ran that). Now, you can just run `tauri [COMMAND]` anywhere, and your local copy will be used.
### Developing Tauri Bundler
### Developing Tauri Bundler and Rust CLI
The code for the bundler is located in `[Tauri repo root]/cli/tauri-bundler`. Build the Tauri CLI on `[Tauri repo root]/cli/core` with `$ cargo build`. This is handled automatically when using the JS CLI.
The code for the bundler is located in `[Tauri repo root]/cli/tauri-bundler`, and the code for the Rust CLI is located in `[Tauri repo root]/cli/core`. If you are using your local copy of Tauri.js (see above), any changes you make to the bundler and CLI will be automatically built and applied when running the build or dev command. Otherwise, running `cargo install --path .` in the Rust CLI directory will allow you to run `cargo tauri build` and `cargo tauri dev` anywhere, using the updated copy of the bundler and cli. You will have to run this command each time you make a change in either package.
### Developing Tauri Core
### Developing Tauri Core and Related Components (Rust API, Macros, and Utils)
The code for Tauri core is located in `[Tauri repo root]/tauri`. The easiest way to test your changes is to use the `[Tauri repo root]/tauri/examples/communication` app. It automatically rebuilds and uses your local codebase. Just run `yarn tauri build` or `yarn tauri dev` in the communication app directory after making changes to test them out. To use your local changes in another project, edit its `src-tauri/Cargo.toml` file so that the `tauri` key looks like `tauri = { path = "PATH", features = [ "api-all", "cli" ] }`, where `PATH` is the relative path to `[Tauri repo root]/tauri`.
The code for Tauri Core is located in `[Tauri repo root]/tauri`, and the Rust API, Macros, and Utils are in `[Tauri repo root]/tauri-(api/macros/utils)`. The easiest way to test your changes is to use the `[Tauri repo root]/tauri/examples/helloworld` app. It automatically rebuilds and uses your local copy of the Tauri core packages. Just run `yarn tauri build` or `yarn tauri dev` in the helloworld app directory after making changes to test them out. To use your local changes in another project, edit its `src-tauri/Cargo.toml` file so that the `tauri` key looks like `tauri = { path = "PATH", features = [ "api-all", "cli" ] }`, where `PATH` is the relative path to `[Tauri repo root]/tauri`. Then, your local copy of the Tauri core packages will be rebuilt and used whenever you build that project.
### Developing the JS API
The JS API provides bindings between the developer's JS in the Webview and the builtin Tauri APIs, written in Rust. Its code is located in `[Tauri repo root]/api`. After making changes to the code, run `yarn build` to build it. To test your changes, we recommend using the API example app, located in `[Tauri repo root]/tauri/examples/api`. It will automatically use your local copy of the JS API and provides a helpful UI to test the various commands.
## Financial Contribution

View File

@@ -4,25 +4,25 @@ on:
workflow_dispatch:
inputs:
repository:
description: 'Repository from which to pull and create a Tauri app.'
description: "Repository from which to pull and create a Tauri app."
required: false
default: 'tauri-apps/tauri'
default: "tauri-apps/tauri"
ref:
description: 'Branch or ref to pull down.'
description: "Branch or ref to pull down."
required: false
default: 'dev'
default: "dev"
dir:
description: 'Directory we expect to run in.'
description: "Directory we expect to run in."
required: false
default: 'tauri/examples/communication'
default: "tauri/examples/helloworld"
buildAssets:
description: 'Command to build the assets.'
description: "Command to build the assets."
required: false
default: 'echo no build needed'
default: "echo no build needed"
buildTauri:
description: 'Command to build the Tauri app.'
description: "Command to build the Tauri app."
required: false
default: 'tauri'
default: "tauri"
env:
RUST_BACKTRACE: 1
@@ -76,7 +76,7 @@ jobs:
yarn global add $PWD
echo "::add-path::$(yarn global bin)"
- name: install and build assets
working-directory: 'example/${{ github.event.inputs.dir }}'
working-directory: "example/${{ github.event.inputs.dir }}"
run: ${{ github.event.inputs.buildAssets }}
- name: build tauri app
uses: tauri-apps/tauri-action@v0
@@ -84,7 +84,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
includeDebug: true
projectPath: 'example/${{ github.event.inputs.dir }}'
projectPath: "example/${{ github.event.inputs.dir }}"
preferGlobal: true
- uses: actions/upload-artifact@v2
if: success()

View File

@@ -4,27 +4,22 @@ cd api
yarn; yarn build
cd ..
echo "Building the Tauri CLI..."
echo "Installing the Tauri Rust CLI..."
cd cli\core
cargo build --release
cargo install --path .
cd ..\..
Set-Alias rtauri "$(pwd)\cli\core\target\release\cargo-tauri.exe"
echo "Added alias 'rtauri' for '$(pwd)\cli\core\target\release\cargo-tauri.exe'"
echo "Tauri CLI installed. Run it with '$ rtauri tauri [COMMAND]'."
echo "Tauri Rust CLI installed. Run it with '$ cargo tauri [COMMAND]'."
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes"
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No"
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice("Node.js CLI", "Do you want to use the Node.js CLI?", $options, 1)
$result = $host.ui.PromptForChoice("Node.js CLI", "Do you want to install the Node.js CLI?", $options, 1)
switch ($result) {
0{
cd cli\tauri.js
yarn; yarn build
yarn; yarn build; yarn link
cd ..\..
Set-Alias stauri "$(pwd)\cli\tauri.js\bin\tauri.js"
echo "Added alias 'stauri' for '$(pwd)\cli\tauri.js\bin\tauri.js'"
echo "Tauri Node.js CLI installed. Run it with '$ stauri [COMMAND]'"
echo "Tauri Node.js CLI installed. Run it with '$ tauri [COMMAND]'"
}
}

View File

@@ -4,25 +4,20 @@ cd api
yarn && yarn build
cd ..
echo "Building the Tauri CLI..."
echo "Building the Tauri Rust CLI..."
cd cli/core
cargo build --release
cargo install --path .
cd ../..
echo "Tauri Rust CLI installed. Run it with '$ cargo tauri [COMMAND]'."
alias rtauri="$(pwd)/cli/core/target/release/cargo-tauri.exe tauri"
echo "Added alias 'rtauri' for '$(pwd)/cli/core/target/release/cargo-tauri.exe tauri'"
echo "Tauri CLI installed. Run it with '$ rtauri [COMMAND]'."
echo "Do you want to use the Node.js CLI?"
echo "Do you want to install the Node.js CLI?"
select yn in "Yes" "No"; do
case $yn in
Yes )
cd cli/tauri.js
yarn && yarn build
yarn && yarn build && yarn link
cd ../..
alias stauri="$(pwd)/cli/tauri.js/bin/tauri.js"
echo "Added alias 'stauri' for '$(pwd)/cli/tauri.js/bin/tauri.js'"
echo "Tauri Node.js CLI installed. Run it with '$ stauri [COMMAND]'"
echo "Tauri Node.js CLI installed. Run it with '$ tauri [COMMAND]'."
break;;
No ) break;;
esac

View File

@@ -94,7 +94,7 @@ if ($example_path -eq $null) {
$example_path = Get-ChildItem examples\*\*\*\$env:example\$env:example
}
# if the example path is still null get the communication example path.
# if the example path is still null get the helloworld example path.
if ($example_path -eq $null) {
$example_path = Get-ChildItem examples\tauri\*\$env:example
}
@@ -109,9 +109,9 @@ switch ($example_path.parent) {
"yew" {
cd $example_path.FullName; cargo web deploy
}
# if tauri run the communication example from the tauri folder.
# if tauri run the helloworld example from the tauri folder.
"tauri" {
cd $CWD/tauri/examples/communication/src-tauri; cargo run
cd $CWD/tauri/examples/helloworld/src-tauri; cargo run
}
# transpiled are not supported yet.
"transpiled" {
@@ -140,8 +140,8 @@ Push-Location $MyInvocation.MyCommand.Path
# initialize the examples list.
$examples = @()
# get the communication example
$examples += Get-ChildItem examples/*/* -Filter communication
# get the helloworld example
$examples += Get-ChildItem examples/*/* -Filter helloworld
# get the rest of the examples.
$examples += Get-ChildItem examples/*/* -Directory -Exclude ('src*', 'public', 'test*', 'source', 'lib', 'web', 'dist', 'node_*')

View File

@@ -92,8 +92,8 @@ notification-all = [ "tauri-api/notification" ]
global-shortcut-all = [ "tauri-api/global-shortcut" ]
[[example]]
name = "communication"
path = "examples/communication/src-tauri/src/main.rs"
name = "helloworld"
path = "examples/helloworld/src-tauri/src/main.rs"
[[example]]
name = "multiwindow"

View File

@@ -5,7 +5,7 @@
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "sirv public",
"tauri:build": "node ../../../cli/tauri.js/bin/tauri build"
"tauri": "node ../../../cli/tauri.js/bin/tauri"
},
"devDependencies": {
"@rollup/plugin-commonjs": "17.1.0",

View File

@@ -7,7 +7,7 @@
},
"tauri": {
"cli": {
"description": "Tauri communication example",
"description": "Tauri API example",
"args": [
{
"short": "c",
@@ -44,7 +44,7 @@
},
"bundle": {
"active": true,
"identifier": "com.tauri.communication",
"identifier": "com.tauri.api",
"icon": [
"icons/32x32.png",
"icons/128x128.png",

View File

@@ -1,27 +0,0 @@
# Communication example
This example demonstrates Tauri's API capabilities. It's used as the main validation app, serving as the testbed of our development process.
In the future, this app will be used on Tauri's integration tests.
![App screenshot](./screenshot.png?raw=true)
## Running the example
- Install dependencies
```bash
# with yarn
$ yarn
# with npm
$ npm install
```
- Compile the app
```bash
# with yarn
$ yarn build
# with npm
$ npm run build
```
- Run the app
```bash
$ ./src-tauri/target/release/app
```

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +0,0 @@
document.getElementById("cli-matches").addEventListener("click", function () {
window.__TAURI__.cli
.getMatches()
.then(registerResponse)
.catch(registerResponse);
});

View File

@@ -1,26 +0,0 @@
document.getElementById("log").addEventListener("click", function () {
console.log("log");
window.__TAURI__.tauri.invoke({
cmd: "logOperation",
event: "tauri-click",
payload: "this payload is optional because we used Option in Rust",
});
});
document.getElementById("request").addEventListener("click", function () {
window.__TAURI__.tauri
.invoke({
cmd: "performRequest",
endpoint: "dummy endpoint arg",
body: {
id: 5,
name: "test",
},
})
.then(registerResponse)
.catch(registerResponse);
});
document.getElementById("event").addEventListener("click", function () {
window.__TAURI__.event.emit("js-event", "this is the payload string");
});

View File

@@ -1,56 +0,0 @@
var defaultPathInput = document.getElementById("dialog-default-path");
var filterInput = document.getElementById("dialog-filter");
var multipleInput = document.getElementById("dialog-multiple");
var directoryInput = document.getElementById("dialog-directory");
document.getElementById("open-dialog").addEventListener("click", function () {
window.__TAURI__.dialog
.open({
defaultPath: defaultPathInput.value || null,
filters: filterInput.value ? [{
name: 'Tauri Example',
extensions: filterInput.value.split(',').map(f => f.trim())
}] : [],
multiple: multipleInput.checked,
directory: directoryInput.checked,
})
.then(function (res) {
if (Array.isArray(res)) {
registerResponse(res);
} else {
var pathToRead = res;
var isFile = pathToRead.match(/\S+\.\S+$/g);
window.__TAURI__.fs
.readBinaryFile(pathToRead)
.then(function (response) {
if (isFile) {
if (pathToRead.includes(".png") || pathToRead.includes(".jpg")) {
arrayBufferToBase64(new Uint8Array(response), function (base64) {
var src = "data:image/png;base64," + base64;
registerResponse('<img src="' + src + '"></img>');
});
} else {
registerResponse(res);
}
} else {
registerResponse(res);
}
})
.catch(registerResponse(res));
}
})
.catch(registerResponse);
});
document.getElementById("save-dialog").addEventListener("click", function () {
window.__TAURI__.dialog
.save({
defaultPath: defaultPathInput.value || null,
filters: filterInput.value ? [{
name: 'Tauri Example',
extensions: filterInput.value.split(',').map(f => f.trim())
}] : [],
})
.then(registerResponse)
.catch(registerResponse);
});

View File

@@ -1,66 +0,0 @@
var dirSelect = document.getElementById("dir");
function getDir() {
return dirSelect.value ? parseInt(dir.value) : null;
}
function arrayBufferToBase64(buffer, callback) {
var blob = new Blob([buffer], {
type: "application/octet-binary",
});
var reader = new FileReader();
reader.onload = function (evt) {
var dataurl = evt.target.result;
callback(dataurl.substr(dataurl.indexOf(",") + 1));
};
reader.readAsDataURL(blob);
}
var pathInput = document.getElementById("path-to-read");
addClickEnterHandler(document.getElementById("read"), pathInput, function () {
var pathToRead = pathInput.value;
var isFile = pathToRead.match(/\S+\.\S+$/g);
var opts = {
dir: getDir(),
};
var promise = isFile
? window.__TAURI__.fs.readBinaryFile(pathToRead, opts)
: window.__TAURI__.fs.readDir(pathToRead, opts);
promise
.then(function (response) {
if (isFile) {
if (pathToRead.includes(".png") || pathToRead.includes(".jpg")) {
arrayBufferToBase64(new Uint8Array(response), function (base64) {
var src = "data:image/png;base64," + base64;
registerResponse('<img src="' + src + '"></img>');
});
} else {
var value = String.fromCharCode.apply(null, response);
registerResponse(
'<textarea id="file-response" style="height: 400px"></textarea><button id="file-save">Save</button>'
);
var fileInput = document.getElementById("file-response");
fileInput.value = value;
document
.getElementById("file-save")
.addEventListener("click", function () {
window.__TAURI__.fs
.writeFile(
{
file: pathToRead,
contents: fileInput.value,
},
{
dir: getDir(),
}
)
.catch(registerResponse);
});
}
} else {
registerResponse(response);
}
})
.catch(registerResponse);
});

View File

@@ -1,33 +0,0 @@
const methodSelect = document.getElementById("request-method");
const requestUrlInput = document.getElementById("request-url");
const requestBodyInput = document.getElementById("request-body");
let client
window.__TAURI__.http.getClient().then(function (c) {
client = c
})
document.getElementById("make-request").addEventListener("click", function () {
const method = methodSelect.value || "GET";
const url = requestUrlInput.value || "";
const options = {
url: url,
method: method,
};
let httpBody = requestBodyInput.value || "";
if (
(httpBody.startsWith("{") && httpBody.endsWith("}")) ||
(httpBody.startsWith("[") && httpBody.endsWith("]"))
) {
options.body = window.__TAURI__.http.Body.json(JSON.parse(httpBody));
} else if (httpBody !== '') {
options.body = window.__TAURI__.http.Body.text(httpBody)
}
client
.request(options)
.then(registerResponse)
.catch(registerResponse);
});

View File

@@ -1,330 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<style>
* {
font-family: Arial, Helvetica, sans-serif;
}
body {
background: #889;
}
.logo-container {
width: 95%;
margin: 0px auto;
overflow: hidden;
}
.logo-link {
font-weight: 700;
position: absolute;
top: 150px;
right: 10px;
}
.logo {
width: 32px;
height: 32px;
cursor: pointer;
position: fixed;
z-index: 10;
top: 7px;
right: 10px;
}
#response {
position: absolute;
left: 10px;
right: 10px;
top: 440px;
min-height: 110px;
background: #aab;
font-family: "Courier New", Courier, monospace;
font-size: 12px;
word-wrap: break-word;
padding: 5px;
border-radius: 5px;
overflow-y: auto;
}
input,
select {
background: white;
font-family: system-ui, sans-serif;
border: 0;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.2;
padding: 0.25rem 0.5rem;
margin: 0.25rem;
}
button:hover,
button:focus {
background: #0053ba;
}
button:focus {
outline: 1px solid #fff;
outline-offset: -4px;
}
button:active {
transform: scale(0.99);
}
.button {
border: 0;
border-radius: 0.25rem;
background: #1e88e5;
color: white;
font-family: system-ui, sans-serif;
font-size: 1rem;
line-height: 1.2;
white-space: nowrap;
text-decoration: none;
padding: 0.25rem 0.5rem;
margin: 0.25rem;
cursor: pointer;
}
.bottom {
position: fixed;
bottom: 0;
left: 0;
text-align: center;
width: 100%;
padding: 5px;
background: #333;
color: #eef;
}
.dark-link {
color: white;
text-decoration: none !important;
}
.tabs-container {
position: fixed;
height: 400px;
top: 20px;
left: 10px;
right: 10px;
z-index: 9;
}
.tabs {
position: relative;
min-height: 400px;
clear: both;
}
.tab {
float: left;
}
.tab > label {
background: #eee;
padding: 10px;
border: 1px solid transparent;
margin-left: -1px;
position: relative;
left: 1px;
}
.tabs > .tabber {
border-top-left-radius: 5px;
}
.tabs > .tabber ~ .tabber {
border-top-left-radius: none;
}
.tab [type="radio"] {
display: none;
}
.content {
position: absolute;
top: 28px;
left: 0;
background: #bbc;
right: 0;
bottom: 0;
padding: 20px;
border: 1px solid transparent;
border-top-right-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
[type="radio"]:checked ~ label {
background: #bbc;
border-bottom: 1px solid transparent;
z-index: 2;
}
[type="radio"]:checked ~ label ~ .content {
z-index: 1;
}
</style>
</head>
<body>
<div class="logo-container">
<img src="icon.png" class="logo" />
</div>
<div class="tabs-container">
<div class="tabs">
<div class="tab">
<input type="radio" id="tab-1" name="tab-group-1" checked />
<label class="tabber" for="tab-1">Messages</label>
<div class="content">
<button class="button" id="log">Call Log API</button>
<button class="button" id="request">
Call Request (async) API
</button>
<button class="button" id="event">Send event to Rust</button>
<button class="button" id="notification">
Send test notification
</button>
<div style="margin-top: 24px">
<input id="title" value="Awesome Tauri Example!" />
<button class="button" id="set-title">Set title</button>
</div>
</div>
</div>
<div class="tab">
<input type="radio" id="tab-2" name="tab-group-1" />
<label class="tabber" for="tab-2">File System</label>
<div class="content">
<div style="margin-top: 24px">
<select class="button" id="dir">
<option value="">None</option>
</select>
<input id="path-to-read" placeholder="Type the path to read..." />
<button class="button" id="read">Read</button>
</div>
<div style="margin-top: 24px">
<input id="dialog-default-path" placeholder="Default path" />
<input id="dialog-filter" placeholder="Extensions filter" />
<div>
<input type="checkbox" id="dialog-multiple" />
<label>Multiple</label>
</div>
<div>
<input type="checkbox" id="dialog-directory" />
<label>Directory</label>
</div>
<button class="button" id="open-dialog">Open dialog</button>
<button class="button" id="save-dialog">Open save dialog</button>
</div>
</div>
</div>
<div class="tab">
<input type="radio" id="tab-3" name="tab-group-1" />
<label class="tabber" for="tab-3">Communication</label>
<div class="content">
<div style="margin-top: 24px">
<input id="url" value="https://tauri.studio" />
<button class="button" id="open-url">Open URL</button>
</div>
<div style="margin-top: 24px">
<select class="button" id="request-method">
<option value="GET">GET</option>
<option value="POST">POST</option>
<option value="PUT">PUT</option>
<option value="PATCH">PATCH</option>
<option value="DELETE">DELETE</option>
</select>
<input id="request-url" placeholder="Type the request URL..." />
<br />
<textarea
id="request-body"
placeholder="Request body"
rows="5"
style="width: 100%; margin-right: 10px; font-size: 12px"
></textarea>
<br />
<button class="button" id="make-request">Make request</button>
</div>
</div>
</div>
<div class="tab">
<input type="radio" id="tab-4" name="tab-group-1" />
<label class="tabber" for="tab-4">CLI</label>
<div class="content">
<div style="margin-top: 24px">
<button class="button" id="cli-matches">Get matches</button>
</div>
</div>
</div>
</div>
</div>
<div id="response"></div>
<div class="bottom">
<a class="dark-link" target="_blank" href="https://tauri.studio"
>Tauri Documentation</a
>&nbsp;&nbsp;&nbsp;
<a
class="dark-link"
target="_blank"
href="https://github.com/tauri-apps/tauri"
>Github Repo</a
>&nbsp;&nbsp;&nbsp;
<a
class="dark-link"
target="_blank"
href="https://github.com/tauri-apps/tauri/tree/dev/tauri/examples/communication"
>Source for this App</a
>
</div>
<script>
function registerResponse(response) {
document.getElementById("response").innerHTML =
typeof response === "object" ? JSON.stringify(response) : response;
}
function addClickEnterHandler(button, input, handler) {
button.addEventListener("click", handler);
input.addEventListener("keyup", function (e) {
if (e.keyCode === 13) {
handler();
}
});
}
window.__TAURI__.event.listen("rust-event", function (res) {
document.getElementById("response").innerHTML = JSON.stringify(res);
});
document.querySelector(".logo").addEventListener("click", function () {
window.__TAURI__.shell.open("https://tauri.studio/");
});
var dirSelect = document.getElementById("dir");
for (var key in window.__TAURI__.fs.Dir) {
if (isNaN(parseInt(key))) {
var value = window.__TAURI__.fs.Dir[key];
var opt = document.createElement("option");
opt.value = value;
opt.innerHTML = key;
dirSelect.appendChild(opt);
}
}
</script>
<script src="communication.js"></script>
<script src="fs.js"></script>
<script src="window.js"></script>
<script src="dialog.js"></script>
<script src="http.js"></script>
<script src="cli.js"></script>
<script src="notification.js"></script>
</body>
</html>

View File

@@ -1,23 +0,0 @@
function sendNotification() {
new Notification("Notification title", {
body: "This is the notification body",
});
}
document.getElementById("notification").addEventListener("click", function () {
if (Notification.permission === "default") {
Notification.requestPermission()
.then(function (response) {
if (response === "granted") {
sendNotification();
} else {
registerResponse("Permission is " + response);
}
})
.catch(registerResponse);
} else if (Notification.permission === "granted") {
sendNotification();
} else {
registerResponse("Permission is denied");
}
});

View File

@@ -1,19 +0,0 @@
var urlInput = document.getElementById("url");
addClickEnterHandler(
document.getElementById("open-url"),
urlInput,
function () {
window.__TAURI__.shell.open(urlInput.value);
}
);
var titleInput = document.getElementById("title");
addClickEnterHandler(
document.getElementById("set-title"),
titleInput,
function () {
window.__TAURI__.window.manager.setTitle(titleInput.value);
}
);

View File

@@ -1,11 +0,0 @@
{
"name": "communication-example",
"version": "1.0.0",
"description": "A Tauri example showcasing the JS-Rust communication",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "node ../../../cli/tauri.js/bin/tauri build"
},
"private": true
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

View File

@@ -1,20 +0,0 @@
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct RequestBody {
id: i32,
name: String,
}
#[derive(Deserialize)]
#[serde(tag = "cmd", rename_all = "camelCase")]
pub enum Cmd {
LogOperation {
event: String,
payload: Option<String>,
},
PerformRequest {
endpoint: String,
body: RequestBody,
},
}

View File

@@ -1,54 +0,0 @@
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
mod cmd;
use serde::Serialize;
#[derive(Serialize)]
struct Reply {
data: String,
}
#[derive(tauri::FromTauriContext)]
#[config_path = "examples/communication/src-tauri/tauri.conf.json"]
struct Context;
fn main() {
tauri::AppBuilder::<tauri::flavors::Wry, Context>::new()
.setup(|webview_manager| async move {
let dispatcher = webview_manager.current_webview().await.unwrap();
let dispatcher_ = dispatcher.clone();
dispatcher.listen("js-event", move |msg| {
println!("got js-event with message '{:?}'", msg);
let reply = Reply {
data: "something else".to_string(),
};
dispatcher_
.emit("rust-event", Some(reply))
.expect("failed to emit");
});
})
.invoke_handler(|_webview_manager, arg| async move {
use cmd::Cmd::*;
match serde_json::from_str(&arg) {
Err(e) => Err(e.into()),
Ok(command) => match command {
LogOperation { event, payload } => {
println!("{} {:?}", event, payload);
Ok(().into())
}
PerformRequest { endpoint, body } => {
println!("{} {:?}", endpoint, body);
Ok("message response".into())
}
},
}
})
.build()
.unwrap()
.run();
}

View File

@@ -1,67 +0,0 @@
{
"build": {
"distDir": "../dist",
"devPath": "http://localhost:4000",
"withGlobalTauri": true
},
"ctx": {},
"tauri": {
"cli": {
"description": "Tauri communication example",
"args": [
{
"short": "c",
"name": "config",
"takesValue": true,
"description": "Config path"
},
{
"short": "t",
"name": "theme",
"takesValue": true,
"description": "App theme",
"possibleValues": ["light", "dark", "system"]
},
{
"short": "v",
"name": "verbose",
"multipleOccurrences": true,
"description": "Verbosity level"
}
],
"subcommands": {
"update": {
"description": "Updates the app",
"args": [
{
"short": "b",
"name": "background",
"description": "Update in background"
}
]
}
}
},
"bundle": {
"active": true,
"identifier": "com.tauri.communication",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
},
"allowlist": {
"all": true
},
"windows": [{
"title": "Tauri API Validation",
"resizable": true
}],
"security": {
"csp": "default-src blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline'"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
{
"name": "hello-world",
"version": "1.0.0",
"scripts": {
"tauri": "node ../../../cli/tauri.js/bin/tauri"
}
}

View File

@@ -0,0 +1,323 @@
// polyfills
if (!String.prototype.startsWith) {
String.prototype.startsWith = function (searchString, position) {
position = position || 0;
return this.substr(position, searchString.length) === searchString;
};
}
(function () {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
var uid = function () {
return (
s4() +
s4() +
"-" +
s4() +
"-" +
s4() +
"-" +
s4() +
"-" +
s4() +
s4() +
s4()
);
};
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly)
symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(source, true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(
target,
Object.getOwnPropertyDescriptors(source)
);
} else {
ownKeys(source).forEach(function (key) {
Object.defineProperty(
target,
key,
Object.getOwnPropertyDescriptor(source, key)
);
});
}
}
return target;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true,
});
} else {
obj[key] = value;
}
return obj;
}
if (!window.__TAURI__) {
window.__TAURI__ = {};
}
window.__TAURI__.transformCallback = function transformCallback(
callback,
once
) {
var identifier = uid();
window[identifier] = function (result) {
if (once) {
delete window[identifier];
}
return callback && callback(result);
};
return identifier;
};
window.__TAURI__.invoke = function invoke(args) {
var _this = this;
return new Promise(function (resolve, reject) {
var callback = _this.transformCallback(function (r) {
resolve(r);
delete window[error];
}, true);
var error = _this.transformCallback(function (e) {
reject(e);
delete window[callback];
}, true);
if (window.__TAURI_INVOKE_HANDLER__) {
window.__TAURI_INVOKE_HANDLER__(
JSON.stringify(
_objectSpread(
{
callback: callback,
error: error,
},
args
)
)
);
} else {
window.addEventListener("DOMContentLoaded", function () {
window.__TAURI_INVOKE_HANDLER__(
JSON.stringify(
_objectSpread(
{
callback: callback,
error: error,
},
args
)
)
);
});
}
});
};
// open <a href="..."> links with the Tauri API
function __openLinks() {
document.querySelector("body").addEventListener(
"click",
function (e) {
var target = e.target;
while (target != null) {
if (
target.matches ? target.matches("a") : target.msMatchesSelector("a")
) {
if (
target.href &&
target.href.startsWith("http") &&
target.target === "_blank"
) {
window.__TAURI__.invoke({
__tauriModule: "Shell",
message: {
cmd: "open",
uri: target.href,
},
});
e.preventDefault();
}
break;
}
target = target.parentElement;
}
},
true
);
}
if (
document.readyState === "complete" ||
document.readyState === "interactive"
) {
__openLinks();
} else {
window.addEventListener(
"DOMContentLoaded",
function () {
__openLinks();
},
true
);
}
window.__TAURI__.invoke({
__tauriModule: 'Event',
message: {
cmd: 'listen',
event: 'tauri://window-created',
handler: window.__TAURI__.transformCallback(function (event) {
if (event.payload) {
var windowLabel = event.payload.label
window.__TAURI__.__windows.push({ label: windowLabel })
}
})
}
})
let permissionSettable = false;
let permissionValue = "default";
function isPermissionGranted() {
if (window.Notification.permission !== "default") {
return Promise.resolve(window.Notification.permission === "granted");
}
return window.__TAURI__.invoke({
__tauriModule: "Notification",
message: {
cmd: "isNotificationPermissionGranted",
},
});
}
function setNotificationPermission(value) {
permissionSettable = true;
window.Notification.permission = value;
permissionSettable = false;
}
function requestPermission() {
return window.__TAURI__
.invoke({
__tauriModule: "Notification",
mainThread: true,
message: {
cmd: "requestNotificationPermission",
},
})
.then(function (permission) {
setNotificationPermission(permission);
return permission;
});
}
function sendNotification(options) {
if (typeof options === "object") {
Object.freeze(options);
}
isPermissionGranted().then(function (permission) {
if (permission) {
return window.__TAURI__.invoke({
__tauriModule: "Notification",
message: {
cmd: "notification",
options:
typeof options === "string"
? {
title: options,
}
: options,
},
});
}
});
}
window.Notification = function (title, options) {
var opts = options || {};
sendNotification(
Object.assign(opts, {
title: title,
})
);
};
window.Notification.requestPermission = requestPermission;
Object.defineProperty(window.Notification, "permission", {
enumerable: true,
get: function () {
return permissionValue;
},
set: function (v) {
if (!permissionSettable) {
throw new Error("Readonly property");
}
permissionValue = v;
},
});
isPermissionGranted().then(function (response) {
if (response === null) {
setNotificationPermission("default");
} else {
setNotificationPermission(response ? "granted" : "denied");
}
});
window.alert = function (message) {
window.__TAURI__.invoke({
__tauriModule: "Dialog",
mainThread: true,
message: {
cmd: "messageDialog",
message: message,
},
});
};
window.confirm = function (message) {
return window.__TAURI__.invoke({
__tauriModule: "Dialog",
mainThread: true,
message: {
cmd: "askDialog",
message: message,
},
});
};
})();

View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Welcome to Tauri!</title>
</head>
<body>
<h1>Welcome to Tauri!</h1>
</body>
</html>

View File

@@ -6,6 +6,5 @@ WixTools
# These are backup files generated by rustfmt
**/*.rs.bk
tauri.js
config.json
bundle.json

View File

@@ -46,16 +46,6 @@ version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
[[package]]
name = "app"
version = "0.1.0"
dependencies = [
"serde",
"serde_json",
"tauri",
"winres",
]
[[package]]
name = "arrayref"
version = "0.3.6"
@@ -111,17 +101,6 @@ dependencies = [
"system-deps",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi 0.3.9",
]
[[package]]
name = "autocfg"
version = "1.0.1"
@@ -304,38 +283,6 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e"
[[package]]
name = "clap"
version = "3.0.0-beta.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142"
dependencies = [
"atty",
"bitflags 1.2.1",
"clap_derive",
"indexmap",
"lazy_static",
"os_str_bytes",
"strsim 0.10.0",
"termcolor",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "clap_derive"
version = "3.0.0-beta.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote 1.0.9",
"syn 1.0.60",
]
[[package]]
name = "cocoa"
version = "0.24.0"
@@ -379,12 +326,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb58b6451e8c2a812ad979ed1d83378caa5e927eef2622017a45f251457c2c9d"
[[package]]
name = "const_fn"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6"
[[package]]
name = "constant_time_eq"
version = "0.1.5"
@@ -505,27 +446,28 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
version = "0.9.1"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
checksum = "d60ab4a8dba064f2fbb5aa270c28da5cf4bbd0e72dae1140a6b0353a779dbe00"
dependencies = [
"cfg-if 1.0.0",
"const_fn",
"crossbeam-utils",
"lazy_static",
"loom",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.1"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
checksum = "bae8f328835f8f5a6ceb6a7842a7f2d0c03692adb5c889347235d59194731fe3"
dependencies = [
"autocfg",
"cfg-if 1.0.0",
"lazy_static",
"loom",
]
[[package]]
@@ -548,7 +490,7 @@ dependencies = [
"ident_case",
"proc-macro2",
"quote 1.0.9",
"strsim 0.9.3",
"strsim",
"syn 1.0.60",
]
@@ -908,6 +850,19 @@ dependencies = [
"system-deps",
]
[[package]]
name = "generator"
version = "0.6.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cdc09201b2e8ca1b19290cf7e65de2246b8e91fb6874279722189c4de7b94dc"
dependencies = [
"cc",
"libc",
"log",
"rustc_version",
"winapi 0.3.9",
]
[[package]]
name = "getrandom"
version = "0.1.16"
@@ -1117,6 +1072,16 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "helloworld"
version = "0.1.0"
dependencies = [
"serde",
"serde_json",
"tauri",
"winres",
]
[[package]]
name = "hermit-abi"
version = "0.1.18"
@@ -1389,6 +1354,17 @@ dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "loom"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d44c73b4636e497b4917eb21c33539efa3816741a2d3ff26c6316f1b529481a4"
dependencies = [
"cfg-if 1.0.0",
"generator",
"scoped-tls",
]
[[package]]
name = "mac-notification-sys"
version = "0.3.0"
@@ -1810,12 +1786,6 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "os_str_bytes"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85"
[[package]]
name = "owned_ttf_parser"
version = "0.6.0"
@@ -2316,6 +2286,15 @@ version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver 0.9.0",
]
[[package]]
name = "rusttype"
version = "0.9.2"
@@ -2392,15 +2371,30 @@ dependencies = [
"libc",
]
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser 0.7.0",
]
[[package]]
name = "semver"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
dependencies = [
"semver-parser",
"semver-parser 0.10.2",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "semver-parser"
version = "0.10.2"
@@ -2545,12 +2539,6 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "strum"
version = "0.8.0"
@@ -2704,7 +2692,6 @@ name = "tauri-api"
version = "0.7.5"
dependencies = [
"bytes",
"clap",
"dirs-next",
"either",
"flate2",
@@ -2714,7 +2701,7 @@ dependencies = [
"rand 0.8.3",
"reqwest",
"rfd",
"semver",
"semver 0.11.0",
"serde",
"serde_json",
"serde_repr",
@@ -2792,24 +2779,6 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "termcolor"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789"
dependencies = [
"unicode-width",
]
[[package]]
name = "thiserror"
version = "1.0.24"
@@ -3024,12 +2993,6 @@ version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.0.4"
@@ -3069,12 +3032,6 @@ version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version-compare"
version = "0.0.10"

View File

@@ -1,44 +1,28 @@
workspace = { }
[package]
name = "app"
name = "helloworld"
version = "0.1.0"
description = "A Tauri App"
authors = [ "you" ]
license = ""
repository = ""
default-run = "app"
default-run = "helloworld"
edition = "2018"
build = "src/build.rs"
[package.metadata.bundle]
identifier = "com.tauri.dev"
icon = [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = [ "derive" ] }
tauri = { path = "../../..", features =["api-all", "cli"]}
tauri = { path = "../../..", features =["api-all"]}
[target."cfg(windows)".build-dependencies]
winres = "0.1"
[features]
default = [ "embedded-server" ]
embedded-server = [ "tauri/embedded-server" ]
[[bin]]
name = "app"
name = "helloworld"
path = "src/main.rs"
[profile.release]
panic = "abort"
codegen-units = 1
lto = true
incremental = false
opt-level = "z"

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

@@ -0,0 +1,10 @@
use serde::Deserialize;
#[derive(Deserialize)]
#[serde(tag = "cmd", rename_all = "camelCase")]
pub enum Cmd {
// your custom commands
// multiple arguments are allowed
// note that rename_all = "camelCase": you need to use "myCustomCommand" on JS
MyCustomCommand { argument: String },
}

View File

@@ -0,0 +1,33 @@
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
mod cmd;
#[derive(tauri::FromTauriContext)]
#[config_path = "examples/helloworld/src-tauri/tauri.conf.json"]
struct Context;
fn main() {
tauri::AppBuilder::<tauri::flavors::Wry, Context>::new()
.invoke_handler(|_webview, arg| async move {
use cmd::Cmd::*;
match serde_json::from_str(&arg) {
Err(e) => Err(e.into()),
Ok(command) => {
match command {
// definitions for your custom commands from Cmd here
MyCustomCommand { argument } => {
// your command code
println!("{}", argument);
}
}
Ok(().into())
}
}
})
.build()
.unwrap()
.run();
}

View File

@@ -0,0 +1,53 @@
{
"build": {
"distDir": "../public",
"devPath": "../public",
"beforeDevCommand": "",
"beforeBuildCommand": ""
},
"tauri": {
"bundle": {
"active": true,
"targets": "all",
"identifier": "com.tauri.dev",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"resources": [],
"externalBin": [],
"copyright": "",
"category": "DeveloperTool",
"shortDescription": "",
"longDescription": "",
"deb": {
"depends": [],
"useBootstrapper": false
},
"osx": {
"frameworks": [],
"minimumSystemVersion": "",
"useBootstrapper": false,
"exceptionDomain": ""
}
},
"allowlist": {
"all": true
},
"windows": [
{
"title": "Welcome to Tauri!",
"width": 800,
"height": 600,
"resizable": true,
"fullscreen": false
}
],
"security": {
"csp": "default-src blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline'"
}
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "communication-example",
"name": "multiwindow-example",
"version": "1.0.0",
"description": "A Tauri example showcasing the JS-Rust communication",
"description": "A Tauri example showcasing Tauri's multiwindow ability",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",

View File

@@ -28,6 +28,7 @@ tauri = { path = "../../..", features =["api-all"]}
winres = "0.1"
[features]
default = [ "embedded-server" ]
embedded-server = [ "tauri/embedded-server" ]
[[bin]]