From 582447e02b381c98492316280b9246f5ba67b363 Mon Sep 17 00:00:00 2001 From: lqdev Date: Tue, 22 Aug 2023 19:23:31 +0200 Subject: [PATCH] rework branches a bit to support saving --- content/2023-08-20-under-construction.tree | 2 +- content/about-treehouse.tree | 55 +++++++++++++------ content/about.tree | 8 +-- content/index.tree | 4 +- crates/treehouse/src/html/tree.rs | 14 +++-- crates/treehouse/src/state.rs | 1 - static/js/tree.js | 61 +++++++++++++++------- template/tree.hbs | 13 +---- 8 files changed, 99 insertions(+), 59 deletions(-) diff --git a/content/2023-08-20-under-construction.tree b/content/2023-08-20-under-construction.tree index 5fcaf6c..209f98f 100644 --- a/content/2023-08-20-under-construction.tree +++ b/content/2023-08-20-under-construction.tree @@ -1 +1 @@ -- section under construction. sorry! in the meantime, maybe you wanna read [my ramblings about the treehouse](#01H89RFHCQCD3E1XS5XAPW86J5)? +- section under construction. sorry! in the meantime, maybe you wanna read [my ramblings about the treehouse][b:01H89RFHCQCD3E1XS5XAPW86J5]? diff --git a/content/about-treehouse.tree b/content/about-treehouse.tree index b0ce9b5..3625b33 100644 --- a/content/about-treehouse.tree +++ b/content/about-treehouse.tree @@ -136,8 +136,10 @@ % id = "01H89RFHCQ2GWJPTAKTRGS1QAC" - weird poems and philosophical talk are over, it's time to focus on the tech. + - call this an overview, Defense of Design, or what have you + % id = "01H89RFHCQF4N9T05B9DVWX67K" - - treehouse is built in the programming language that gives me the most pleasure while developing. + - treehouse is built in the programming language that gives me the most pleasure coding. - no need for you to know more. :shhh: @@ -149,10 +151,10 @@ - but being the altruist I am - don't worry, it _will_ be open source one day. - in case you're reading this in the far future, and this is still here… - you wouldn't mind [dropping me a line](#01H89P3CH8CD28KGX9GVRFK60E) would you? + you wouldn't mind [dropping me a line][b:01H89P3CH8CD28KGX9GVRFK60E] would you? % id = "01H89RFHCQAQVXP6B2H0T8NNDS" - - personally… the language you build a personal project in almost never matters. it's rather how you execute your ideas. + - personally… the language you build a personal project with almost never matters. it's rather how you execute your ideas. + therefore I find boasting that my project is powered by a `$LANGUAGE` or a `$FRAMEWORK` unnecessary. @@ -162,7 +164,7 @@ - (yes, I know that website is super old, but I still find it incredibly funny :hueh:) % id = "01H89RFHCQFWC2FWBAE9PVNC08" - - as I alluded to [here](#01H89RFHCQ3EAP0F6PRSEK7S1T), treehouse is built to decay gracefully + - as I alluded to [here][b:01H89RFHCQ3EAP0F6PRSEK7S1T], treehouse is built to decay gracefully as you take away the fancy parts. - you will be able to read it just fine without JavaScript, just that it'll be a little @@ -185,6 +187,14 @@ - if you have accessibility concerns about this decision, please let me know. + - it also saves your progress as you read. if you refresh the page, you'll notice you end up exactly where you left off! + + - but, there is one very crucial piece of JavaScript that makes this website tick, and your experience **will be degraded** if you disable it. that feature is linking to branches. + + - by default, if you link to an element by its id and it's contained within a `
`, the `
` will not expand. :ralsei_dead: + + - therefore there's a bit of JS to make that work, _and_ to tie that together with lazy loading. + - treehouse will not work *as* fine without CSS though - the `
` will look extremely janky, but the content should still be fully readable. @@ -193,20 +203,21 @@ - the structure of `.tree` files is extremely minimal. there are only a few syntactic features to speak of. - here's a taste of `.tree`: - ``` - \% id = "root" - \- this is a branch - \% id = "child" - \- this is a child branch + - ``` + \% id = "root" + \- this is a branch - \+ this is a branch that is collapsed + \% id = "child" + \- this is a child branch - \- and this is a child of that branch + \+ this is a branch that is collapsed - \% content.link = "some-other-tree" - \- and this branch links to another tree - ``` + \- and this is a child of that branch + + \% content.link = "some-other-tree" + \- and this branch links to another tree + ``` - the `.tree` format is line-based. that means the `%`, `-`, and `+` tokens are only interpreted when at the beginning of a line. @@ -219,15 +230,15 @@ - …may or may not be expanded by default (this is the branch's _kind_) - that's what the minus `-` and plus `+` tokens do - - …are sequenced like: optional attributes, kind, content + - each branch is constructed in this order: optional attributes, kind, content - - …end when another line beginning with `%`, `-`, or `+` is found. + - and ends when another line beginning with `%`, `-`, or `+` is found. - other than that, `.tree` assumes nothing about what format the branch attributes or content are encoded in. - I chose TOML and Markdown for their ease of use and flexibility, but the parser couldn't care less. - - …actually, that's a lie. see that code example above? Markdown code fences \`\`\` are handled specially to let you do that kind of stuff. that's all. + - …actually, that's a lie. see that code example above? Markdown code fences \`\`\` are handled specially to let embed `.tree` source code blocks within `.tree` files. that's all. - you may have noticed in that code example above that almost every branch has an `id` attribute. @@ -261,6 +272,16 @@ - which is cool because it's much denser while avoiding ambiguous characters - `0`, `O`, and `o` are all interpreted as `0` (zero). + - noticed how fast the treehouse restores your state? there's basically no delay. + + - this is because it restores your state _as it's loading in_, by using [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements). + + - despite many people calling that API extremely low-level, I beg to differ. it's actually pretty easy and pleasant to use. + + - most importantly it lets me enhance vanilla `
  • ` elements with custom behavior executed on load, which I use to restore your reading progress as the page is loading in. + + - linked branches also use Web Components by the way. + - while not strictly a technical topic, I'd like to shout out [Recursive](https://recursive.design) for being an awesome font :ralsei_love: - (not to be confused with Font Awesome, which I do not use here. icon designs are my own.) diff --git a/content/about.tree b/content/about.tree index 84fbd96..668a70d 100644 --- a/content/about.tree +++ b/content/about.tree @@ -97,10 +97,10 @@ - [DELTARUNE](https://deltarune.com) % id = "01H89P3CH89TQ3SFG2Z40J29HX" - - they're pretty great you should check them out (also check out [my games corner][page:/games]? :pleading_face:) + - they're pretty great you should check them out (also check out [my games corner][page:games]? :pleading_face:) % id = "01H89P3CH8AJATQ5DJBBFXJ1NH" - - or [music][page:/music] + - or [music][page:music] % id = "01H89P3CH8XQ59YZD3RFRYQ2BM" - various genres from electronic through jazz and even rock @@ -153,7 +153,7 @@ - anyways you can find me on % id = "01H89P3CH8EMM31JEMJRVRAKF4" - + Discord - username is [this](#01H89P3CH8GAHS8DDW1HHEWA3P) + + Discord - username is [this][b:01H89P3CH8GAHS8DDW1HHEWA3P] % id = "01H89P3CH89HHDVHGB9GE287TR" - I'm most active there so you'll have the best chance of getting a reply @@ -162,7 +162,7 @@ - you'll know it's me if you see a profile with a fluffy boy avatar % id = "01H89P3CH8WTBKXP0GGN0HYQK2" - + Matrix - username is [this](#01H89P3CH8943QGT52K7MRW12Q) at gacko.pl + + Matrix - username is [this][b:01H89P3CH8943QGT52K7MRW12Q] at gacko.pl % id = "01H89P3CH832E4GK0NJ77KED06" - I try to be as active there as on Discord but my availability may be a little more diff --git a/content/index.tree b/content/index.tree index 8c3198c..2e1aad9 100644 --- a/content/index.tree +++ b/content/index.tree @@ -3,11 +3,11 @@ - welcome! make yourself at home - - this is my treehouse, the place on the Internet I like to call home. + --- % id = "about" content.link = "about" - + ## about yourself + + ## about me % id = "about-treehouse" content.link = "about-treehouse" diff --git a/crates/treehouse/src/html/tree.rs b/crates/treehouse/src/html/tree.rs index c09f9d9..95a8835 100644 --- a/crates/treehouse/src/html/tree.rs +++ b/crates/treehouse/src/html/tree.rs @@ -31,17 +31,21 @@ pub fn branch_to_html(s: &mut String, treehouse: &mut Treehouse, file_id: FileId ); let class = if has_children { "branch" } else { "leaf" }; + let component = if let Content::Link(_) = attributes.content { + "th-b-linked" + } else { + "th-b" + }; + let linked_branch = if let Content::Link(link) = &attributes.content { - format!( - " is=\"th-linked-branch\" data-th-link=\"{}\"", - EscapeHtml(link) - ) + format!(" data-th-link=\"{}\"", EscapeHtml(link)) } else { String::new() }; + write!( s, - "
  • ", + "
  • ", EscapeAttribute(&id) ) .unwrap(); diff --git a/crates/treehouse/src/state.rs b/crates/treehouse/src/state.rs index 8defbea..f739862 100644 --- a/crates/treehouse/src/state.rs +++ b/crates/treehouse/src/state.rs @@ -6,7 +6,6 @@ use codespan_reporting::{ files::SimpleFiles, term::termcolor::{ColorChoice, StandardStream}, }; -use log::debug; use ulid::Ulid; pub type Files = SimpleFiles; diff --git a/static/js/tree.js b/static/js/tree.js index 94f218f..68c3de8 100644 --- a/static/js/tree.js +++ b/static/js/tree.js @@ -1,13 +1,41 @@ -class LinkedBranch extends HTMLLIElement { +const branchStateKey = "treehouse.openBranches"; +let branchState = JSON.parse(localStorage.getItem(branchStateKey)) || {}; + +function saveBranchIsOpen(branchID, state) { + branchState[branchID] = state; + localStorage.setItem(branchStateKey, JSON.stringify(branchState)); +} + +function branchIsOpen(branchID) { + return branchState[branchID]; +} + +class Branch extends HTMLLIElement { + constructor() { + super(); + + this.details = this.childNodes[0]; + this.innerUL = this.details.childNodes[1]; + + let isOpen = branchIsOpen(this.id); + if (isOpen !== undefined) { + this.details.open = isOpen; + } + this.details.addEventListener("toggle", _ => { + saveBranchIsOpen(this.id, this.details.open); + }); + } +} + +customElements.define("th-b", Branch, { extends: "li" }); + +class LinkedBranch extends Branch { constructor() { super(); this.linkedTree = this.getAttribute("data-th-link"); - this.details = this.childNodes[0]; - this.innerUL = this.details.childNodes[1]; - - this.state = "notloaded"; + this.loadingState = "notloaded"; this.loadingText = document.createElement("p"); { @@ -19,12 +47,13 @@ class LinkedBranch extends HTMLLIElement { this.innerUL.appendChild(this.loadingText); // This produces a warning during static generation but we still want to handle that - // correctly. Having an expanded-by-default linked block can be useful in development. + // correctly, as Branch saves the state in localStorage. Having an expanded-by-default + // linked block can be useful in development. if (this.details.open) { this.loadTree(); } - this.details.addEventListener("toggle", event => { + this.details.addEventListener("toggle", _ => { if (this.details.open) { this.loadTree(); } @@ -32,8 +61,8 @@ class LinkedBranch extends HTMLLIElement { } loadTree() { - if (this.state == "notloaded") { - this.state = "loading"; + if (this.loadingState == "notloaded") { + this.loadingState = "loading"; fetch(`/${this.linkedTree}.html`) .then(response => { @@ -46,26 +75,22 @@ class LinkedBranch extends HTMLLIElement { let parser = new DOMParser(); let linkedDocument = parser.parseFromString(text, "text/html"); let main = linkedDocument.getElementsByTagName("main")[0]; - let ul /*: Element */ = main.getElementsByTagName("ul")[0]; - console.log(ul); + let ul = main.getElementsByTagName("ul")[0]; this.loadingText.remove(); + this.innerUL.innerHTML = ul.innerHTML; - for (let i = 0; i < ul.childNodes.length; ++i) { - this.innerUL.appendChild(ul.childNodes[i]); - } - - this.state = "loaded"; + this.loadingState = "loaded"; }) .catch(error => { this.loadingText.innerText = error.toString(); - this.state = "error"; + this.loadingState = "error"; }); } } } -customElements.define("th-linked-branch", LinkedBranch, { extends: "li" }); +customElements.define("th-b-linked", LinkedBranch, { extends: "li" }); function expandDetailsRecursively(element) { while (element && element.tagName != "MAIN") { diff --git a/template/tree.hbs b/template/tree.hbs index 56f4cbb..61f24c4 100644 --- a/template/tree.hbs +++ b/template/tree.hbs @@ -33,18 +33,9 @@ miners.
    if you don't believe me, you're free to inspect the source yourself! all the scripts are written lovingly in vanilla JS (not minified!) by yours truly ❤️

    - and if this box is annoying, feel free to zap it with uBlock Origin or something. I have no + and if this box is annoying, feel free to block it with uBlock Origin or something. I have no way of remembering you closed it, and don't wanna host this site on a dynamic server. - - {{!--
    - -
    - --}} - {{!-- I disabled the button because I can't figure out a way to do this without storing a cookie, and I - don't like those. I'd prefer if this website were fully static. --}} - +