revamp the way page:treehouse/new works
- treehouse/new is now a regular page, not a special template - most of the code related to the `new` badge in page:index has been removed - you're meant to discern between pages you've read vs ones you haven't by looking at the colors of the links (blue vs purple)
This commit is contained in:
		
							parent
							
								
									8d1deee626
								
							
						
					
					
						commit
						e201ea7058
					
				
					 6 changed files with 128 additions and 362 deletions
				
			
		| 
						 | 
				
			
			@ -1,133 +1,159 @@
 | 
			
		|||
%% template = "_new.hbs"
 | 
			
		||||
   title = "a curated feed of updates to the house"
 | 
			
		||||
   styles = ["new.css"]
 | 
			
		||||
   feed = "news"
 | 
			
		||||
%% title = "a curated feed of updates to the house"
 | 
			
		||||
styles = ["new.css"]
 | 
			
		||||
 | 
			
		||||
% id = "01J4J5N6WZQ03VTB3TZ51J7QZK"
 | 
			
		||||
- [featured]{.badge .blue} I was bored over a weekend, so I decided to write the tiniest programming language I could imagine.
 | 
			
		||||
it came out looking pretty Lispy, and I'm glad about that!
 | 
			
		||||
I learned a ton about Lisps in the process of researching it.
 | 
			
		||||
even though it didn't end up having macros...
 | 
			
		||||
% id = "01JCGWPM6T73PAC5Q8YHPBEAA1"
 | 
			
		||||
+ hello!
 | 
			
		||||
if you've been wondering what I've been up to, you've come to the right place.
 | 
			
		||||
 | 
			
		||||
### haku - writing a little programming language for fun
 | 
			
		||||
    % id = "01JCGWPM6T3W07KAGG3J29JMVF"
 | 
			
		||||
    - posts are sorted from newest to oldest.
 | 
			
		||||
 | 
			
		||||
[read][page:programming/blog/haku]
 | 
			
		||||
    % id = "01JCGWPM6TGQ17JPSJW8G58SB0"
 | 
			
		||||
    - you can keep track of which posts you've read by looking at the color of the links.
 | 
			
		||||
 | 
			
		||||
    % id = "01JCGWPM6TMAJT0B50GQSA4BDW"
 | 
			
		||||
    - there is currently no RSS or Atom feed for this page, sorry!
 | 
			
		||||
 | 
			
		||||
% id = "01JBAGZAZ30K443QYPK0XBNZWM"
 | 
			
		||||
- ### the curious case of Amon Tobin's Creatures
 | 
			
		||||
- ### [the curious case of Amon Tobin's Creatures][page:music/creatures]
 | 
			
		||||
 | 
			
		||||
a weird anomaly I noticed while listening to some breaks
 | 
			
		||||
 | 
			
		||||
[read][page:music/creatures]
 | 
			
		||||
    % id = "01JBAGZAZ3NKBED4M9FANR5RPZ"
 | 
			
		||||
    - a weird anomaly I noticed while listening to some breaks
 | 
			
		||||
 | 
			
		||||
% id = "01J8ZP2EG9TM8320R9E3K1GQEC"
 | 
			
		||||
- I was listening to Oneohtrix Point Never's _Magic Oneohtrix Point Never_, and had some retrospective thoughts about the distorted vocals in...
 | 
			
		||||
- ### [I Don't Love Me Anymore][page:music/reviews/opn/i-dont-love-me-anymore]
 | 
			
		||||
 | 
			
		||||
### I Don't Love Me Anymore
 | 
			
		||||
    % id = "01J8ZP2EG96VQ2ZK0XYK0FK1NR"
 | 
			
		||||
    - I was listening to Oneohtrix Point Never's _Magic Oneohtrix Point Never_, and had some retrospective thoughts about the vocals in this song.
 | 
			
		||||
 | 
			
		||||
it's also a nice opportunity to say that I've refreshed the music section a bit!
 | 
			
		||||
 | 
			
		||||
[read][page:music/reviews/opn/i-dont-love-me-anymore]
 | 
			
		||||
    % id = "01J8ZP2EG92T1SM7F6MTCXZHNJ"
 | 
			
		||||
    - it's also a nice opportunity to say that I've refreshed the music section a bit!
 | 
			
		||||
 | 
			
		||||
