Skip to main content

serve/
serve.rs

1//! A small intuiTUIve app, served to a browser.
2//!
3//!     cargo run -p rs-rich-web --example serve [-- ADDRESS]
4//!
5//! Open the address it prints: it carries the token the server checks.
6//! Every tab gets its own copy of the app, in a process of its own: its
7//! own clock, counter and list. The address is `127.0.0.1:8080` unless given;
8//! keep it a loopback one unless a proxy with authentication is in front
9//! (see the crate's documentation).
10//!
11//! In the page: type in the box and press Enter to add a line · Tab moves
12//! to the counter, where + and - change it · a click on the counter adds
13//! one · Ctrl+Q ends the tab's session (reload for a new one).
14
15use std::time::Duration;
16
17use rich_web::intuituive::interact::Input;
18use rich_web::intuituive::prelude::*;
19use rich_web::intuituive::rich::markup::escape;
20
21/// The app each tab runs.
22fn app() -> App {
23    App::new(|| {
24        let seconds = signal(0u64);
25        every(Duration::from_secs(1), move |_| seconds.update(|s| *s += 1));
26        let count = signal(0i64);
27        let said = signal(Vec::<String>::new());
28
29        let entry = repeating(
30            || Input::new("Say"),
31            move |line: String, _| {
32                let line = line.trim().to_string();
33                if !line.is_empty() {
34                    said.update(|s| s.push(line));
35                }
36            },
37        );
38        let lines = text(move || {
39            said.with(|s| {
40                if s.is_empty() {
41                    "[muted]Nothing yet: type above and press Enter.".to_string()
42                } else {
43                    s.iter()
44                        .rev()
45                        .map(|line| format!("[accent]•[/] {}", escape(line)))
46                        .collect::<Vec<_>>()
47                        .join("\n")
48                }
49            })
50        });
51        let counter = text!("[b]{count}[/]  [muted]+ and - change it; a click adds one")
52            .focus_style("reverse")
53            .on_key("+", move |_| count.update(|c| *c += 1))
54            .on_key("-", move |_| count.update(|c| *c -= 1))
55            .on_click(move |_| count.update(|c| *c += 1));
56
57        column([
58            text!("Up for [b]{seconds}[/] s in this tab")
59                .panel("Clock")
60                .fixed(3),
61            entry.panel("Say something").fixed(3),
62            counter.panel("Counter").fixed(3),
63            lines.panel("Said"),
64            label("[muted]Tab moves · Ctrl+Q ends this tab's session").auto(),
65        ])
66        .on_key("ctrl+q", |cx| cx.quit())
67    })
68}
69
70fn main() -> std::io::Result<()> {
71    let addr = std::env::args()
72        .nth(1)
73        .unwrap_or_else(|| "127.0.0.1:8080".to_string());
74    rich_web::Server::bind(addr.as_str(), app)?
75        .title("rs-rich-web example")
76        .run()
77}