Compare commits

..

3 commits

10 changed files with 55 additions and 190 deletions

View file

@ -711,3 +711,14 @@ div.homepage {
grid-template-columns: repeat(auto-fill, minmax(20em, 1fr)); grid-template-columns: repeat(auto-fill, minmax(20em, 1fr));
grid-gap: 3em; grid-gap: 3em;
} }
ul.posts {
list-style-type: none;
margin: 0;
padding: 0;
}
div.post_summary {
margin-bottom: 1em;
padding: 0.5rem;
}

View file

@ -7,7 +7,7 @@ defmodule JOL.Blog do
end end
use NimblePublisher, use NimblePublisher,
build: JOL.Blog.Post, build: Post,
from: Application.app_dir(:jol, "priv/posts/**/*.md"), from: Application.app_dir(:jol, "priv/posts/**/*.md"),
parser: Parser, parser: Parser,
as: :posts as: :posts
@ -15,6 +15,17 @@ defmodule JOL.Blog do
@posts Enum.sort_by(@posts, & &1.date, {:desc, Date}) @posts Enum.sort_by(@posts, & &1.date, {:desc, Date})
@tags @posts |> Enum.flat_map(& &1.tags) |> Enum.uniq() |> Enum.sort() @tags @posts |> Enum.flat_map(& &1.tags) |> Enum.uniq() |> Enum.sort()
@spec all_posts() :: [
%Post{
author: String.t(),
body: String.t(),
date: DateTime.t(),
draft: false | nil,
slug: String.t(),
tags: [String.t()],
title: String.t()
}
]
def all_posts, do: @posts def all_posts, do: @posts
def unique_tag_list, do: @tags def unique_tag_list, do: @tags

View file

@ -1,8 +1,25 @@
defmodule JOL.Blog.Post do defmodule JOL.Blog.Post do
@enforce_keys [:author, :title, :body, :tags, :date, :slug] @enforce_keys [:author, :title, :body, :tags, :date, :slug, :lede]
defstruct [:author, :draft, :title, :body, :tags, :date, :slug] defstruct [:author, :draft, :title, :body, :tags, :date, :slug, :lede]
def build(_filename, attrs, body) do def build(_filename, attrs, body) do
struct!(__MODULE__, [author: "Jessica Phoenix Canady", body: body] ++ Map.to_list(attrs)) struct!(
__MODULE__,
[author: "Jessica Phoenix Canady", body: body, lede: extract_lede(body)] ++
Map.to_list(attrs)
)
end
defp extract_lede(text) do
case Regex.named_captures(~r/(?<lede>.*)\n<!-- more -->/s, text) do
%{"lede" => lede} ->
lede
_ ->
text
|> String.split()
|> Enum.take(50)
|> Enum.join(" ")
end
end end
end end

View file

@ -14,9 +14,9 @@
<nav class="menu"> <nav class="menu">
<ul class="menu__inner"> <ul class="menu__inner">
<li class="active"><a href="">home</a></li> <li class="active"><a href={~p"/"}>home</a></li>
<li><a href={~p"/tags/"}>tags</a></li> <li><a href={~p"/tags/"}>tags</a></li>
<li><a href={~p"/archive/"}>blog archive</a></li> <li><a href={~p"/blog/"}>blog archive</a></li>
<li><a href={~p"/about/"}>about</a></li> <li><a href={~p"/about/"}>about</a></li>
<li><a href={~p"/now/"}>now</a></li> <li><a href={~p"/now/"}>now</a></li>
<li><a href="https://forge.sigill.zone/phoenix/">code</a></li> <li><a href="https://forge.sigill.zone/phoenix/">code</a></li>
@ -27,7 +27,9 @@
</header> </header>
<div class="content"> <div class="content">
<%= @inner_content %> <div class="post">
<%= @inner_content %>
</div>
</div> </div>
<footer class="footer"> <footer class="footer">

View file

@ -1,7 +1,9 @@
<h1>The Blog</h1> <h1 class="post-title">Post Archive</h1>
<ul>
<%= for post <- @posts do %> <%= for post <- @posts do %>
<li><.link href={~p"/blog/#{post.slug}"}><%= post.title %></.link></li> <div class="post-summary">
<p class="post-date"><date><%= post.date %></date></p>
<h3> <.link href={~p"/blog/#{post.slug}"}><%= post.title %> </.link> </h3>
<p><%= raw post.lede %></p>
</div>
<% end %> <% end %>
</ul>