% id = "01J7C1KBZ58BR21AVFA1PMWV68"
 | 
			
		||||
- I like lean websites. did you know that?
 | 
			
		||||
- ### [not quite buildless][page:programming/blog/buildsome]
 | 
			
		||||
 | 
			
		||||
I also really like lean websites that are simple in construction and deployment. did you know the treehouse is a website like that?
 | 
			
		||||
    % id = "01J7C1KBZ5XKZRN4V5BWFQTV6Y"
 | 
			
		||||
    - I like lean websites. did you know that?
 | 
			
		||||
 | 
			
		||||
so I've decided to write up a few anecdotes and other cool stories about the treehouse's inner workings.
 | 
			
		||||
    % id = "01J7C1KBZ50EMBK9VPH9CE3F7H"
 | 
			
		||||
    - I also really like lean websites that are simple in construction and deployment. did you know the treehouse is a website like that?
 | 
			
		||||
 | 
			
		||||
also, it's (way past) its one year anniversary! hooray!
 | 
			
		||||
    % id = "01J7C1KBZ5QCVM6DDT9G5KQGP2"
 | 
			
		||||
    - so I've decided to write up a few anecdotes and other cool stories about the treehouse's inner workings.
 | 
			
		||||
 | 
			
		||||
### not quite buildless
 | 
			
		||||
 | 
			
		||||
[read][page:programming/blog/buildsome]
 | 
			
		||||
    % id = "01J7C1KBZ5S0XTQXKY41VZNWJZ"
 | 
			
		||||
    - also, it's (way past) its one year anniversary! hooray!
 | 
			
		||||
 | 
			
		||||
% id = "01J73BSWA15KHTQ21T0S14NZW0"
 | 
			
		||||
- I decided to write up some ideas on what sort of cool data analysis I could do on my [ListenBrainz data set][def:social/listenbrainz].
 | 
			
		||||
I haven't done any of it yet, but I thought it'd be cool to share my ideas anyways!
 | 
			
		||||
- ### [the ListenBrainz data set][page:music/brainz]
 | 
			
		||||
 | 
			
		||||
### the ListenBrainz data set
 | 
			
		||||
    % id = "01J73BSWA1EX7ZP28KCCG088DD"
 | 
			
		||||
    - I decided to write up some ideas on what sort of cool data analysis I could do on my [ListenBrainz data set][def:social/listenbrainz].
 | 
			
		||||
 | 
			
		||||
[read][page:music/brainz]
 | 
			
		||||
    % id = "01J73BSWA1ANRQ31DNYHTNPSP5"
 | 
			
		||||
    - I haven't done any of it yet, but I thought it'd be cool to share my ideas anyways!
 | 
			
		||||
 | 
			
		||||
% id = "01J4J5N6WZQ03VTB3TZ51J7QZK"
 | 
			
		||||
- ### [haku - writing a little programming language for fun][page:programming/blog/haku]
 | 
			
		||||
 | 
			
		||||
   % id = "01J4J5N6WZQ1316WKDXB1M5W6E"
 | 
			
		||||
   - I was bored over a weekend, so I decided to write the tiniest programming language I could imagine.
 | 
			
		||||
 | 
			
		||||
       % id = "01J4J5N6WZ2RW32HJX1VBJM58X"
 | 
			
		||||
       - it came out looking pretty Lispy, and I'm glad about that!
 | 
			
		||||
 | 
			
		||||
   % id = "01J4J5N6WZV6E1AHF65PQ5J6GF"
 | 
			
		||||
   - I learned a ton about Lisps in the process of researching it.
 | 
			
		||||
   even though it didn't end up having macros...
 | 
			
		||||
 | 
			
		||||
% id = "01J293BFEBT15W0Z3XF1HEFGZT"
 | 
			
		||||
- sometimes people call me crazy for saying that bashing JavaScript is senseless and that it's not as bad of a language as people make it out to be.
 | 
			
		||||
so I decided to collect my thoughts into a nice little page I can link easily.
 | 
			
		||||
- ### [JavaScript is not as bad as people make it out to be][page:programming/languages/javascript]
 | 
			
		||||
 | 
			
		||||
### JavaScript is not as bad as people make it out to be
 | 
			
		||||
 | 
			
		||||
