Merge remote-tracking branch 'upstream/main' into updater

This commit is contained in:
Max Coppen 2022-11-15 19:07:41 +01:00
commit 8b9299ec1c
87 changed files with 15088 additions and 667 deletions

View file

@ -1,3 +0,0 @@
/dist/
/target/
/Cargo.lock

View file

@ -1,16 +0,0 @@
[build]
target = "./index.html"
[watch]
ignore = ["./src-tauri"]
[serve]
address = "127.0.0.1"
port = 1420
open = false
# [[hooks]]
# # Runs SSG on production builds
# stage = "post_build"
# command = "bash"
# command_arguments = ["-c", "if [[ $TRUNK_PROFILE == \"release\" ]]; then cargo run --release --features ssg -- $TRUNK_STAGING_DIR; fi"]

View file

@ -1,12 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Tauri + Yew App</title>
<link data-trunk rel="css" href="style.css" />
<link data-trunk rel="copy-dir" href="public" />
</head>
<body>
<!--app-html-->
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -1,9 +0,0 @@
[package]
name = "shared"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { version = "1.0.140", features = ["derive"] }

View file

@ -1,12 +0,0 @@
use serde::{Serialize, Deserialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Reply<'a> {
pub data: &'a str,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RequestBody<'a> {
pub id: i32,
pub name: &'a str,
}

View file

@ -1,37 +0,0 @@
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
use shared::{Reply, RequestBody};
#[tauri::command]
fn log_operation(event: String, payload: Option<String>) {
println!("{} {:?}", event, payload);
}
#[tauri::command]
fn perform_request(endpoint: String, body: RequestBody) -> String {
println!("{} {:?}", endpoint, body);
"message response".into()
}
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![log_operation, perform_request])
.on_page_load(|window, _| {
let window_ = window.clone();
window.listen("js-event", move |event| {
println!("got js-event with message '{:?}'", event.payload());
let reply = Reply {
data: "something else",
};
window_
.emit("rust-event", Some(reply))
.expect("failed to emit");
});
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View file

@ -1,82 +0,0 @@
mod views;
use sycamore::prelude::*;
#[cfg(not(feature = "ssg"))]
use sycamore_router::{Router, HistoryIntegration};
#[component]
fn Header<G: Html>(cx: Scope) -> View<G> {
view! { cx,
header(style="display: flex; gap: 1em; margin-bottom: 1em;") {
a(href="/") {
"Welcome"
}
a(href="/app") {
"App"
}
a(href="/clipboard") {
"Clipboard"
}
a(href="/updater") {
"Updater"
}
a(href="/communication") {
"Communication"
}
}
}
}
#[cfg(all(not(debug_assertions), not(feature = "ssg")))]
fn main() {
wasm_logger::init(wasm_logger::Config::default());
sycamore::hydrate(|cx| view! { cx,
Header
Router(
integration=HistoryIntegration::new(),
view=views::switch
)
});
}
#[cfg(all(debug_assertions, not(feature = "ssg")))]
fn main() {
use sycamore::view;
wasm_logger::init(wasm_logger::Config::default());
sycamore::render(|cx| view! { cx,
Header
Router(
integration=HistoryIntegration::new(),
view=views::switch
)
});
}
#[cfg(feature = "ssg")]
fn main() {
use sycamore_router::StaticRouter;
let out_dir = std::env::args().nth(1).unwrap();
println!("out_dir {}", out_dir);
let template = std::fs::read_to_string(format!("{}/index.html", out_dir)).unwrap();
let html = sycamore::render_to_string(|cx| view! { cx,
Header
StaticRouter(
route=route.clone(),
view=views::switch
)
});
let html = template.replace("<!--app-html-->\n", &html);
let path = format!("{}/index.html", out_dir);
println!("Writing html to file \"{}\"", path);
std::fs::write(path, html).unwrap();
}

View file

@ -1,78 +0,0 @@
use gloo_timers::callback::Timeout;
use sycamore::prelude::*;
use tauri_sys::app;
#[component]
pub fn App<G: Html>(cx: Scope) -> View<G> {
let show_app = |_| {
sycamore::futures::spawn_local(async move {
let res = app::hide().await;
log::debug!("app hide res {:?}", res);
let timeout = Timeout::new(2_000, move || {
sycamore::futures::spawn_local(async move {
let res = app::show().await;
log::debug!("app show res {:?}", res);
});
});
timeout.forget();
});
};
let hide_app = |_| {
sycamore::futures::spawn_local(async move {
let res = app::hide().await;
log::debug!("app hide res {:?}", res);
});
};
let get_name = |_| {
sycamore::futures::spawn_local(async move {
let res = app::get_name().await;
log::debug!("app name {:?}", res);
});
};
let get_version = |_| {
sycamore::futures::spawn_local(async move {
let res = app::get_version().await;
log::debug!("app version {:?}", res);
});
};
let get_tauri_version = |_| {
sycamore::futures::spawn_local(async move {
let res = app::get_tauri_version().await;
log::debug!("tauri version {:?}", res);
});
};
view! { cx,
div {
button(class="btn",id="get_name",on:click=get_name) {
"Get App Name"
}
button(class="btn",id="get_version",on:click=get_version) {
"Get App Version"
}
button(class="btn",id="get_tauri_version",on:click=get_tauri_version) {
"Get Tauri Version"
}
}
div {
button(class="btn",id="show",title="Hides and shows the app after 2 seconds",on:click=show_app) {
"Show"
}
button(class="btn",id="hide",on:click=hide_app) {
"Hide"
}
}
}
}

View file

@ -1,42 +0,0 @@
use sycamore::prelude::*;
use tauri_sys::clipboard::{read_text, write_text};
#[component]
pub fn Clipboard<G: Html>(cx: Scope) -> View<G> {
let text = create_signal(cx, "clipboard message".to_string());
let write = move |_| {
sycamore::futures::spawn_local_scoped(cx, async move {
write_text(&text.get()).await
// .then(() => {
// onMessage('Wrote to the clipboard')
// })
// .catch(onMessage)
});
};
let read = |_| {
sycamore::futures::spawn_local(async move {
let text = read_text().await;
log::info!("Read text from clipboard {:?}", text);
// readText()
// .then((contents) => {
// onMessage(`Clipboard contents: ${contents}`)
// })
// .catch(onMessage)
});
};
view! { cx,
div(class="flex gap-1") {
input(class="grow input",placeholder="Text to write to the clipboard",bind:value=text)
button(class="btn",type="button",on:click=write) {
"Write"
}
button(class="btn",type="button",on:click=read) {
"Read"
}
}
}
}

View file

@ -1,90 +0,0 @@
use serde::{Deserialize, Serialize};
use sycamore::prelude::*;
use tauri_sys::event::{emit, listen};
use tauri_sys::tauri::invoke;
use shared::RequestBody;
#[component]
pub fn Communication<'a, G: Html>(cx: Scope<'a>) -> View<G> {
let unlisten = create_signal::<Option<Box<&dyn FnOnce()>>>(cx, None);
// on_mount(cx, move || {
// sycamore::futures::spawn_local_scoped(cx, async move {
// let unlisten_raw = listen::<Reply>("rust-event", &|reply| log::debug!("got reply {:?}", reply)).await;
// unlisten.set(Some(Box::new(&unlisten_raw)));
// });
// });
// on_cleanup(cx, || {
// if let Some(unlisten) = unlisten .take().as_deref() {
// (unlisten)()
// }
// });
let log = |_| {
#[derive(Serialize)]
struct Payload<'a> {
event: &'a str,
payload: &'a str,
}
sycamore::futures::spawn_local(async move {
let res = invoke::<_, ()>(
"log_operation",
&Payload {
event: "tauri-click",
payload: "this payload is optional because we used Option in Rust",
},
)
.await;
log::debug!("Emitted event, response {:?}", res);
});
};
let perform_request = |_| {
sycamore::futures::spawn_local(async move {
#[derive(Serialize)]
struct Payload<'a> {
endpoint: &'a str,
body: RequestBody<'a>
}
let res = invoke::<_, String>(
"perform_request",
&Payload {
endpoint: "dummy endpoint arg",
body: RequestBody {
id: 5,
name: "test",
},
},
)
.await;
log::debug!("Got reply {:?}", res);
});
};
let emit_event = |_| {
sycamore::futures::spawn_local(async move {
emit("js-event", &"this is the payload string").await;
});
};
view! { cx,
div {
button(class="btn",id="log",on:click=log) {
"Call Log API"
}
button(class="btn",mid="request",on:click=perform_request) {
"Call Request (async) API"
}
button(class="btn",id="event",on:click=emit_event) {
"Send event to Rust"
}
}
}
}

View file

@ -1,33 +0,0 @@
mod app;
mod clipboard;
mod communication;
mod updater;
mod welcome;
use sycamore::view::View;
use sycamore_router::Route;
use sycamore::prelude::*;
#[derive(Debug, Clone, Route)]
pub enum Page {
#[to("/app")]
App,
#[to("/clipboard")]
Clipboard,
#[to("/communication")]
Communication,
#[to("/updater")]
Updater,
#[not_found]
NotFound
}
pub fn switch<G: Html>(cx: Scope, route: &ReadSignal<Page>) -> View<G> {
match route.get().as_ref() {
Page::App => app::App(cx),
Page::Clipboard => clipboard::Clipboard(cx),
Page::Communication => communication::Communication(cx),
Page::Updater => updater::Updater(cx),
Page::NotFound => welcome::Welcome(cx)
}
}

View file

@ -1,10 +0,0 @@
use sycamore::prelude::*;
#[component]
pub fn Welcome<G: Html>(cx: Scope) -> View<G> {
view! { cx,
h1 {
"Welcome"
}
}
}

View file

@ -1,120 +0,0 @@
.logo.yew:hover {
filter: drop-shadow(0 0 2em #20a88a);
}
.logo.sycamore {
color: #0000;
font-size: 3rem;
line-height: 1;
font-weight: 800;
-webkit-background-clip: text;
background-clip: text;
background-image: linear-gradient(to right,#fdba74, #f87171);
font-family: Inter,system-ui,sans-serif;
}
.logo.sycamore:hover {
filter: drop-shadow(0 0 2em #f87171);
}
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color: #0f0f0f;
background-color: #f6f6f6;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
.container {
margin: 0;
padding-top: 10vh;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: 0.75s;
}
.logo.tauri:hover {
filter: drop-shadow(0 0 2em #24c8db);
}
.row {
display: flex;
justify-content: center;
align-items: center;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
h1 {
text-align: center;
}
input,
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
color: #0f0f0f;
background-color: #ffffff;
transition: border-color 0.25s;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
}
button {
cursor: pointer;
}
button:hover {
border-color: #396cd8;
}
input,
button {
outline: none;
}
#greet-input {
margin-right: 5px;
}
@media (prefers-color-scheme: dark) {
:root {
color: #f6f6f6;
background-color: #2f2f2f;
}
a:hover {
color: #24c8db;
}
input,
button {
color: #ffffff;
background-color: #0f0f0f98;
}
}

2
examples/test/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
target
dist

3894
examples/test/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,21 +1,19 @@
[package]
name = "tauri-app-ui"
name = "tauri-sys-test-ui"
version = "0.0.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tauri-sys = { path = "../../", features = ["all"] }
serde = { version = "1.0.140", features = ["derive"] }
sycamore = { git = "https://github.com/sycamore-rs/sycamore", rev = "abd556cbc02047042dad2ebd04405e455a9b11b2", features = ["suspense", "hydrate"] }
sycamore-router = { git = "https://github.com/sycamore-rs/sycamore", rev = "abd556cbc02047042dad2ebd04405e455a9b11b2" }
log = "0.4.17"
sycamore = { git = "https://github.com/sycamore-rs/sycamore", rev = "abd556cbc02047042dad2ebd04405e455a9b11b2", features = ["suspense"] }
anyhow = "1.0.66"
console_error_panic_hook = "0.1.7"
wasm-bindgen-futures = "0.4.32"
futures-util = "0.3.25"
serde = { version = "1.0.147", features = ["derive"] }
wasm-logger = "0.2.0"
gloo-timers = "0.2.4"
shared = { path = "shared" }
log = "0.4.17"
[features]
ssg = ["sycamore/ssr"]
[workspace]
members = ["src-tauri", "shared"]
ci = []

10
examples/test/Trunk.toml Normal file
View file

@ -0,0 +1,10 @@
[build]
target = "./index.html"
[watch]
ignore = ["./src-tauri"]
[serve]
address = "127.0.0.1"
port = 1420
open = false

7
examples/test/index.html Normal file
View file

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Tauri + Yew App</title>
</head>
</html>

View file

@ -1,5 +1,5 @@
[package]
name = "tauri-app"
name = "tauri-sys-test"
version = "0.0.0"
description = "A Tauri App"
authors = ["you"]
@ -11,13 +11,12 @@ rust-version = "1.57"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[build-dependencies]
tauri-build = { git = "https://github.com/tauri-apps/tauri", features = [] }
tauri-build = { version = "1.2", features = [] }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tauri = { git = "https://github.com/tauri-apps/tauri", features = ["api-all", "updater"] }
shared = { path = "../shared" }
tauri = { version = "1.2", features = ["api-all"] }
[features]
# by default Tauri runs in production mode

View file

@ -0,0 +1,6 @@
{
"build": {
"beforeDevCommand": "trunk serve --features ci",
"beforeBuildCommand": "trunk build --release --features ci"
}
}

View file

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 974 B

After

Width:  |  Height:  |  Size: 974 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 903 B

After

Width:  |  Height:  |  Size: 903 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -0,0 +1,41 @@
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
use std::sync::atomic::{AtomicBool, Ordering};
use tauri::{Manager, State, api::notification::Notification};
struct Received(AtomicBool);
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
#[tauri::command]
fn verify_receive(emitted: State<Received>) -> bool {
emitted.0.load(Ordering::Relaxed)
}
#[tauri::command]
fn exit_with_error(e: &str) -> bool {
eprintln!("{}", e);
std::process::exit(1);
}
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![verify_receive, exit_with_error])
.setup(|app| {
app.manage(Received(AtomicBool::new(false)));
let app_handle = app.handle();
app.listen_global("foo", move |_| {
app_handle
.state::<Received>()
.0
.store(true, Ordering::Relaxed);
});
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View file

@ -7,7 +7,7 @@
"withGlobalTauri": true
},
"package": {
"productName": "tauri-app",
"productName": "tauri-sys-test",
"version": "0.0.0"
},
"tauri": {
@ -63,7 +63,7 @@
"fullscreen": false,
"height": 600,
"resizable": true,
"title": "tauri-app",
"title": "tauri-sys testing suite",
"width": 800
}
]

34
examples/test/src/app.rs Normal file
View file

@ -0,0 +1,34 @@
use anyhow::ensure;
use tauri_sys::app;
pub async fn get_name() -> anyhow::Result<()> {
let name = app::get_name().await?;
ensure!(name == "tauri-sys-test");
Ok(())
}
pub async fn get_version() -> anyhow::Result<()> {
let version = app::get_version().await?;
ensure!(version.major == 0);
ensure!(version.minor == 0);
ensure!(version.patch == 0);
ensure!(version.build.is_empty());
ensure!(version.pre.is_empty());
Ok(())
}
pub async fn get_tauri_version() -> anyhow::Result<()> {
let version = app::get_tauri_version().await?;
ensure!(version.major == 1);
ensure!(version.minor == 2);
ensure!(version.patch == 0);
ensure!(version.build.is_empty());
ensure!(version.pre.is_empty());
Ok(())
}

View file

@ -0,0 +1,12 @@
use anyhow::ensure;
use tauri_sys::clipboard;
pub async fn test() -> anyhow::Result<()> {
clipboard::write_text("foobar").await?;
let text = clipboard::read_text().await?;
ensure!(text == "foobar".to_string());
Ok(())
}

View file

@ -0,0 +1,97 @@
use anyhow::ensure;
use tauri_sys::dialog::{FileDialogBuilder, MessageDialogBuilder, MessageDialogType};
pub async fn ask() -> anyhow::Result<()> {
let mut builder = MessageDialogBuilder::new();
builder.set_title("Tauri");
builder.set_type(MessageDialogType::Warning);
let works = builder
.ask("Does this work? \n Click Yes to mark this test as passing")
.await?;
ensure!(works);
Ok(())
}
pub async fn confirm() -> anyhow::Result<()> {
let mut builder = MessageDialogBuilder::new();
builder.set_title("Tauri");
builder.set_type(MessageDialogType::Warning);
let works = builder
.confirm("Does this work? \n Click Ok to mark this test as passing")
.await?;
ensure!(works);
Ok(())
}
pub async fn message() -> anyhow::Result<()> {
let mut builder = MessageDialogBuilder::new();
builder.set_title("Tauri");
builder.set_type(MessageDialogType::Warning);
builder.message("This is a message just for you!").await?;
Ok(())
}
pub async fn pick_file() -> anyhow::Result<()> {
let mut builder = FileDialogBuilder::new();
builder.set_title("Select a file to mark this test as passing");
let file = builder.pick_file().await?;
ensure!(file.is_some());
Ok(())
}
pub async fn pick_files() -> anyhow::Result<()> {
let mut builder = FileDialogBuilder::new();
builder.set_title("Select a multiple files to mark this test as passing");
let file = builder.pick_files().await?;
ensure!(file.is_some());
ensure!(file.unwrap().len() > 1);
Ok(())
}
pub async fn pick_folder() -> anyhow::Result<()> {
let mut builder = FileDialogBuilder::new();
builder.set_title("Select a folder to mark this test as passing");
let file = builder.pick_folder().await?;
ensure!(file.is_some());
Ok(())
}
pub async fn pick_folders() -> anyhow::Result<()> {
let mut builder = FileDialogBuilder::new();
builder.set_title("Select a multiple folders to mark this test as passing");
let file = builder.pick_folders().await?;
ensure!(file.is_some());
ensure!(file.unwrap().len() > 1);
Ok(())
}
pub async fn save() -> anyhow::Result<()> {
let mut builder = FileDialogBuilder::new();
builder.set_title("Select a file to mark this test as passing");
let file = builder.save().await?;
ensure!(file.is_some());
Ok(())
}

View file

@ -0,0 +1,10 @@
use anyhow::ensure;
use tauri_sys::{event, tauri};
pub async fn emit() -> anyhow::Result<()> {
event::emit("foo", &"bar").await?;
ensure!(tauri::invoke::<_, bool>("verify_receive", &()).await?);
Ok(())
}

175
examples/test/src/main.rs Normal file
View file

@ -0,0 +1,175 @@
mod app;
mod clipboard;
mod event;
mod window;
mod dialog;
mod notification;
mod os;
extern crate console_error_panic_hook;
use std::future::Future;
use std::panic;
use sycamore::prelude::*;
use sycamore::suspense::Suspense;
#[cfg(feature = "ci")]
async fn exit_with_error(e: String) {
use serde::Serialize;
#[derive(Serialize)]
struct Args {
e: String,
}
tauri_sys::tauri::invoke::<_, ()>("exit_with_error", &Args { e })
.await
.unwrap();
}
#[derive(Props)]
pub struct TestProps<'a, F>
where
F: Future<Output = anyhow::Result<()>> + 'a,
{
name: &'a str,
test: F,
}
#[component]
pub async fn Test<'a, G: Html, F>(cx: Scope<'a>, props: TestProps<'a, F>) -> View<G>
where
F: Future<Output = anyhow::Result<()>> + 'a,
{
let res = props.test.await;
view! { cx,
tr {
td { code { (props.name.to_string()) } }
td { (if let Err(e) = &res {
#[cfg(feature = "ci")]
{
wasm_bindgen_futures::spawn_local(exit_with_error(e.to_string()));
unreachable!()
}
#[cfg(not(feature = "ci"))]
format!("{:?}", e)
} else {
format!("")
})
}
}
}
}
#[cfg(not(feature = "ci"))]
#[component]
pub async fn InteractiveTest<'a, G: Html, F>(cx: Scope<'a>, props: TestProps<'a, F>) -> View<G>
where
F: Future<Output = anyhow::Result<()>> + 'a,
{
let mut test = Some(props.test);
let render_test = create_signal(cx, false);
let run_test = |_| {
render_test.set(true);
};
view! { cx,
(if *render_test.get() {
let test = test.take().unwrap();
let fallback = view! { cx,
tr {
td { code { (props.name.to_string()) } }
td {
"Running Test..."
}
}
};
view! { cx,
Suspense(fallback=fallback) {
Test(name=props.name, test=test)
}
}
} else {
view! { cx,
tr {
td { code { (props.name.to_string()) } }
td {
button(on:click=run_test) { "Run Interactive Test"}
}
}
}
})
}
}
#[cfg(feature = "ci")]
#[component]
pub async fn InteractiveTest<'a, G: Html, F>(cx: Scope<'a>, _props: TestProps<'a, F>) -> View<G>
where
F: Future<Output = anyhow::Result<()>> + 'a,
{
view! { cx, "Interactive tests are not run in CI mode" }
}
#[component]
pub async fn Terminate<'a, G: Html>(cx: Scope<'a>) -> View<G> {
#[cfg(feature = "ci")]
sycamore::suspense::await_suspense(cx, async {
tauri_sys::process::exit(0).await;
})
.await;
view! {
cx,
}
}
fn main() {
wasm_logger::init(wasm_logger::Config::default());
panic::set_hook(Box::new(|info| {
console_error_panic_hook::hook(info);
#[cfg(feature = "ci")]
wasm_bindgen_futures::spawn_local(exit_with_error(format!("{}", info)));
}));
sycamore::render(|cx| {
view! { cx,
table {
tbody {
Suspense(fallback=view!{ cx, "Running Tests..." }) {
Test(name="app::get_name",test=app::get_name())
Test(name="app::get_version",test=app::get_version())
Test(name="app::get_tauri_version",test=app::get_tauri_version())
Test(name="clipboard::read_text | clipboard::write_text",test=clipboard::test())
Test(name="event::emit",test=event::emit())
InteractiveTest(name="dialog::message",test=dialog::message())
InteractiveTest(name="dialog::ask",test=dialog::ask())
InteractiveTest(name="dialog::confirm",test=dialog::confirm())
InteractiveTest(name="dialog::pick_file",test=dialog::pick_file())
InteractiveTest(name="dialog::pick_files",test=dialog::pick_files())
InteractiveTest(name="dialog::pick_folder",test=dialog::pick_folder())
InteractiveTest(name="dialog::pick_folders",test=dialog::pick_folders())
InteractiveTest(name="dialog::save",test=dialog::save())
Test(name="os::arch",test=os::arch())
Test(name="os::platform",test=os::platform())
Test(name="os::tempdir",test=os::tempdir())
Test(name="os::kind",test=os::kind())
Test(name="os::version",test=os::version())
Test(name="notification::is_permission_granted",test=notification::is_permission_granted())
Test(name="notification::request_permission",test=notification::request_permission())
InteractiveTest(name="notification::show_notification",test=notification::show_notification())
// Test(name="window::WebviewWindow::new",test=window::create_window())
Terminate
}
}
}
}
});
}

View file

@ -0,0 +1,28 @@
use anyhow::ensure;
use tauri_sys::notification::{self, Permission};
pub async fn is_permission_granted() -> anyhow::Result<()> {
let granted = notification::is_permission_granted().await?;
ensure!(granted);
Ok(())
}
pub async fn request_permission() -> anyhow::Result<()> {
let permission = notification::request_permission().await?;
ensure!(permission == Permission::Granted);
Ok(())
}
pub async fn show_notification() -> anyhow::Result<()> {
let mut n = notification::Notification::default();
n.set_title("TAURI");
n.set_body("Tauri is awesome!");
n.show()?;
Ok(())
}

41
examples/test/src/os.rs Normal file
View file

@ -0,0 +1,41 @@
use tauri_sys::os;
pub async fn arch() -> anyhow::Result<()> {
let arch = os::arch().await?;
log::debug!("{:?}", arch);
Ok(())
}
pub async fn platform() -> anyhow::Result<()> {
let platform = os::platform().await?;
log::debug!("{:?}", platform);
Ok(())
}
pub async fn tempdir() -> anyhow::Result<()> {
let tempdir = os::tempdir().await?;
log::debug!("{:?}", tempdir);
Ok(())
}
pub async fn kind() -> anyhow::Result<()> {
let kind = os::kind().await?;
log::debug!("{:?}", kind);
Ok(())
}
pub async fn version() -> anyhow::Result<()> {
let version = os::version().await?;
log::debug!("{:?}", version);
Ok(())
}

View file

@ -0,0 +1,13 @@
use anyhow::ensure;
use tauri_sys::window;
pub async fn create_window() -> anyhow::Result<()> {
let win = window::WebviewWindow::new("foo", ());
ensure!(win.is_visible().await?);
// ensure!(win.label() == "foo".to_string());
win.close().await?;
Ok(())
}