diff --git a/packages/liveview/.gitignore b/packages/liveview/.gitignore new file mode 100644 index 000000000..1d74e2196 --- /dev/null +++ b/packages/liveview/.gitignore @@ -0,0 +1 @@ +.vscode/ diff --git a/packages/liveview/Cargo.toml b/packages/liveview/Cargo.toml index 1d9b9bb65..c32e0dc80 100644 --- a/packages/liveview/Cargo.toml +++ b/packages/liveview/Cargo.toml @@ -8,3 +8,32 @@ edition = "2018" [dependencies] dioxus-core = { path = "../core", version = "0.1.2" } +dioxus-web = { path = "../web" } + + +serde = { version = "1", features = ['derive'] } +tide = "0.16.0" +tide-websockets = "0.3.0" +async-std = { version = "1.8.0", features = ["attributes"] } +log = "0.4" +fern = { version = "0.6.0", features = ["colored"] } +async-channel = "1.5.1" +futures-lite = "1.11.2" +anyhow = "1.0.35" + + +js-sys = { version = "0.3", optional = true } +wasm-bindgen = { version = "0.2.71", optional = true } +lazy_static = { version = "1.4.0", optional = true } +wasm-bindgen-futures = { version = "0.4.20", optional = true } + + +serde_millis = "0.1" +serde_json = "1" +strum = { version = "0.20", features = ["derive"] } + + +[features] +default = ["client", "server"] +server = [] +client = [] diff --git a/packages/liveview/examples/tide.rs b/packages/liveview/examples/tide.rs new file mode 100644 index 000000000..00ad49c31 --- /dev/null +++ b/packages/liveview/examples/tide.rs @@ -0,0 +1,97 @@ +pub fn main() { + #[cfg(feature = "client")] + wasm_bindgen_futures::spawn_local(async { client::app().await.unwrap() }); + + #[cfg(feature = "server")] + async_std::task::block_on(async { server::app().await.expect("") }); +} + +#[derive(strum::EnumIter, strum::Display, strum::AsRefStr)] +pub enum SelectedStream { + Football, + Hockey, + Socker, +} + +#[cfg(feature = "client")] +mod client { + use super::*; + use dioxus_core::prelude::*; + use dioxus_web::WebsysRenderer; + use strum::IntoEnumIterator; + + pub async fn app() -> anyhow::Result<()> { + Ok(dioxus_web::WebsysRenderer::start(APP).await) + } + + static APP: FC<()> = |ctx, props| { + let (selected_stream, set_stream) = use_state(&ctx, || SelectedStream::Football); + + let options = SelectedStream::iter().map(|name| { + rsx! { option { "{name}", value: "{name}" } } + }); + + ctx.render(rsx! { + div { + h1 { "Tide basic CRUD app" } + h2 { "Chosen stream: {selected_stream}" } + select { + value: {selected_stream.as_ref()} + "{selected_stream}" + {options} + } + } + }) + }; +} + +#[cfg(feature = "server")] +mod server { + use async_std::sync::RwLock; + pub use log::info; + use std::sync::Arc; + use tide::Request; + use tide_websockets::{Message, WebSocket, WebSocketConnection}; + + // type ServerRequest = Request>>; + type ServerRequest = Request<()>; + // type ServerRequest = Request>>; + + static CLIENT_PATH: &'static str = ""; + + pub async fn app() -> anyhow::Result<()> { + let mut app = tide::new(); + // let mut app = tide::with_state(Arc::new(RwLock::new(()))); + // let mut app = tide::with_state(ServerState::new()); + + // for all examples: + // assume the bundle exists at ../public + + app.at("") + .serve_dir(format!("{}/pkg", CLIENT_PATH)) + .expect("Cannot serve directory"); + + app.at("/updates").get(WebSocket::new(socket_handler)); + + let addr = "0.0.0.0:9001"; + log::info!("Congrats! Server is up and running at http://{}", addr); + app.listen(addr).await?; + + Ok(()) + } + + async fn socket_handler( + request: ServerRequest, + stream: WebSocketConnection, + ) -> tide::Result<()> { + // clone the receiver channel + // subscribe to any updates + // let receiver = request.state().read().await.receiver.clone(); + // while let Ok(evt) = receiver.recv().await { + // let response_msg = serde_json::to_string(&evt)?; + // stream.send_string(response_msg).await?; + // } + + Ok(()) + } +}