[why dude why][page:programming/languages/javascript]
 | 
			
		||||
    % id = "01J293BFEB4G7214N20SZA8V7W"
 | 
			
		||||
    - sometimes people call me crazy for saying that bashing JavaScript is senseless and that it's not as bad of a language as people make it out to be.
 | 
			
		||||
    
 | 
			
		||||
        % id = "01J293BFEBYSW4K7YHVN42J3WP"
 | 
			
		||||
        - so I decided to collect my thoughts into a nice little page I can link easily.
 | 
			
		||||
 | 
			
		||||
% id = "01J0VNHPTRNC1HFXAQ790Y1EZB"
 | 
			
		||||
- a friend of mine asked if it makes sense to define your own wrapper class for `SDL_Window` the way [Lazy Foo](https://lazyfoo.net/tutorials/SDL/10_color_keying/index.php) does it.
 | 
			
		||||
I told him there's no reason to do that in modern C++, because `std::unique_ptr` can do everything for you anyways.
 | 
			
		||||
- ### [freeing C memory automatically using `std::unique_ptr` and `std::shared_ptr`][page:programming/languages/cxx/shared-unique-ptr-deleter]
 | 
			
		||||
 | 
			
		||||
### freeing C memory automatically using `std::unique_ptr` and `std::shared_ptr`
 | 
			
		||||
    % id = "01J0VNHPTRP51XYDA4N2RPG58F"
 | 
			
		||||
    - a friend of mine asked if it makes sense to define your own wrapper class for `SDL_Window` the way [Lazy Foo](https://lazyfoo.net/tutorials/SDL/10_color_keying/index.php) does it.
 | 
			
		||||
 | 
			
		||||
~on another note, I did read a blog post about this once somewhere, but couldn't be bothered to find it. so there you go! I made a post about this too.~
 | 
			
		||||
        % id = "01J0VNHPTRW3XR4YG0GWGFF4N4"
 | 
			
		||||
        - I told him there's no reason to do that in modern C++, because `std::unique_ptr` can do everything for you anyways.
 | 
			
		||||
 | 
			
		||||
[read][page:programming/languages/cxx/shared-unique-ptr-deleter]
 | 
			
		||||
    % id = "01J0VNHPTRMXFTH3F601R7V1S9"
 | 
			
		||||
    - on another note, I did read a blog post about this once somewhere, but couldn't be bothered to find it. so there you go! I made a post about this too.
 | 
			
		||||
 | 
			
		||||
% id = "01J0KRPMV7SS48B64BFCJZK7VQ"
 | 
			
		||||
- it's updatin' time! I took some time to clean up old pages and update my _about me_.\
 | 
			
		||||
over time I've been learning how to write content on the treehouse effectively, and the new about me reflects that.
 | 
			
		||||
- ### [about me (version 2)][page:about]
 | 
			
		||||
 | 
			
		||||
### about me (version 2)
 | 
			
		||||
    % id = "01J0KRPMV73K71D3QXFQ3GNY2N"
 | 
			
		||||
    - it's updatin' time! I took some time to clean up old pages and update my _about me_.\
 | 
			
		||||
    over time I've been learning how to write content on the treehouse effectively, and the new about me reflects that.
 | 
			
		||||
 | 
			
		||||
[read][page:about] [version 1][page:about/v1]
 | 
			
		||||
    % id = "01J0KRPMV7KD7X3HHXGKBS0VAX"
 | 
			
		||||
    - [version 1][page:about/v1]
 | 
			
		||||
 | 
			
		||||
% id = "01HY5R1ZW2PYZSSP2J2KAA23DA"
 | 
			
		||||
- I recently got a question from my someone telling me they doesn't understand why `*x` does not read from the pointer `x` when on the left-hand side of an assignment.
 | 
			
		||||
and that made me think,
 | 
			
		||||
- ### [what's up with `*x` not always meaning the same thing in different contexts?][page:programming/blog/lvalues]
 | 
			
		||||
 | 
			
		||||
### what's up with `*x` not always meaning the same thing in different contexts?
 | 
			
		||||
 | 
			
		||||
[read][page:programming/blog/lvalues]
 | 
			
		||||
    % id = "01HY5R1ZW24YJ2NF2RYWRZG4ZT"
 | 
			
		||||
    - I recently got a question from my someone telling me they doesn't understand why `*x` does not read from the pointer `x` when on the left-hand side of an assignment.
 | 
			
		||||
    and that made me think, _why_ is that the case?
 | 
			
		||||
 | 
			
		||||
% id = "01HV1DGFHZ65GJVQRSREKR67J9"
 | 
			
		||||
- I've been thinking recently how cool it is to be able to single-step into Unreal Engine's source code and edit it while you're working with it, and how uncool it is that I can't do the same thing easily in the Rust world.
 | 
			
		||||
- ### [systems are just a bunch of code][page:programming/blog/systems]
 | 
			
		||||
 | 
			
		||||
after all, aren't we just dealing with a bunch of code running on the computer? why not let me poke at it?
 | 
			
		||||
    % id = "01HV1DGFHZFFZSQNCVWBTJ1VHM"
 | 
			
		||||
    - I've been thinking recently how cool it is to be able to single-step into Unreal Engine's source code and edit it while you're working with it, and how uncool it is that I can't do the same thing easily in the Rust world.
 | 
			
		||||
 | 
			
		||||
### systems are just a bunch of code
 | 
			
		||||
        % id = "01HV1DGFHZGFYWT5MMM57SEWNN"
 | 
			
		||||
        - after all, aren't we just dealing with a bunch of code running on the computer? why not let me poke at it?
 | 
			
		||||
 | 
			
		||||
[can _you_ can read other people's code?][page:programming/blog/systems] [bonus: dismantling Unreal Engine's GENERATED_BODY][page:programming/technologies/unreal-engine/generated-body]
 | 
			
		||||
    % id = "01HV1DGFHZ2SDPDV3VYRR7VBRR"
 | 
			
		||||
    - bonus: [dismantling Unreal Engine's `GENERATED_BODY`][page:programming/technologies/unreal-engine/generated-body]
 | 
			
		||||
 | 
			
		||||
% id = "01HTWNETT2S5NSBF3QR4HYA7HN"
 | 
			
		||||
- last night I couldn't sleep because of type theory. in the process of trying to write down my thoughts, I ended up discovering a class of types which, to my knowledge, no language implements.
 | 
			
		||||
- ### [OR-types][page:programming/blog/or-types]
 | 
			
		||||
 | 
			
		||||
### OR-types
 | 
			
		||||
 | 
			
		||||
[what the hell do you mean, aren't sum types exactly that??][page:programming/blog/or-types]
 | 
			
		||||
    % id = "01HTWNETT2N8NPENETWYFBTXEM"
 | 
			
		||||
    - last night I couldn't sleep because of type theory. in the process of trying to write down my thoughts, I ended up discovering a class of types which, to my knowledge, no language implements.
 | 
			
		||||
 | 
			
		||||
% id = "01HRG3VN091V715A8T54QK5PVX"
 | 
			
		||||
- I really like Lua, did you know that? but I get kind of tired of explaining why a thousand times to people who don't know the language, so…
 | 
			
		||||
- ### [programming languages: Lua][page:programming/languages/lua]
 | 
			
		||||
 | 
			
		||||
### programming languages: Lua
 | 
			
		||||
 | 
			
		||||
[read why I like it so much][page:programming/languages/lua]
 | 
			
		||||
    % id = "01HRG3VN095BNHERHWVX1TKS9K"
 | 
			
		||||
    - I really like Lua, did you know that? but I get kind of tired of explaining why a thousand times to people who don't know the language, so here's a page with my thoughts!
 | 
			
		||||
 | 
			
		||||
% id = "01HR9ZTS8RS4VJNJYSNRQYSKHZ"
 | 
			
		||||
- sidebars! also known as, _"enjoying the main content? how about I distract you from it so that you can't focus!"_\
 | 
			
		||||
seriously though. I don't like them.
 | 
			
		||||
- ### [design: sidebars][page:design/sidebars]
 | 
			
		||||
 | 
			
		||||
### design: sidebars
 | 
			
		||||
 | 
			
		||||
[read why I don't like them so much][page:design/sidebars]
 | 
			
		||||
    % id = "01HR9ZTS8RY3N4EJM5W7WBTF0G"
 | 
			
		||||
    - sidebars! also known as, _"enjoying the main content? how about I distract you from it so that you can't focus!"_
 | 
			
		||||
    
 | 
			
		||||
        % id = "01HR9ZTS8RQ1EN0THYEVNQRY2A"
 | 
			
		||||
        - seriously though. I don't like them.
 | 
			
		||||
 | 
			
		||||
% id = "01HQ8KV8T8GRCVFDJ3EP6QE163"
 | 
			
		||||
- I started a branch on user interface and user experience design, because I was working with mintty at work and had some thoughts about it.
 | 
			
		||||
- ### [liquidex's treehouse: design][page:design]
 | 
			
		||||
 | 
			
		||||
"why does mintty always feel so _out of place_ compared to `cmd.exe`?"
 | 
			
		||||
    % id = "01HQ8KV8T8EEX6XBG2K1X3FGKW"
 | 
			
		||||
    - I started a branch on user interface and user experience design, because I was working with mintty at work and had some thoughts about it.
 | 
			
		||||
 | 
			
		||||
### liquidex's treehouse: design
 | 
			
		||||
    "why does mintty always feel so _out of place_ compared to `cmd.exe`?"
 | 
			
		||||
 | 
			
		||||
[read: _on digital textures_][page:design/digital-textures] [go to branch][page:design]
 | 
			
		||||
        % id = "01HQ8KV8T865WKME5R9TD0DSTN"
 | 
			
		||||
        - I also wrote a post summarising my thoughts: [_on digital textures_][page:design/digital-textures]
 | 
			
		||||
 | 
			
		||||
% id = "01HQ6G30PTVT5H0Z04VVRHEZQF"
 | 
			
		||||
- ever wondered how Terraria renders its worlds? or how editors like Tiled manage to make painting tiles so easy?
 | 
			
		||||
- ### [tairu - an interactive exploration of 2D autotiling techniques][page:programming/blog/tairu]
 | 
			
		||||
 | 
			
		||||
### tairu - an interactive exploration of 2D autotiling techniques
 | 
			
		||||
    % id = "01HQ6G30PTG8QA5MAPEJPWSM14"
 | 
			
		||||
    - ever wondered how Terraria renders its worlds? or how editors like Tiled manage to make painting tiles so easy?
 | 
			
		||||
 | 
			
		||||
[read][page:programming/blog/tairu]
 | 
			
		||||
        % id = "01HQ6G30PT1D729Z29NYVDCFDB"
 | 
			
		||||
        - this post explores basically just that.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,134 +1,33 @@
 | 
			
		|||
/* Give the intro and outro some breathing room. */
 | 
			
		||||
section {
 | 
			
		||||
    padding: 1em 2em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Style all links in the last paragraph as big buttons. */
 | 
			
		||||
.tree th-bc>p:last-child {
 | 
			
		||||
    --transition-duration: 0.2s;
 | 
			
		||||
 | 
			
		||||
    margin-top: var(--8px);
 | 
			
		||||
    margin-bottom: var(--4px);
 | 
			
		||||
 | 
			
		||||
    &>a {
 | 
			
		||||
        display: inline-block;
 | 
			
		||||
 | 
			
		||||
        padding: 0.5em 1.5em;
 | 
			
		||||
 | 
			
		||||
        color: var(--text-color);
 | 
			
		||||
        background-color: transparent;
 | 
			
		||||
        border: var(--1px) solid var(--border-1);
 | 
			
		||||
        border-radius: 2em;
 | 
			
		||||
        text-decoration: none;
 | 
			
		||||
 | 
			
		||||
        transition:
 | 
			
		||||
            color var(--transition-duration),
 | 
			
		||||
            background-color var(--transition-duration),
 | 
			
		||||
            border-color var(--transition-duration);
 | 
			
		||||
 | 
			
		||||
        &:hover,
 | 
			
		||||
        &:focus {
 | 
			
		||||
            color: white;
 | 
			
		||||
            background-color: #058ef0;
 | 
			
		||||
            border-color: white;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.tree li>div:first-child,
 | 
			
		||||
.tree li>details>summary:first-child {
 | 
			
		||||
    --margin: 2.5em;
 | 
			
		||||
 | 
			
		||||
    border: none;
 | 
			
		||||
    margin-left: var(--tree-indent-width);
 | 
			
		||||
    width: calc(100% - var(--tree-indent-width));
 | 
			
		||||
    margin-top: var(--margin);
 | 
			
		||||
    margin-bottom: var(--margin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.tree th-bp {
 | 
			
		||||
    display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.tree th-bb {
 | 
			
		||||
    opacity: 100%;
 | 
			
		||||
 | 
			
		||||
    & .branch-date {
 | 
			
		||||
        display: block !important;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (max-width: 600px) {
 | 
			
		||||
    .tree .branch-container {
 | 
			
		||||
        flex-direction: column-reverse;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
section.settings {
 | 
			
		||||
    & h3 {
 | 
			
		||||
        display: inline;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & details>summary {
 | 
			
		||||
        --recursive-wght: 700;
 | 
			
		||||
 | 
			
		||||
        list-style: none;
 | 
			
		||||
        cursor: pointer;
 | 
			
		||||
 | 
			
		||||
        opacity: 50%;
 | 
			
		||||
        transition: opacity var(--transition-duration);
 | 
			
		||||
 | 
			
		||||
        &::-webkit-details-marker {
 | 
			
		||||
            display: none;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &::before {
 | 
			
		||||
            --recursive-casl: 0.0;
 | 
			
		||||
            --recursive-mono: 1.0;
 | 
			
		||||
            --recursive-slnt: 0.0;
 | 
			
		||||
 | 
			
		||||
            content: '+';
 | 
			
		||||
            margin-right: 0.3em;
 | 
			
		||||
 | 
			
		||||
            opacity: 50%;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &:hover {
 | 
			
		||||
            opacity: 100%;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & details[open]>summary {
 | 
			
		||||
.tree .branch-container {
 | 
			
		||||
    &:has(th-bc > h3) > th-bb {
 | 
			
		||||
        opacity: 100%;
 | 
			
		||||
 | 
			
		||||
        &::before {
 | 
			
		||||
            content: '-';
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & p {
 | 
			
		||||
        margin-bottom: var(--8px);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & button {
 | 
			
		||||
        border: var(--1px) solid var(--border-1);
 | 
			
		||||
        border-radius: 999px;
 | 
			
		||||
        padding: var(--4px) var(--12px);
 | 
			
		||||
        background: none;
 | 
			
		||||
        color: var(--text-color);
 | 
			
		||||
        font-size: 1rem;
 | 
			
		||||
 | 
			
		||||
        cursor: pointer;
 | 
			
		||||
 | 
			
		||||
        transition:
 | 
			
		||||
            color var(--transition-duration),
 | 
			
		||||
            background-color var(--transition-duration),
 | 
			
		||||
            border-color var(--transition-duration);
 | 
			
		||||
 | 
			
		||||
        &:hover {
 | 
			
		||||
            color: white;
 | 
			
		||||
            background-color: #058ef0;
 | 
			
		||||
            border-color: white;
 | 
			
		||||
        & .branch-date {
 | 
			
		||||
            display: block !important;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (max-width: 720px) {
 | 
			
		||||
    .tree .branch-container {
 | 
			
		||||
        &:has(th-bc > h3) {
 | 
			
		||||
            flex-direction: column;
 | 
			
		||||
            padding-left: 1rem;
 | 
			
		||||
            padding-top: 0.25rem;
 | 
			
		||||
            padding-bottom: 0.25rem;
 | 
			
		||||
 | 
			
		||||
            & > th-bp {
 | 
			
		||||
                display: none;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            & > th-bc > h3 {
 | 
			
		||||
                margin-top: 0;
 | 
			
		||||
                margin-bottom: 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            & > th-bb {
 | 
			
		||||
                margin: 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,71 +0,0 @@
 | 
			
		|||
// news.js because new.js makes the TypeScript language server flip out.
 | 
			
		||||
// Likely because `new` is a keyword, but also, what the fuck.
 | 
			
		||||
 | 
			
		||||
import { addSpell, spell } from "treehouse/spells.js";
 | 
			
		||||
import { getSettingValue } from "treehouse/settings.js";
 | 
			
		||||
import { Branch } from "treehouse/tree.js";
 | 
			
		||||
 | 
			
		||||
const seenStatesKey = "treehouse.news.seenBranches";
 | 
			
		||||
const seenStates = new Set(JSON.parse(localStorage.getItem(seenStatesKey)) || []);
 | 
			
		||||
 | 
			
		||||
let seenCount = seenStates.size;
 | 
			
		||||
let unseenCount = TREEHOUSE_NEWS_COUNT - seenCount;
 | 
			
		||||
 | 
			
		||||
function saveSeenStates() {
 | 
			
		||||
    localStorage.setItem(seenStatesKey, JSON.stringify(Array.from(seenStates)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function markAsRead(branch) {
 | 
			
		||||
    let branchData = spell(branch, Branch);
 | 
			
		||||
 | 
			
		||||
    if (!seenStates.has(branchData.namedID) && seenCount > 0) {
 | 
			
		||||
        let badge = document.createElement("span");
 | 
			
		||||
        badge.classList.add("badge", "red", "before-content");
 | 
			
		||||
        badge.textContent = "new";
 | 
			
		||||
 | 
			
		||||
        branchData.branchContent.firstChild.insertBefore(badge, branchData.branchContent.firstChild.firstChild);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    seenStates.add(branchData.namedID);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function initNewsPage() {
 | 
			
		||||
    for (let [_, branch] of Branch.branchesByNamedID) {
 | 
			
		||||
        markAsRead(branch);
 | 
			
		||||
    }
 | 
			
		||||
    saveSeenStates();
 | 
			
		||||
 | 
			
		||||
    // If any branches are added past the initial load, add them to the seen set too.
 | 
			
		||||
    Branch.onAdded.push(branch => {
 | 
			
		||||
        markAsRead(branch);
 | 
			
		||||
        saveSeenStates();
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function markAllAsUnread() {
 | 
			
		||||
    localStorage.removeItem(seenStatesKey);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
addSpell("new", class New {
 | 
			
		||||
    constructor(element) {
 | 
			
		||||
        // Do not show the badge to people who have never seen any news.
 | 
			
		||||
        // It's just annoying in that case.
 | 
			
		||||
        // In case you do not wish to see the badge anymore, go to the news page and uncheck the
 | 
			
		||||
        // checkbox at the bottom.
 | 
			
		||||
        let userSawNews = seenCount > 0;
 | 
			
		||||
        let userWantsToSeeNews = getSettingValue("showNewPostIndicator");
 | 
			
		||||
        if (userSawNews && userWantsToSeeNews && unseenCount > 0) {
 | 
			
		||||
            this.newText = document.createElement("span");
 | 
			
		||||
            this.newText.classList.add("new-text");
 | 
			
		||||
            this.newText.textContent = element.textContent;
 | 
			
		||||
            element.textContent = "";
 | 
			
		||||
            element.appendChild(this.newText);
 | 
			
		||||
 | 
			
		||||
            this.badge = document.createElement("span");
 | 
			
		||||
            this.badge.classList.add("badge", "red");
 | 
			
		||||
            this.badge.textContent = unseenCount.toString();
 | 
			
		||||
            element.appendChild(this.badge);
 | 
			
		||||
            element.classList.add("has-news");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -1,72 +0,0 @@
 | 
			
		|||
<!DOCTYPE html>
 | 
			
		||||
 | 
			
		||||
<html lang="en-US" prefix="og: https://ogp.me/ns#">
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
    {{> components/_head.hbs }}
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
    {{#> components/_nav.hbs }}
 | 
			
		||||
 | 
			
		||||
    {{!-- For /index, include a "new" link that goes to the curated news feed page. --}}
 | 
			
		||||
    {{#if (eq page.tree_path "index")}}
 | 
			
		||||
    <a href="{{ config.site }}/treehouse/new" data-cast="new">new</a>
 | 
			
		||||
    {{/if}}
 | 
			
		||||
 | 
			
		||||
    {{/ components/_nav.hbs }}
 | 
			
		||||
 | 
			
		||||
    {{> components/_noscript.hbs }}
 | 
			
		||||
 | 
			
		||||
    <section>
 | 
			
		||||
        <p>welcome!</p>
 | 
			
		||||
        <p>since you clicked here, you must be curious as to what's been going on since your last visit to the house. so
 | 
			
		||||
            here's a recap just for you - enjoy!</p>
 | 
			
		||||
    </section>
 | 
			
		||||
 | 
			
		||||
    {{> components/_tree.hbs }}
 | 
			
		||||
 | 
			
		||||
    <section>
 | 
			
		||||
        <p>note that this page does not include any updates that were made to the website itself - for that, you can
 | 
			
		||||
            visit <a href="{{ config.site }}/treehouse/changelog">the changelog</a>.
 | 
			
		||||
        </p>
 | 
			
		||||
    </section>
 | 
			
		||||
 | 
			
		||||
    <section class="settings" data-cast="js">
 | 
			
		||||
        <details>
 | 
			
		||||
            <summary>
 | 
			
		||||
                settings
 | 
			
		||||
            </summary>
 | 
			
		||||
            <section>
 | 
			
		||||
                <p>if you find the newsfeed annoying, you can customize some aspects of it.</p>
 | 
			
		||||
                <p>
 | 
			
		||||
                    <input type="checkbox" data-cast="setting-checkbox" id="showNewPostIndicator">
 | 
			
		||||
                    <label for="showNewPostIndicator">show the <span class="badge red">1</span> badge on the homepage
 | 
			
		||||
                        for
 | 
			
		||||
                        new posts you haven't read yet</label>
 | 
			
		||||
                </p>
 | 
			
		||||
                <p>
 | 
			
		||||
                    <button id="mark-all-as-unread"
 | 
			
		||||
                        title="Mostly useful for debugging purposes, but it's there if you really wanna do it.">
 | 
			
		||||
                        mark all as unread</button>
 | 
			
		||||
                </p>
 | 
			
		||||
            </section>
 | 
			
		||||
        </details>
 | 
			
		||||
    </section>
 | 
			
		||||
 | 
			
		||||
    {{!-- For all pages except the one linked from the footer, include the footer icon. --}}
 | 
			
		||||
    {{#if (ne page.tree_path "treehouse")}}
 | 
			
		||||
    {{> components/_footer.hbs }}
 | 
			
		||||
    {{/if}}
 | 
			
		||||
 | 
			
		||||
    <script type="module" defer>
 | 
			
		||||
        import { initNewsPage, markAllAsUnread } from "{{ config.site }}/static/js/news.js";
 | 
			
		||||
        initNewsPage();
 | 
			
		||||
        document.getElementById("mark-all-as-unread").addEventListener("click", () => {
 | 
			
		||||
            markAllAsUnread();
 | 
			
		||||
            alert("congration! you done it");
 | 
			
		||||
        });
 | 
			
		||||
    </script>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +18,6 @@ clever to do while browser vendors figure that out, we'll just have to do a cach
 | 
			
		|||
 | 
			
		||||
<script>
 | 
			
		||||
    const TREEHOUSE_SITE = `{{ config.site }}`;
 | 
			
		||||
    const TREEHOUSE_NEWS_COUNT = {{ len feeds.news.branches }};
 | 
			
		||||
 | 
			
		||||
    {{!-- Yeah, this should probably be solved in a better way somehow.
 | 
			
		||||
    For now this is used to allow literate-programming.js to refer to syntax files with the ?cache attribute,
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +34,6 @@ clever to do while browser vendors figure that out, we'll just have to do a cach
 | 
			
		|||
    import "treehouse/settings.js";
 | 
			
		||||
    import "treehouse/tree.js";
 | 
			
		||||
    import "treehouse/emoji.js";
 | 
			
		||||
    import "treehouse/news.js";
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<meta property="og:site_name" content="{{ config.user.title }}">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,17 +3,3 @@
 | 
			
		|||
        {{{ include_static 'svg/object/logo.svg' }}}
 | 
			
		||||
    </a>
 | 
			
		||||
</nav>
 | 
			
		||||
 | 
			
		||||
{{!--
 | 
			
		||||
 | 
			
		||||
I don't have any idea where to put this right now.
 | 
			
		||||
There's no obvious place, and even when it is there, I hate the hideous red badge on new entries.
 | 
			
		||||
No time to figure it out. Will do later.
 | 
			
		||||
 | 
			
		||||
{{#if (eq page.tree_path 'index')}}
 | 
			
		||||
<nav id="nav-links">
 | 
			
		||||
    <a href="{{ config.site }}/treehouse/new" data-cast="new">new</a>
 | 
			
		||||
</nav>
 | 
			
		||||
{{/if}}
 | 
			
		||||
 | 
			
		||||
--}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue