about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-09-18T16·23+0300
committertazjin <tazjin@tvl.su>2022-09-18T16·40+0000
commitbb47baf638c96d133dae51827ff676166d818153 (patch)
tree6f22d62769d8c75ff2885912fea00eeecffffbdd
parent993c22de5990a6522794647522b221f4fde6c770 (diff)
feat(corp/tvixbolt): persist state in tvixbolt's URL r/4900
This makes it possible to enter something into tvixbolt and then share
the link with someone else.

Suggested by Profpatsch originally.

Change-Id: I9886e76a7b821070f13ea7005df09188821e091d
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6636
Tested-by: BuildkiteCI
Reviewed-by: Profpatsch <mail@profpatsch.de>
-rw-r--r--corp/tvixbolt/Cargo.lock1
-rw-r--r--corp/tvixbolt/Cargo.toml4
-rw-r--r--corp/tvixbolt/src/main.rs28
3 files changed, 23 insertions, 10 deletions
diff --git a/corp/tvixbolt/Cargo.lock b/corp/tvixbolt/Cargo.lock
index 4f52a73cfd52..e6572fc03d09 100644
--- a/corp/tvixbolt/Cargo.lock
+++ b/corp/tvixbolt/Cargo.lock
@@ -592,6 +592,7 @@ version = "0.1.0"
 dependencies = [
  "codemap",
  "rnix",
+ "serde",
  "serde_urlencoded",
  "tvix-eval",
  "wasm-bindgen",
diff --git a/corp/tvixbolt/Cargo.toml b/corp/tvixbolt/Cargo.toml
index 57eea8e1260a..fc7cedfd5846 100644
--- a/corp/tvixbolt/Cargo.toml
+++ b/corp/tvixbolt/Cargo.toml
@@ -22,3 +22,7 @@ rev = "7d0d929c22ad27bdcc0779afe445b541d3ce9631"
 [dependencies.tvix-eval]
 path = "../../tvix/eval"
 default-features = false
+
+[dependencies.serde]
+version = "*" # pinned by yew
+features = [ "derive" ]
diff --git a/corp/tvixbolt/src/main.rs b/corp/tvixbolt/src/main.rs
index 35e9d27921f9..8dad534a30a4 100644
--- a/corp/tvixbolt/src/main.rs
+++ b/corp/tvixbolt/src/main.rs
@@ -1,5 +1,6 @@
 use std::fmt::Write;
 
+use serde::{Deserialize, Serialize};
 use std::rc::Rc;
 use tvix_eval::observer::TracingObserver;
 use tvix_eval::observer::{DisassemblingObserver, NoOpObserver};
@@ -7,12 +8,14 @@ use web_sys::HtmlInputElement;
 use web_sys::HtmlTextAreaElement;
 use yew::prelude::*;
 use yew::TargetCast;
+use yew_router::{prelude::*, AnyRoute};
 
 enum Msg {
     CodeChange(String),
     ToggleTrace(bool),
 }
 
+#[derive(Clone, Serialize, Deserialize)]
 struct Model {
     code: String,
     trace: bool,
@@ -87,25 +90,30 @@ impl Component for Model {
     type Message = Msg;
     type Properties = ();
 
-    fn create(_ctx: &Context<Self>) -> Self {
-        Self {
-            code: String::new(),
-            trace: false,
-        }
+    fn create(_: &Context<Self>) -> Self {
+        BrowserHistory::new()
+            .location()
+            .query::<Self>()
+            .unwrap_or_else(|_| Self {
+                code: String::new(),
+                trace: false,
+            })
     }
 
-    fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
+    fn update(&mut self, _: &Context<Self>, msg: Self::Message) -> bool {
         match msg {
             Msg::ToggleTrace(trace) => {
                 self.trace = trace;
-                true
             }
 
             Msg::CodeChange(new_code) => {
                 self.code = new_code;
-                true
             }
         }
+
+        let _ = BrowserHistory::new().replace_with_query(AnyRoute::new("/"), self.clone());
+
+        true
     }
 
     fn view(&self, ctx: &Context<Self>) -> Html {
@@ -128,8 +136,8 @@ impl Component for Model {
                              Msg::CodeChange(ta)
 
                          })}
-                         id="code" cols="30" rows="10">
-                        </textarea>
+                         id="code" cols="30" rows="10" value={self.code.clone()}>
+                         </textarea>
                     </div>
 
                     <div class="form-group">