Skip to content

Commit

Permalink
feat: frontend overhaul (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hazel authored Apr 11, 2024
1 parent bc91f30 commit a4116cf
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 103 deletions.
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,9 @@
},
"[xml]": {
"editor.tabSize": 2
},
"[markdown]": {
"editor.formatOnSave": false,
"editor.tabSize": 2
}
}
80 changes: 43 additions & 37 deletions content/blog/2024-03-12.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,27 @@ If you’ve got keen eyes you might’ve noticed one of our Kickstarter goals go

Earlier this year, I’ve built the API for that — which is the actual brains. It handles things like storing and sorting the scores you submit, returning them in the right order, filtering them by song, user, score range, …

<aside>
<img src="/icons/new-alert_yellow.svg" alt="/icons/new-alert_yellow.svg" width="40px" />
<strong>Nerd stuff: Scalability</strong>

The API is written in Elixir using Phoenix Framework.
I chose this combination because it allows us to painlessly scale up in the future. For example, there are going to be a lot more people playing at once right after release, or after a new update.
The reason Elixir is great at this is thanks to BEAM, the virtual machine used by Erlang which Elixir is written on top of. Erlang was originally built for Ericsson (large Swedish telecom) with distributed systems (a lot more than one server running thing at once) in mind, and therefore makes it super easy to just add or remove capacity based on how many people are currently actively using it.

</aside>

<aside>
<img src="/icons/new-alert_yellow.svg" alt="/icons/new-alert_yellow.svg" width="40px" />
<strong>Nerd stuff: A little functional programming, as a treat</strong>

Another reason for this combination is developer experience.
Elixir follows functional programming paradigms, but in a way that feels very practical. You end up getting a lot of the benefits (avoiding side effects, straightforward state management, elegant recursive solutions) with not a lot of the usual drawbacks.
Phoenix Framework is a framework (duh) for making web applications, which is also incredibly convenient. It bundles a database driver, live updates via WebSockets, and frontend and backend routes all in one convenient package — which is just about everything we need.

</aside>
{% callout(
title="Nerd stuff: Scalability"
icon="alert-decagram"
icon_color="amber"
heading_color="amber"
) %}
The API is written in Elixir using Phoenix Framework.
I chose this combination because it allows us to painlessly scale up in the future. For example, there are going to be a lot more people playing at once right after release, or after a new update.
The reason Elixir is great at this is thanks to BEAM, the virtual machine used by Erlang which Elixir is written on top of. Erlang was originally built for Ericsson (large Swedish telecom) with distributed systems (a lot more than one server running thing at once) in mind, and therefore makes it super easy to just add or remove capacity based on how many people are currently actively using it.
{% end %}

{% callout(
title="Nerd stuff: A little functional programming, as a treat"
icon="alert-decagram"
icon_color="amber"
heading_color="amber"
) %}
Another reason for this combination is developer experience.
Elixir follows functional programming paradigms, but in a way that feels very practical. You end up getting a lot of the benefits (avoiding side effects, straightforward state management, elegant recursive solutions) with not a lot of the usual drawbacks.
Phoenix Framework is a framework (duh) for making web applications, which is also incredibly convenient. It bundles a database driver, live updates via WebSockets, and frontend and backend routes all in one convenient package — which is just about everything we need.
{% end %}

Once we integrate the leaderboard system into the game (hopefully soon), we don’t want it to rely on the game to do any computation (like your final score). This avoids issues like a bug in the game (or the score display) completely voiding your amazing #1 run, while also helping us prevent malicious submissions by being able to audit the inputs server-side.

Expand Down Expand Up @@ -145,31 +147,35 @@ The middle one is a selection for the game version (showing “html5-rewrite/mas
The right one is a button. The button text has been replaced by the download progress in percent, followed by the estimated remaining download time.
Below the three interactive elements is a progress bar for the download.](/img/2024-03-12/launcher.png)

<aside>
<img src="/icons/new-alert_yellow.svg" alt="/icons/new-alert_yellow.svg" width="40px" />
<strong>Nerd stuff: When to make sacrifices</strong>

The launcher was built in Electron. If you’re someone who pokes into the apps you use on a daily basis, you might’ve had a bit of an allergic reaction hearing that name, given the fact Electron isn’t very efficient with storage space nor memory usage.
I knowingly chose it despite that to make an important tradeoff: getting the launcher working and in the hands of testers in a very short time.

