Implement aside

This commit is contained in:
2026-05-05 12:16:10 +02:00
parent 551b5f6301
commit d8a5371108
19 changed files with 121 additions and 46 deletions
+6
View File
@@ -3,11 +3,17 @@ import { defineConfig } from "astro/config";
import remarkToc from "remark-toc";
import mdx from "@astrojs/mdx";
import icon from "astro-icon";
import { fileURLToPath } from "url";
export default defineConfig({
integrations: [icon(), mdx()],
vite: {
plugins: [tailwindcss()],
resolve: {
alias: {
"@": fileURLToPath(new URL("./src", import.meta.url)),
},
},
},
site: "https://zoriya.dev",
prefetch: {
+53
View File
@@ -0,0 +1,53 @@
---
import { Icon } from "astro-icon/components";
interface Props {
type?: "note" | "tip" | "warning" | "danger";
title?: string;
}
const { type = "note", title } = Astro.props;
const styles = {
note: {
border: "border-blue-500",
bg: "bg-blue-500/10",
icon: "fa6-solid:circle-info",
},
tip: {
border: "border-green-500",
bg: "bg-green-500/10",
icon: "fa6-solid:lightbulb",
},
warning: {
border: "border-yellow-500",
bg: "bg-yellow-500/10",
icon: "fa6-solid:triangle-exclamation",
},
danger: {
border: "border-red-500",
bg: "bg-red-500/10",
icon: "fa6-solid:circle-exclamation",
},
};
const currentStyle = styles[type];
const defaultTitles = {
note: "Note",
tip: "Tip",
warning: "Warning",
danger: "Danger",
};
---
<div class={`my-4 p-4 rounded-lg border-l-4 ${currentStyle.border} ${currentStyle.bg}`}>
<div class="flex items-center gap-2 mb-2">
<Icon name={currentStyle.icon} class={`w-5 h-5 ${currentStyle.border.replace("border-", "text-")}`} />
<span class={`font-semibold ${currentStyle.border.replace("border-", "text-")}`}>
{title || defaultTitles[type]}
</span>
</div>
<div class="text-fg-secondary">
<slot />
</div>
</div>
+1 -1
View File
@@ -1,6 +1,6 @@
---
import { Icon } from "astro-icon/components";
import ThemeToggle from "./ThemeToggle.astro";
import ThemeToggle from "@/components/ThemeToggle.astro";
const navLinks = [
{ href: "/blogs/", label: "Blogs" },
+16 -12
View File
@@ -7,6 +7,7 @@ date: 2024-08-20
tags: ["gameboy", "asm", "school", "gamejam"]
---
import Aside from "@/components/Aside.astro";
import { Icon } from 'astro-icon/components';
I recently mentioned on Twitter that I made a gameboy game with some friends during my first year of college. Since there's some cool stuff to showcase, here's a blog about it!
@@ -135,14 +136,17 @@ Here you can see the whole background of the game. A 32x32 grid of tiles (so 256
We can move the camera over this background by setting the `SCX` and `SCY` registers (aka `scroll x` and `scroll y`). The camera will show a 160x144 pixel area and will wrap around the background if necessary (if part of the background goes off-screen, it will appear on the opposite side of the screen).
> **Note:** You might have guessed but the `SCX` and `SCY` registers are of course memory mapped, meaning to set them you just need to write at `$FF43` and `$FF42` respectively. In c, it would be something like:
>
> ```c
> uint8_t *scroll_x = 0xFF43;
> *scrool_x = 12;
> // set scroll to 12
> // (or whatever value you want)
> ```
<Aside>
You might have guessed but the `SCX` and `SCY` registers are of course memory mapped, meaning to set them you just need to write at `$FF43` and `$FF42` respectively. In c, it would be something like:
```c
uint8_t *scroll_x = 0xFF43;
*scrool_x = 12;
// set scroll to 12
// (or whatever value you want)
```
</Aside>
This means, we can fake a moving spaceship by simply placing a sprite in the middle of the screen and changing the scroll registers.
@@ -249,9 +253,7 @@ Now that all the numbers we want to display are in BCD format, displaying them b
<details>
<summary>
Here is an example implementation of a write number function.
</summary>
<summary>Here is an example implementation of a write number function.</summary>
```asm
; Write the number in `a` to the address `de` (in ascii)
@@ -298,7 +300,9 @@ Also, I said earlier that we thought it would be cool to play our game on real h
It's our very own cartridge that reads the game from an EEPROM. The right image shows the game that segfault!
> As said previously, segfault is not possible on the gameboy but we made a security mechanism when we jump at a weird place in memory to help us debug. This is this security screen that you are seeing in this image.
<Aside>
As said previously, segfault is not possible on the gameboy but we made a security mechanism when we jump at a weird place in memory to help us debug. This is this security screen that you are seeing in this image.
</Aside>
This catridge can also be used to play on a SNES by using the Super GameBoy!
@@ -5,6 +5,8 @@ date: 2024-06-14
tags: ["ffmpeg", "kyoo"]
---
import Aside from "@/components/Aside.astro";
For [Kyoo](https://github.com/zoriya/kyoo), I need to play video on a variety of clients (browsers, TVs, mobile apps). Clients does not always support the video codec of the source video since videos are user provided. Any valid video should work everywhere. Users should not have to worry about converting videos for Kyoo to work, everything should Work™ the first time.
Users don't always have a stable connection, but they should be able to play their video. Even if they are on a train. Those constraints mean that Kyoo needs a service to change videos codec and file size (transcode) on the fly. Why on the fly? Because we don't want users to store all their videos 5 times (the original, a 480p version, a 720p version and so on).
@@ -269,11 +271,11 @@ This command will output something like that:
in a few seconds. We can use that before starting to transcode to know where we should cut segments.
{{< alert "note" >}}
<Aside type="note">
Kyoo actually start transcoding before every keyframes could be retrieved since on slow HDD, keyframe extraction can take up to 30 seconds. This ensures that you wait for a minimum amount of time before playback start. Since keyframes are cached for later uses, this process is transparent for users, and you can resume playback from the middle of your movie latter if you want.
{{< /alert >}}
</Aside>
## Wrapping up
@@ -284,12 +286,11 @@ For example, hardware acceleration, aka using your graphics card for faster tran
I iterated a lot on this transcoder, my first implementation was written in C and used ffmpeg's library directly (this was also my first C and low level project, I had never heard of a pointer before). Everybody told me this was a bad idea and I should just create a node process that would call ffmpeg. While this was the right call if I wanted to quickly create a transcoder, learning to read the ffmpeg's source code and how it worked inside gave me lots of insights. Insights I still use today when working in today's transcoder, after rewriting everything in Rust and then in Go. Each rewrite originated from perspective shift on how to process state and streams, leading to the current implementation that finally archived every goal.
Kyoo's transcoder also has other features that resolve around video like extracting subtitles, fonts or media thumbnails for seeking (see picture below).
Kyoo's transcoder also has other features that resolves around video like extracting subtitles, fonts or media thumbnails for seeking (see picture below).
![thumbnail for seeking](./kyoo-seek.png)
It's still a moving project with new features coming, but the core transcoding process is done and fully working! The next feature that will probably come is intro/outro detection using audio fingerprints.
This was my first blog about Kyoo's development, If you want to read more about a specific topic, please manifest yourself! If you liked this article, consider sharing it or staring [Kyoo](https://github.com/zoriya/kyoo) on GitHub.
<!-- vim: set wrap: -->
{/* vim: set wrap: */}
@@ -6,6 +6,8 @@ draft: false
tags: ["vim", "tools"]
---
import Aside from "@/components/Aside.astro";
I get asked at lot why I use vim and people don't believe me when I tell them I don't miss IntelliJ or other IDEs. This post will explain why I initially left the comfort of my well-known IDE and tried vim. I'm also going to explain why I find vim's way of handling keybinds and file tabs appealing ; as well as what my pain-points with traditional IDE's way of handling them were.
## The learning curve
@@ -97,11 +99,11 @@ The jump list works great for quickly navigating between files but after jumping
You can think of global marks as a bookmark, you first mark a file with a key (<kbd>m</kbd>+<kbd>A</kbd> for example, <kbd>m</kbd> means mark and <kbd>A</kbd> is the name of your mark, it can be any uppercase letter). Pressing <kbd>\'</kbd>+<kbd>A</kbd> will bring you back to the same file at the exact same line as when you bookmarked it.
{{< alert "note" >}}
<Aside type="note">
You might wonder why only uppercase letters are allowed for global marks. That's simply because a lowercase letter refers to a local mark. A local mark is scoped to a file, so you can have a <kbd>a</kbd> mark per file. Pressing it will get you back to the marked line but will not change file.
{{< /alert >}}
</Aside>
## Closing notes: the present of vim
@@ -118,5 +120,4 @@ Be aware though, if you have no interest scripting your editor to your liking, y
Vim is not an of-the-shelf solution. You will need to configure it before using it as a daily editor. If you do not enjoy that kind of editor, that's fine just use something else. I personally really like getting to know my tools and having an editor I can tinker with. Consistently learning new things about the editor and using more coreutils tools in my workflow is something I find really enjoyable.<br/>
-- On a side note, I still think `awk` and `jq` are ones of the most underrated tools available.
<!-- vim: set wrap: -->
{/* vim: set wrap: */}
@@ -5,6 +5,8 @@ date: 2024-09-22
tags: ["tools", "rent"]
---
import Aside from "@/components/Aside.astro";
I use a lot of nerdy tools (linux, nix, river), some tools also have a steep learning curve (vim, dvorak). I also type on a [32 split keyboard](https://github.com/zoriya/abyss) I made myself.
![my keyboard](keyboard.jpg)
@@ -18,14 +20,14 @@ I rewrite projects from scratch if I feel this is needed, even if it means losin
I never use LLM, for writing code or searching for solution/alternatives. Heck, I don't even use auto-complete to write code.
{{< alert "note" >}}
<Aside type="note">
While you could say I'm just an old-fashioned nerd, my choices can be summarized by those sentences:
- **Building** things I use is fun
- **Learning** new things is fun
- Being **competent** is fun
{{< /alert >}}
</Aside>
I like using projects I build. I like learning new things everyday, new obscure features of my editor/os/packet manager/wm.\
I love being **wrong** and having my understanding of something being completely changed after learning something new.\
@@ -37,4 +39,4 @@ My github bio is "I'm not a dev, I'm a sorceress". This is not (only) because I
I don't have an end-goal of shipping stuff, getting cracked or becoming a millionaire. I just want to have fun, and to me, being a dev is more fun than any video game or movies.
<!-- vim: set wrap: -->
{/* vim: set wrap: */}
@@ -5,11 +5,13 @@ date: 2024-12-30
tags: []
---
import Aside from "@/components/Aside.astro";
Recently, I've felt a bit lost about where to go in my career. I pride myself as a generalist and love to explore new domains and I felt like web/backend didn't have anything new to offer.
I've been wondering how `specialists` found their domain and what types of profiles exist in the wild.
> We value T-shaped people. That is, people who are both generalists (highly skilled at a broad set of valuable things—the top of the T) and also experts (among the best in their field within a narrow discipline—the vertical leg of the T.) _ Valve's handbook
> We value "T-shaped" people. That is, people who are both generalists (highly skilled at a broad set of valuable things—the top of the T) and also experts (among the best in their field within a narrow discipline—the vertical leg of the T.) _ Valve's handbook
When first hearing this, it felt logical, and then I wondered: do people really just pick a single domain to become an expert in? Shouldn't we value V shaped people more?
Those questions began to sit in the back of my mind for a while and this blog is my answer.
@@ -18,11 +20,11 @@ Those questions began to sit in the back of my mind for a while and this blog is
My first observation was that no domain lives in isolation from the others. To give a simple example using webdev, no backend exists without its frontend. No one can be a backend expert without knowing how your API is going to be used and what could be its pain points.
{{< alert "note" >}}
<Aside type="note">
If you feel hurt by this sentence, I hope it can serve as motivation for you to learn a bit about a new domain. fullstack is not a mediocre back & a mediocre front, it is a necessary path to become a better webdev.
{{< /alert >}}
</Aside>
The second observation I made is obvious: you do not know the depth of a domain without being an expert in it. You can use the Dunning Kruger graph to illustrate.
@@ -41,4 +43,4 @@ I still don't know how specialists define their subjects (do they just toss a co
I don't have much to say, keep exploring the knowledge map ; I'm sure there's an island or two that are unexplored.
<!-- vim: set wrap: -->
{/* vim: set wrap: */}
+2 -2
View File
@@ -1,7 +1,7 @@
---
import "../styles/global.css";
import Footer from "../components/Footer.astro";
import Header from "../components/Header.astro";
import Footer from "@/components/Footer.astro";
import Header from "@/components/Header.astro";
interface Props {
title: string;
+4 -4
View File
@@ -2,10 +2,10 @@
import type { CollectionEntry } from "astro:content";
import type { MarkdownHeading } from "astro";
import type { AstroComponentFactory } from "astro/runtime/server/index.js";
import Comments from "../components/Comments.astro";
import TableOfContents from "../components/TableOfContents.astro";
import TagBadge from "../components/TagBadge.astro";
import BaseLayout from "./BaseLayout.astro";
import Comments from "@/components/Comments.astro";
import TableOfContents from "@/components/TableOfContents.astro";
import TagBadge from "@/components/TagBadge.astro";
import BaseLayout from "@/layouts/BaseLayout.astro";
interface Props {
entry: CollectionEntry<"blogs" | "posts">;
+2 -2
View File
@@ -1,7 +1,7 @@
---
import type { CollectionEntry } from "astro:content";
import PostCard from "../components/PostCard.astro";
import BaseLayout from "./BaseLayout.astro";
import PostCard from "@/components/PostCard.astro";
import BaseLayout from "@/layouts/BaseLayout.astro";
interface Props {
title: string;
+1 -1
View File
@@ -1,6 +1,6 @@
---
import { getCollection, render } from "astro:content";
import BlogPostLayout from "../../layouts/BlogPostLayout.astro";
import BlogPostLayout from "@/layouts/BlogPostLayout.astro";
export async function getStaticPaths() {
const blogs = await getCollection("blogs");
+1 -1
View File
@@ -1,6 +1,6 @@
---
import { getCollection } from "astro:content";
import ListLayout from "../../layouts/ListLayout.astro";
import ListLayout from "@/layouts/ListLayout.astro";
const blogs = await getCollection("blogs", ({ data }) => !data.draft);
blogs.sort((a, b) => b.data.date.getTime() - a.data.date.getTime());
+2 -2
View File
@@ -1,7 +1,7 @@
---
import { Icon } from "astro-icon/components";
import RecentPosts from "../components/RecentPosts.astro";
import BaseLayout from "../layouts/BaseLayout.astro";
import RecentPosts from "@/components/RecentPosts.astro";
import BaseLayout from "@/layouts/BaseLayout.astro";
const description =
"I work on Kyoo or other nerdy projects at night. I love weird tools (a keyboard that I designed myself, vim, tiling window manager like dwl or gaze). Feel free to reach out if you want to talk!";
+1 -1
View File
@@ -1,6 +1,6 @@
---
import { getCollection, render } from "astro:content";
import BlogPostLayout from "../../layouts/BlogPostLayout.astro";
import BlogPostLayout from "@/layouts/BlogPostLayout.astro";
export async function getStaticPaths() {
const posts = await getCollection("posts");
+1 -1
View File
@@ -1,6 +1,6 @@
---
import { getCollection } from "astro:content";
import ListLayout from "../../layouts/ListLayout.astro";
import ListLayout from "@/layouts/ListLayout.astro";
const posts = await getCollection("posts", ({ data }) => !data.draft);
posts.sort((a, b) => b.data.date.getTime() - a.data.date.getTime());
+1 -1
View File
@@ -1,6 +1,6 @@
---
import { getCollection } from "astro:content";
import ListLayout from "../../layouts/ListLayout.astro";
import ListLayout from "@/layouts/ListLayout.astro";
export async function getStaticPaths() {
const allBlogs = await getCollection("blogs", ({ data }) => !data.draft);
+1 -1
View File
@@ -1,6 +1,6 @@
---
import { getCollection } from "astro:content";
import BaseLayout from "../../layouts/BaseLayout.astro";
import BaseLayout from "@/layouts/BaseLayout.astro";
const allBlogs = await getCollection("blogs", ({ data }) => !data.draft);
const allPosts = await getCollection("posts", ({ data }) => !data.draft);
+7 -1
View File
@@ -1,4 +1,10 @@
{
"extends": "astro/tsconfigs/strict",
"exclude": ["dist", "src/content"]
"exclude": ["dist", "src/content"],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}