From 45ae5739c15d389d2610956918fadc3b75724c59 Mon Sep 17 00:00:00 2001 From: chaosprint Date: Fri, 7 Jul 2023 09:01:41 +0200 Subject: [PATCH 1/3] add hyperlink in ui and text example --- Cargo.lock | 48 ++++++++++++++++++++++- crates/wasm/Cargo.toml | 4 ++ crates/wasm/src/client/mod.rs | 7 ++++ guest/rust/examples/ui/text/src/client.rs | 2 + shared_crates/schema/src/schema/text.toml | 11 ++++++ shared_crates/ui/src/text.rs | 31 ++++++++++++--- web/Cargo.lock | 48 ++++++++++++++++++++++- 7 files changed, 141 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 216f0c28ae..912aa51b1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1594,6 +1594,7 @@ dependencies = [ "ambient_core", "ambient_ecs", "ambient_gpu", + "ambient_guest_bridge", "ambient_input", "ambient_model", "ambient_network", @@ -1637,6 +1638,7 @@ dependencies = [ "wasi-common", "wasmtime", "wasmtime-wasi", + "webbrowser", "wgpu 0.16.1", "winit", "wit-bindgen-core", @@ -2714,7 +2716,7 @@ dependencies = [ "alsa", "core-foundation-sys", "coreaudio-rs", - "jni", + "jni 0.19.0", "js-sys", "libc", "mach", @@ -4257,6 +4259,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "hound" version = "3.5.0" @@ -4577,6 +4588,22 @@ dependencies = [ "walkdir", ] +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + [[package]] name = "jni-sys" version = "0.3.0" @@ -5450,7 +5477,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27f63c358b4fa0fbcfefd7c8be5cfc39c08ce2389f5325687e7762a48d30a5c1" dependencies = [ - "jni", + "jni 0.19.0", "ndk 0.6.0", "ndk-context", "num-derive", @@ -8591,6 +8618,23 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webbrowser" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd222aa310eb7532e3fd427a5d7db7e44bc0b0cf1c1e21139c345325511a85b6" +dependencies = [ + "core-foundation", + "home", + "jni 0.21.1", + "log", + "ndk-context", + "objc", + "raw-window-handle", + "url", + "web-sys", +] + [[package]] name = "webpki" version = "0.22.0" diff --git a/crates/wasm/Cargo.toml b/crates/wasm/Cargo.toml index 40710fb85f..01f2e25caf 100644 --- a/crates/wasm/Cargo.toml +++ b/crates/wasm/Cargo.toml @@ -20,11 +20,15 @@ ambient_gpu = { path = "../gpu" } ambient_renderer = { path = "../renderer" } ambient_procedurals = { path = "../procedurals" } +ambient_guest_bridge = { path = "../../shared_crates/guest_bridge", default-features = false, version = "0.3.0-dev" } + ambient_project = { path = "../../shared_crates/project" } ambient_shared_types = { path = "../../shared_crates/shared_types", features = [ "native", ] } +webbrowser = "0.8.10" + anyhow = { workspace = true } async-trait = { workspace = true } byteorder = { workspace = true } diff --git a/crates/wasm/src/client/mod.rs b/crates/wasm/src/client/mod.rs index cf6372fc85..31ada4df82 100644 --- a/crates/wasm/src/client/mod.rs +++ b/crates/wasm/src/client/mod.rs @@ -1,6 +1,7 @@ use crate::shared::{self, client_bytecode_from_url, module_bytecode, ModuleBytecode}; use ambient_core::{asset_cache, async_ecs::async_run, runtime}; use ambient_ecs::{query, EntityId, SystemGroup, World}; +use ambient_guest_bridge::components::text::hyperlink; use ambient_std::{ asset_cache::AsyncAssetKeyExt, asset_url::AbsAssetUrl, download_asset::BytesFromUrl, }; @@ -27,6 +28,12 @@ pub fn systems() -> SystemGroup { SystemGroup::new( "core/wasm/client", vec![ + query(hyperlink().changed()).to_system(move |q, world, qs, _| { + for (id, url) in q.collect_cloned(world, qs) { + webbrowser::open(&url).ok(); + world.despawn(id); + } + }), query(client_bytecode_from_url().changed()).to_system(move |q, world, qs, _| { for (id, url) in q.collect_cloned(world, qs) { let url = match AbsAssetUrl::from_str(&url) { diff --git a/guest/rust/examples/ui/text/src/client.rs b/guest/rust/examples/ui/text/src/client.rs index 4d668e6f0d..cbbe434614 100644 --- a/guest/rust/examples/ui/text/src/client.rs +++ b/guest/rust/examples/ui/text/src/client.rs @@ -14,6 +14,8 @@ fn App(_hooks: &mut Hooks) -> Element { Text::el("Custom size").with(font_size(), 40.), Text::el("Custom color").with(color(), vec4(1., 0., 0., 1.)), Text::el("Multi\n\nLine"), + Text::el("Hyperlink:"), + Hyperlink::el("https://ambient.run".to_string()), ]) .with_padding_even(STREET) .with(space_between_items(), 10.) diff --git a/shared_crates/schema/src/schema/text.toml b/shared_crates/schema/src/schema/text.toml index ae15bf91bc..90f8a08269 100644 --- a/shared_crates/schema/src/schema/text.toml +++ b/shared_crates/schema/src/schema/text.toml @@ -26,3 +26,14 @@ type = "String" name = "Text" description = "Create a text mesh on this entity." attributes = ["Debuggable", "Networked", "Store"] + + +[components."core::text::hyperlink"] +type = "String" +name = "Hyperlink" +description = """ +This is a hyperlink text. With this component, the entity is a special one. +Once spawned, the system will open the URL String in the browser. +Then the entity will be destroyed. +""" +attributes = ["Debuggable", "Networked", "Store"] diff --git a/shared_crates/ui/src/text.rs b/shared_crates/ui/src/text.rs index 4c055dddfe..139e86b5ae 100644 --- a/shared_crates/ui/src/text.rs +++ b/shared_crates/ui/src/text.rs @@ -2,12 +2,15 @@ use crate::{UIBase, UIElement}; use ambient_element::{element_component, Element, ElementComponentExt, Hooks}; -use ambient_guest_bridge::components::{ - app::{name, ui_scene}, - layout::{height, width}, - rendering::color, - text::{font_family, font_size, text}, - transform::mesh_to_local, +use ambient_guest_bridge::{ + components::{ + app::{name, ui_scene}, + layout::{height, width}, + rendering::color, + text::{font_family, font_size, hyperlink, text}, + transform::mesh_to_local, + }, + ecs::Entity, }; use glam::{vec4, Mat4}; @@ -68,3 +71,19 @@ pub fn FontAwesomeIcon( .to_string(), ) } + +#[element_component] +/// Hyperlink to a URL. This will open browser when clicked. +pub fn Hyperlink( + _hooks: &mut Hooks, + /// The URL to open + url: String, +) -> Element { + crate::prelude::Button::new(&url.clone(), move |world| { + println!("Opening url {}", &url); + let link = Entity::new().with(hyperlink(), url.clone()); + world.spawn(link); + }) + .style(crate::prelude::ButtonStyle::Inline) + .el() +} diff --git a/web/Cargo.lock b/web/Cargo.lock index bc733a4dc3..f7fc75b41d 100644 --- a/web/Cargo.lock +++ b/web/Cargo.lock @@ -960,6 +960,7 @@ dependencies = [ "ambient_core", "ambient_ecs", "ambient_gpu", + "ambient_guest_bridge", "ambient_input", "ambient_model", "ambient_network", @@ -996,6 +997,7 @@ dependencies = [ "tokio", "tracing", "ulid", + "webbrowser", "wgpu", "winit", "wit-bindgen-core", @@ -1695,7 +1697,7 @@ dependencies = [ "alsa", "core-foundation-sys", "coreaudio-rs", - "jni", + "jni 0.19.0", "js-sys", "libc", "mach", @@ -3019,6 +3021,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "hound" version = "3.5.0" @@ -3326,6 +3337,22 @@ dependencies = [ "walkdir", ] +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + [[package]] name = "jni-sys" version = "0.3.0" @@ -4040,7 +4067,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27f63c358b4fa0fbcfefd7c8be5cfc39c08ce2389f5325687e7762a48d30a5c1" dependencies = [ - "jni", + "jni 0.19.0", "ndk 0.6.0", "ndk-context", "num-derive", @@ -5970,6 +5997,23 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webbrowser" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd222aa310eb7532e3fd427a5d7db7e44bc0b0cf1c1e21139c345325511a85b6" +dependencies = [ + "core-foundation", + "home", + "jni 0.21.1", + "log", + "ndk-context", + "objc", + "raw-window-handle", + "url", + "web-sys", +] + [[package]] name = "webpki" version = "0.22.0" From 72e488c5ed8ed79ccddc86d9e5599453d764905f Mon Sep 17 00:00:00 2001 From: chaosprint Date: Fri, 7 Jul 2023 10:36:15 +0200 Subject: [PATCH 2/3] change to crate 'open'; add some log info and error checking --- Cargo.lock | 48 +-------------- crates/wasm/Cargo.toml | 2 +- crates/wasm/src/client/mod.rs | 7 ++- shared_crates/ui/src/text.rs | 1 - web/Cargo.lock | 107 ++++++++++++++++++++-------------- 5 files changed, 72 insertions(+), 93 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 912aa51b1c..f51ec42d4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1622,6 +1622,7 @@ dependencies = [ "itertools", "log", "once_cell", + "open", "parking_lot", "paste", "physxx", @@ -1638,7 +1639,6 @@ dependencies = [ "wasi-common", "wasmtime", "wasmtime-wasi", - "webbrowser", "wgpu 0.16.1", "winit", "wit-bindgen-core", @@ -2716,7 +2716,7 @@ dependencies = [ "alsa", "core-foundation-sys", "coreaudio-rs", - "jni 0.19.0", + "jni", "js-sys", "libc", "mach", @@ -4259,15 +4259,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" -[[package]] -name = "home" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" -dependencies = [ - "windows-sys 0.48.0", -] - [[package]] name = "hound" version = "3.5.0" @@ -4588,22 +4579,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine", - "jni-sys", - "log", - "thiserror", - "walkdir", - "windows-sys 0.45.0", -] - [[package]] name = "jni-sys" version = "0.3.0" @@ -5477,7 +5452,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27f63c358b4fa0fbcfefd7c8be5cfc39c08ce2389f5325687e7762a48d30a5c1" dependencies = [ - "jni 0.19.0", + "jni", "ndk 0.6.0", "ndk-context", "num-derive", @@ -8618,23 +8593,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webbrowser" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd222aa310eb7532e3fd427a5d7db7e44bc0b0cf1c1e21139c345325511a85b6" -dependencies = [ - "core-foundation", - "home", - "jni 0.21.1", - "log", - "ndk-context", - "objc", - "raw-window-handle", - "url", - "web-sys", -] - [[package]] name = "webpki" version = "0.22.0" diff --git a/crates/wasm/Cargo.toml b/crates/wasm/Cargo.toml index 01f2e25caf..0a75a869e3 100644 --- a/crates/wasm/Cargo.toml +++ b/crates/wasm/Cargo.toml @@ -27,7 +27,6 @@ ambient_shared_types = { path = "../../shared_crates/shared_types", features = [ "native", ] } -webbrowser = "0.8.10" anyhow = { workspace = true } async-trait = { workspace = true } @@ -43,6 +42,7 @@ indoc = { workspace = true } itertools = { workspace = true } log = { workspace = true } once_cell = { workspace = true } +open = { workspace = true } parking_lot = { workspace = true } paste = { workspace = true } ambient_profiling = { workspace = true } diff --git a/crates/wasm/src/client/mod.rs b/crates/wasm/src/client/mod.rs index 31ada4df82..df5f2a95f3 100644 --- a/crates/wasm/src/client/mod.rs +++ b/crates/wasm/src/client/mod.rs @@ -30,7 +30,12 @@ pub fn systems() -> SystemGroup { vec![ query(hyperlink().changed()).to_system(move |q, world, qs, _| { for (id, url) in q.collect_cloned(world, qs) { - webbrowser::open(&url).ok(); + match open::that(&url) { + Ok(()) => log::info!("Opened '{}'", &url), + Err(err) => { + log::error!("An error occurred when opening '{}': {}", &url, err) + } + } world.despawn(id); } }), diff --git a/shared_crates/ui/src/text.rs b/shared_crates/ui/src/text.rs index 139e86b5ae..e73a75d29b 100644 --- a/shared_crates/ui/src/text.rs +++ b/shared_crates/ui/src/text.rs @@ -80,7 +80,6 @@ pub fn Hyperlink( url: String, ) -> Element { crate::prelude::Button::new(&url.clone(), move |world| { - println!("Opening url {}", &url); let link = Entity::new().with(hyperlink(), url.clone()); world.spawn(link); }) diff --git a/web/Cargo.lock b/web/Cargo.lock index f7fc75b41d..c84d0b2b5d 100644 --- a/web/Cargo.lock +++ b/web/Cargo.lock @@ -986,6 +986,7 @@ dependencies = [ "itertools", "log", "once_cell", + "open", "parking_lot", "paste", "pollster", @@ -997,7 +998,6 @@ dependencies = [ "tokio", "tracing", "ulid", - "webbrowser", "wgpu", "winit", "wit-bindgen-core", @@ -1697,7 +1697,7 @@ dependencies = [ "alsa", "core-foundation-sys", "coreaudio-rs", - "jni 0.19.0", + "jni", "js-sys", "libc", "mach", @@ -3021,15 +3021,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" -[[package]] -name = "home" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" -dependencies = [ - "windows-sys 0.48.0", -] - [[package]] name = "hound" version = "3.5.0" @@ -3337,22 +3328,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine", - "jni-sys", - "log", - "thiserror", - "walkdir", - "windows-sys 0.45.0", -] - [[package]] name = "jni-sys" version = "0.3.0" @@ -4067,7 +4042,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27f63c358b4fa0fbcfefd7c8be5cfc39c08ce2389f5325687e7762a48d30a5c1" dependencies = [ - "jni 0.19.0", + "jni", "ndk 0.6.0", "ndk-context", "num-derive", @@ -4099,6 +4074,16 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +[[package]] +name = "open" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2423ffbf445b82e58c3b1543655968923dd06f85432f10be2bb4f1b7122f98c" +dependencies = [ + "pathdiff", + "windows-sys 0.36.1", +] + [[package]] name = "openssl-probe" version = "0.1.5" @@ -4199,6 +4184,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + [[package]] name = "peeking_take_while" version = "0.1.2" @@ -5997,23 +5988,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webbrowser" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd222aa310eb7532e3fd427a5d7db7e44bc0b0cf1c1e21139c345325511a85b6" -dependencies = [ - "core-foundation", - "home", - "jni 0.21.1", - "log", - "ndk-context", - "objc", - "raw-window-handle", - "url", - "web-sys", -] - [[package]] name = "webpki" version = "0.22.0" @@ -6230,6 +6204,19 @@ dependencies = [ "windows-targets 0.48.0", ] +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + [[package]] name = "windows-sys" version = "0.42.0" @@ -6305,6 +6292,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + [[package]] name = "windows_aarch64_msvc" version = "0.37.0" @@ -6323,6 +6316,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + [[package]] name = "windows_i686_gnu" version = "0.37.0" @@ -6341,6 +6340,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + [[package]] name = "windows_i686_msvc" version = "0.37.0" @@ -6359,6 +6364,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + [[package]] name = "windows_x86_64_gnu" version = "0.37.0" @@ -6389,6 +6400,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + [[package]] name = "windows_x86_64_msvc" version = "0.37.0" From c38e20f656ebc8d9f29b10257d0f09a09292a3cb Mon Sep 17 00:00:00 2001 From: chaosprint Date: Fri, 7 Jul 2023 10:56:27 +0200 Subject: [PATCH 3/3] cfg gate --- crates/wasm/src/client/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/wasm/src/client/mod.rs b/crates/wasm/src/client/mod.rs index df5f2a95f3..25893e4c22 100644 --- a/crates/wasm/src/client/mod.rs +++ b/crates/wasm/src/client/mod.rs @@ -30,6 +30,7 @@ pub fn systems() -> SystemGroup { vec![ query(hyperlink().changed()).to_system(move |q, world, qs, _| { for (id, url) in q.collect_cloned(world, qs) { + #[cfg(not(target_os = "unknown"))] match open::that(&url) { Ok(()) => log::info!("Opened '{}'", &url), Err(err) => {