diff --git a/Cargo.lock b/Cargo.lock index 2f0c2ba..b72b081 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,6 +56,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + [[package]] name = "async-channel" version = "2.3.1" @@ -1011,6 +1017,17 @@ dependencies = [ "wasi 0.9.0+wasi-snapshot-preview1", ] +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + [[package]] name = "gimli" version = "0.29.0" @@ -1523,6 +1540,15 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" +dependencies = [ + "proc-macro2", +] + [[package]] name = "lock_api" version = "0.4.12" @@ -1657,6 +1683,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.4" @@ -1713,6 +1745,7 @@ dependencies = [ "ordermap", "serde-wasm-bindgen 0.6.5", "serde_json", + "sir", "tokio-util", "wasm-bindgen", "wasm-bindgen-futures", @@ -1743,6 +1776,16 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -1753,6 +1796,36 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1927,7 +2000,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" dependencies = [ "phf_shared", - "rand", + "rand 0.7.3", ] [[package]] @@ -2088,14 +2161,25 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom", + "getrandom 0.1.16", "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.2.2", + "rand_core 0.5.1", "rand_hc", "rand_pcg", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -2103,7 +2187,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", ] [[package]] @@ -2112,7 +2206,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", ] [[package]] @@ -2121,7 +2224,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", ] [[package]] @@ -2130,7 +2233,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" dependencies = [ - "rand_core", + "rand_core 0.5.1", ] [[package]] @@ -2211,6 +2314,23 @@ dependencies = [ "winreg", ] +[[package]] +name = "rsass" +version = "0.28.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212e14dfa9e48df42c0125c80a213a9a0269103130c8c154080fdbbb79ce7d52" +dependencies = [ + "arc-swap", + "fastrand", + "lazy_static", + "nom", + "num-bigint", + "num-integer", + "num-rational", + "num-traits", + "tracing", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -2519,6 +2639,30 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "sir" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75a6aabaa54dc0d627a5f9af5d932fb71ba940cb8401cfe0e7b7bf340f9c45c3" +dependencies = [ + "dioxus", + "once_cell", + "sir-macro", +] + +[[package]] +name = "sir-macro" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bff4c4b9aafdb2abc85cbe4e252474c319ed7f4ce57e5ffcb768473f6aaf393" +dependencies = [ + "litrs", + "proc-macro2", + "quote", + "rand 0.8.5", + "rsass", +] + [[package]] name = "slab" version = "0.4.9" diff --git a/Cargo.toml b/Cargo.toml index a70004a..bbe1e85 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,3 +27,4 @@ html-purifier = "0.3.0" markdown = "0.3.0" gloo-timers = { version = "0.3.0", features = ["futures"] } futures-channel = "0.3.30" +sir = { version = "0.5.0", features = ["dioxus"] } diff --git a/src/app.rs b/src/app.rs index 9956d8f..382e788 100644 --- a/src/app.rs +++ b/src/app.rs @@ -4,6 +4,7 @@ use std::collections::{BTreeMap, BTreeSet, HashMap}; use dioxus::prelude::*; use ordermap::OrderSet; +use sir::css; pub type ChannelId = u32; pub type UserId = u32; @@ -75,31 +76,67 @@ pub static STATE: State = State { server: Signal::global(|| Default::default()), }; +#[component] +pub fn UserPill(name: String) -> Element { + let pill = css!( + " + border: solid 1px black; + border-radius: 8px; + margin: 4px; + padding: 4px; + " + ); + + rsx!( + span { + class: "{pill}", + "{name}" + } + ) +} + #[component] pub fn User(id: UserId) -> Element { let server = STATE.server.read(); let state = server.users.get(&id)?; - rsx!( - span { - style: "border: solid black 1px; border-radius: 4px;", - "{state.name}" - } - ) + rsx!(UserPill { + name: state.name.clone() + }) } #[component] pub fn Channel(id: ChannelId) -> Element { let server = STATE.server.read(); let state = server.channels.get(&id)?; + + let channel_details = css!( + " + flex: 0 0 100%; + " + ); + let channel_children = css!( + " + border-left: solid black 1px; + display: flex; + flex-direction: row; + flex-wrap: wrap; + margin-left: 5px; + padding-left: 11px; " + ); + rsx!( - "{state.name}" - div { - style: "border-left: solid black 1px; padding-left: 8px;", - for child in state.children.iter() { - Channel { id: *child } - } - for id in state.users.iter() { - User { id: *id } + details { + class: "{channel_details}", + open: true, + summary { "{state.name}" } + div { + class: "{channel_children}", + for id in state.users.iter() { + User { id: *id } + } + for child in state.children.iter() { + Channel { id: *child } + } } } ) @@ -115,10 +152,7 @@ pub fn ChatView() -> Element { style: "margin: 16px; padding: 16px; border: solid black 1px;", for chat in server.chat.iter() { if let Some(sender) = chat.sender.and_then(|u| server.users.get(&u)) { - span { - style: "border: solid black 1px; border-radius: 4px;", - "{sender.name}" - } + UserPill { name: sender.name.clone() } "\u{8194}" } span { @@ -170,6 +204,7 @@ pub fn app() -> Element { let status = &STATE.status; rsx!( + sir::AppStyle { } div { input { placeholder: "username", diff --git a/src/lib.rs b/src/lib.rs index 04ec652..35ee7f1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -549,9 +549,35 @@ fn accept_command( ) -> Result<(), JsValue> { match command { Command::SendChat { markdown, channels } => { - let html_text = markdown::to_html(&markdown); + use markdown::*; + let html_text = match tokenize(&markdown).as_slice() { + block @ [Block::Paragraph(par)] => match par.as_slice() { + [Span::Text(par)] => par.to_string(), + _ => generate_markdown(block.to_vec()) + .trim() + .strip_prefix("

") + .unwrap() + .strip_suffix("

") + .unwrap() + .to_string(), + }, + block => generate_markdown(block.to_vec()).trim().to_string(), + }; + + { + let mut server = STATE.server.write(); + let Some(me) = server.session else { + bail!("not signed in with a session id") + }; + server.chat.push(Chat { + raw: markdown, + dangerous_html: html_text.clone(), + sender: Some(me), + }) + } + let mut u = msgs::TextMessage::new(); - u.set_message(html_text); + u.set_message(html_text.to_string()); u.set_channel_id(channels); let _ = send_chan.unbounded_send(u.into()); }