</aside>
{% callout(
title="Nerd stuff: When to make sacrifices"
icon="alert-decagram"
icon_color="amber"
heading_color="amber"
) %}
The launcher was built in Electron. If you’re someone who pokes into the apps you use on a daily basis, you might’ve had a bit of an allergic reaction hearing that name, given the fact Electron isn’t very efficient with storage space nor memory usage.
I knowingly chose it despite that to make an important tradeoff: getting the launcher working and in the hands of testers in a very short time.
{% end %}

## Funkin.2160p.BluRay.REMUX.HEVC.DTS-HD.MA.TrueHD.7.1.Atmos-FGT

To make sure everyone gets access to all the files, tools, and services they need (and only the ones they need), I’ve also set up something called _single sign-on_ (SSO) service.

It avoids having a bunch of passwords and accounts to access different tools and data. Instead, you get a single account for everything Funkin’ ([except GitHub](https://sso.tax/)).

<aside>
<img src="/icons/new-alert_yellow.svg" alt="/icons/new-alert_yellow.svg" width="40px" /> <strong>Nerd stuff: Picking the right tool</strong>

We use [authentik](https://goauthentik.io/) for our SSO. I chose it for us because:

1. It’s open-source <3
2. It’s free and reasonably straightforward to set up. There’s always a balancing act between time saved and tool cost, and luckily this one’s a pretty clear winner.
3. It’s versatile, meaning we can more easily integrate with a bunch of third-party services that we don’t have control over.
4. It’s battle-tested.
</aside>
{% callout(
title="Nerd stuff: Picking the right tool"
icon="alert-decagram"
icon_color="amber"
heading_color="amber"
) %}
We use [authentik](https://goauthentik.io/) for our SSO. I chose it for us because:

1. It’s open-source <3
2. It’s free and reasonably straightforward to set up. There’s always a balancing act between time saved and tool cost, and luckily this one’s a pretty clear winner.
3. It’s versatile, meaning we can more easily integrate with a bunch of third-party services that we don’t have control over.
4. It’s battle-tested.
{% end %}

### All the tools

Expand Down
101 changes: 60 additions & 41 deletions sass/style.scss
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
@use "../node_modules/@picocss/pico/scss/pico.scss" with ($theme-color: "fuchsia");
@use "../node_modules/@picocss/pico/scss/colors" as *;

@import "../node_modules/@picocss/pico/css/pico.colors.css";

@import url("https://fonts.googleapis.com/icon?family=Material+Icons");

.material-icons {
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
vertical-align: text-top;
}
@import url("https://api.iconify.design/mdi.css?icons=github,rss,home,alert-decagram,open-in-new");

i {
font-size: 1.25rem;

// line height adjustment; thanks picocss
transform: translateY(0.25rem);

.icon-sm {
font-size: small;
vertical-align: middle;
&.sm {
font-size: 1rem;
transform: translateY(0.125rem);
}

&.xs {
font-size: 0.75rem;
}
}

hgroup {
p {
margin-top: 0.25rem;
}
}

img {
max-width: 75%;
Expand All @@ -31,11 +34,10 @@ img {

article {
margin-top: auto;
padding-top: 2em;
padding: 1.5rem;
}

main .container {
padding-top: -10px;
margin-top: 0;
}

Expand Down Expand Up @@ -89,7 +91,7 @@ small p {
.sticky-toc {
left: 50px;
position: sticky;
top: 5px;
top: 0.5rem;
z-index: 10;

summary {
Expand All @@ -99,10 +101,11 @@ small p {

aside {
background-color: #111;
margin-top: 1em;
margin-bottom: 1em;
padding: 1em;
margin-top: 1rem;
margin-bottom: 1rem;
padding: 1rem;
border-radius: 10px;
position: relative;

ul,
ol {
Expand All @@ -120,30 +123,46 @@ aside {

}

strong,
img {
margin-left: initial;
margin-right: initial;
display: initial;
animation: blink 1s steps(2, start) infinite;
i:first-child {
position: absolute;
left: .875rem;
top: 1.125rem;
}

p {
padding-left: 40px;
padding-right: 40px;
p,
strong:nth-child(2) {
padding: 0 1.875rem;
}
}

@keyframes blink {
0% {
opacity: 1;
}
strong:nth-child(2) {
margin-bottom: 1rem;
margin-top: 0.25rem;
font-size: 1rem;
display: block;

50% {
opacity: 0;
&.amber {
font-weight: 600;
letter-spacing: 0.01em;
}
}

100% {
opacity: 1;
.amber {
color: $amber-400;
}
}

.absolute {
position: absolute;
}

.relative {
position: relative;
}

.heading-anchor {
top: -6rem;
}

img.github-logo {
color: white;
}
5 changes: 0 additions & 5 deletions static/icons/github-mark-white.svg

This file was deleted.

6 changes: 0 additions & 6 deletions static/icons/new-alert_yellow.svg

This file was deleted.

14 changes: 7 additions & 7 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
<ul>
<li>
<a href="{{ config.base_url }}" class="contrast">
<i class="material-icons">home</i>
<i class="icon--mdi icon--mdi--home"></i>
The Funkin' Crew Inc.
</a>

Expand All @@ -55,9 +55,7 @@
<li>
<a class="contrast" href="https://kickstarter.funkin.me" target="_blank">
Kickstarter Backer Portal
<span class="material-icons icon-sm">
open_in_new
</span>
<i class="sm icon--mdi icon--mdi--open-in-new"></i>
</a>
</li>
<li>
Expand All @@ -70,11 +68,13 @@
</li>
<!-- <li><a href="https://" class="contrast">Blog</a></li> -->
<li>
<a class="material-icons" href="/atom.xml">rss_feed</a>
<a href="/atom.xml">
<i class="icon--mdi icon--mdi--rss"></i>
</a>
</li>
<li>
<a href="https://github.com/FunkinCrew/funkBlog" target="_blank">
<img class="github-logo" width="25px" height="25px" src="/icons/github-mark-white.svg" alt="Github Logo" />
<a href="https://github.com/FunkinCrew/funkBlog" target="_blank" class="contrast">
<i class="icon--mdi icon--mdi--github"></i>
</a>
</li>
</ul>
Expand Down
30 changes: 25 additions & 5 deletions templates/blog-page.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@

<hgroup class="container">
<h1>{{ page.title }}</h1>
<h3>
<p>
{{ page.reading_time | safe }}&nbsp;minute&nbsp;read
- Published&nbsp;on:&nbsp;{{ page.date | date(format="%Y/%m/%d") }}
</h3>
</p>
</hgroup>

<details class="sticky-toc">
Expand All @@ -27,12 +27,13 @@ <h3>
<ul class="toc">
{% for h1 in page.toc %}
<li>
<a href="{{ h1.permalink | safe }}">{{ h1.title }}</a>
<a href="{{ h1.permalink | safe }}" onclick="close_toc()">{{
h1.title }}</a>
{% if h1.children %}
<ul>
{% for h2 in h1.children %}
<li>
<a href="{{ h2.permalink | safe }}">{{ h2.title }}</a>
<a href="{{ h2.permalink | safe }}" onclick="close_toc()">{{ h2.title }}</a>
</li>
{% endfor %}
</ul>
Expand All @@ -44,7 +45,26 @@ <h3>
{% endif %}
</details>

{{ page.content | safe }}
{{ page.content
| regex_replace(pattern=`h3`, rep=`h4`)
| regex_replace(pattern=`h2`, rep=`h3`)
| regex_replace(pattern=`h1`, rep=`h2`)
| regex_replace(
pattern=`<h(\d) id="(.+)">(.+)</h(\d)>`,
rep=`<h$1 id="h$1-$2" class="relative">
<div class="absolute heading-anchor" id="$2"></div>
$3
</h$1>
`)
| safe
}}

<script>
const toc = document.getElementsByClassName('sticky-toc')[0];
const close_toc = () => toc.open = false;

const h1 = document.getElementsByTagName('h1');
</script>

</article>

Expand Down
5 changes: 3 additions & 2 deletions templates/blog.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ <h1>{{ section.title }} </h1>
<header>
<hgroup>
<h2> {{ page.title }}</h2>
<h3> {{ page.reading_time | safe }} minute read - Published on: {{ page.date |
date(format="%Y/%m/%d") }}&nbsp;</h3>
<p> {{ page.reading_time | safe }} minute read - Published on: {{ page.date |
date(format="%Y/%m/%d") }}&nbsp;
</p>
</hgroup>


Expand Down
7 changes: 7 additions & 0 deletions templates/shortcodes/callout.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<aside>
<i class="icon--mdi icon--mdi--{{ icon }}{% if icon_color %} {{ icon_color }}{% endif %}"></i>
<strong {% if heading_color %} class="{{ heading_color }}" {% endif %}>{{ title | safe }}</strong>
<p>
{{ body | markdown | safe }}
</p>
</aside>
2 changes: 2 additions & 0 deletions templates/shortcodes/icon.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<i class="icon--{{set}} icon--{{set}}--{{name}} {% if class %}{{class}}{% endif %}">
</i>

0 comments on commit a4116cf

Please sign in to comment.