View file

@ -3,7 +3,7 @@
<ul> <ul>
<%= for tag <- @tags do %> <%= for tag <- @tags do %>
<li class="tag-list"> <li class="tag-list">
<a href="#"><%= tag %></a> <a href={~p"/tags/#{tag}"}><%= tag %></a>
</li> </li>
<% end %> <% end %>
</ul> </ul>

View file

@ -1,57 +0,0 @@
+++
title = "LAN Voice Chat with Mumble"
date = 2024-04-16 11:51:33-04:00
draft = false
[taxonomies]
# these go in quotes, like the title
tags = ["software", "family"]
+++
My kids, 11yo and 7yo, are *really* into playing Minecraft and Terraria together. But, being siblings, it doesn't always go as well as anyone really wants it to. Sometimes, it's just that they can't be in the same *room* together. And since they both have fancy gaming headsets, they might as well get used to using voice chat.
But how?
It might be easy to give them Discord accounts and let them get to know the wide world of _Shitty Internet Culture_, _Awful Desktop Software_ and _Yay Notifications Forever_, but that seems like a horrible idea. Besides, what kind of Tech would I be if I didn't solve this problem by deploying software?
Enter: [Mumble](https://www.mumble.info/downloads/).
## The Server
The server is called Murnur, and has [an official Docker image](https://github.com/mumble-voip/mumble-docker).
In my case, I just plugged this into [Portainer](https://www.portainer.io) using their Docker Compose example.
(If, like me, you're trying to copy/paste a reasonable looking `docker-compose.json` file while two kids are louodly wondering why this is taking so long, you might also miss the `image: mumblevoip/mumble-server:<tag>` placeholder in their example. I've replaced that with `latest` below.)
```json
services:
mumble-server:
image: mumblevoip/mumble-server:latest
container_name: mumble-server
hostname: mumble-server
restart: on-failure
ports:
- 64738:64738
- 64738:64738/udp
```
Literally nothing to do but run that. The Docker logs will show a password for the `SuperUser` account, which you may want, but for our simple use-case here I never needed it.
## The Client
Mumble has [clients](https://www.mumble.info/downloads/) for Windows, Mac, Linux, iOS, and Android.
After running, you'll go through an Audio Setup Wizard that's fairly self-explanatory. Then it'll ask for connection details.
Here's the fun bit:
Since you're doing this locally and not publically, feel free to just pick a username for the server. Mumble will generate a certificate that identifies you, and normally you'd want to back that up and register with the server and all that, but for my use case none of that really matters. I just had the kids type in whatever name they wanted, and bam, they're in.
There's a `Root` channel everyone joins by default. Others can be created, but since I've just got the two kids, it's easy enough just to let them both be in that channel.
## How'd It Go?
It's been running faultless for a few days, with the only real issue being that the client likes to be restarted after the kids' laptops resume from suspend.
This rocks. Way better than having my kids ask me to buy _Discord Nitro_ for them.

View file

@ -1,44 +0,0 @@
+++
title = "HOWTO: Use the KVM in the Odyssey Ark Gen2"
draft = false
date = 2024-01-02 14:00:00-05:00
[taxonomies]
tags = ["howto", "hardware"]
+++
I splurged on the absolutely monstrous Samsung Odyssey Ark 55" (Gen 2) monitor.
If you want a gigantic beast of a monitor and you don't mind it also being a Smart TV kinda thing with its own Home screen and wifi connection, this is a fantastic device!
<!-- more -->
One of my use cases for a primary display is plugging it into my desktop and also my laptop. The built-in KVM on the monitor is *superbly* under-documented. Here's how to set it up quickly:
## Connect your computers
The control box that the display connects to has four inputs: three HDMI and a DisplayPort. Pick the ones you like, and plug them in. Note which numbered port you connect which machine to.
You also need a USB connection to each, so connect a USB B or C cable from one of the labeled ports on the control box. There's three B and a C. Same as before, note which port you plugged which computer into.
## Connect your peripherals
On the right side (from the front) of the control box, there's a couple of USB A ports. Each provides a different amount of power.
There's only two, which will work for a mouse and a keyboard. I highly recommend plugging a USB hub of some kind into the control box, and then plugging your stuff into there.
## Configure the Odyssey Ark
In the Settings menu of the Odyssey Ark, navigate to Connection -> External Device Manager -> USB Input Port Setup.
This menu maps USB input Ports on the control box to display inputs. For each USB input you've plugged into on the back of the control box, map it to one (or more) displays.
---
That's it! Now, when you switch the monitor to a given input, it'll map the peripherals on the side ports to whichever USB Host port you've mapped them to.
## What about the multi-monitor thing?
Hell if I know, it requires some Windows-only software and so I haven't even attempted to give it a try yet.
Hope this helps someone!

View file

@ -1,26 +0,0 @@
+++
title = "HOWTO: Fix Steam Deck Unresponsive Touchscreen"
date = 2024-01-07 13:40:00-05:00
[taxonomies]
tags = ["howto", "hardware", "games", "shit's on fire yo"]
+++
If you've picked up your Steam Deck recently and the touchscreen just randomly stopped working, there is a *super* quick fix! Instead of factory resetting and wondering if you accidentally dropped the damn thing, do this:
<!-- more -->
1. Turn your Steam Deck off. Actually off from the Steam menu, not just suspended by tapping the power button.
1. Unplug the Deck if it's plugged in.
1. Hold the volume up button while you tap the power button. Keep holding the volume up button until you hear the chime.
1. Use the D-Pad to select "Setup Utility" and press A.
1. Navigate to the Power menu.
1. Choose Battery storage mode, and confirm.
Your Deck will power off and the power LED will blink three times to confirm battery storage mode.
Plug back into the power supply, and turn it back on normally. This will automatically disable battery storage mode.
After this, my touchscreen worked perfectly again.
Hope this helps someone!

View file

@ -1,51 +0,0 @@
+++
title = "The Names We Discard"
date = 2024-01-30 15:53:22-05:00
[taxonomies]
tags = ["trans"]
+++
> It's the name you used for _thirty-some years_. It's not _evil_.
>
> -- My wife
<!-- more -->
We were packing up boxes, finally clearing out our old house so we could sell it. A good few of the boxes were full of stuff from my childhood, things that my Mom gave me when I had could store them and get them out of the cramped apartment we lived in. They all had my deadname on them.
I was visibly upset by those boxes, and had just commented about the bittersweetness of these items (and others, like pictures of me from Back When), when my wife fired off the quote above and I had to take a minute to get myself together.
My wife isn't trans; her first experience with trans people in real life was when I transitioned; and she didn't say it maliciously. Just _thoughtlesly_, as if I had been acting silly. I had to figure out why her offhanded remark hurt _so damn much._
---
The name I discarded when I finally decided to embrace _the real me_ was indeed part of my life for 37 years. It was my email domain, it was (is) on my Bachelor of Science degree, On trophies. On boxes of childhood treasures in my Mom's neat handwriting. I don't hate it, and I don't hate who that person was.
But seeing it makes me uncomfortable.
It reminds me of the decades I outright suppressed and ignored my feelings.
The young child afraid to be _too_ girly, so folks wouldn't make fun of them.
The adolescent that knew that if they could wave a wand and, Sailor Moon-style, magically transform into a girl, that they'd do it. Y'know, just to _try it out_.
The 20-something that would occasionally get pretty drunk and refer to themselves as a girl, but even then would look around to make sure nobody heard.
The 30-something that was getting drunk _far_ too often, at times daily, and ordering cheap women's clothes from Amazon and hiding them from their wife and kids.
My deadname reminds me that, despite my driver's license and credit cards all having Jessica Phoenix Canady printed on them, there are still people I love (or loved) who will absolutely use t to refer to me. Sometimes to my face. Sometimes after I just corrected them, hoping in vain that they "just forgot."
It also reminds me of how I figured out why I never looked *right* in mirrors or pictures, and that I finally _do_.
Of the card my eldest son made me that says he'll always love me no matter what my gender is.
How my youngest son calls me "Dad" in public and doesn't understand or care why some folks give us weird looks sometimes.
That my wife still loves me, despite everything.
None of this even scratches the surface! The name kind of stores all my feelings about my transness encoded in it, and seeing it unexpectedly can drop them all back onto me at once.
Hearing or seeing my deadname is going to be a weird, bittersweet, somewhat painful thing for a while. Eventually, I hope, it's only used by the folks I'll never speak to again because they can't put it down.
But it's damn heavy, and I'm glad I don't always have to carry it anymore.