BEN TSAI⋅BLOG

writing words on the internet since 00

i was posting the other week about this tension with the format of a reverse-chronological feed of writing. if you look at all the apps (twitter, mastodon, instagram, etc) the new content is at the top, modulo any algorithms in place. however, you write top-down, so the most recent stuff as at the bottom of a "post".

well, i discovered a new app called PaperRoll that is a fresh take on this. in fact, i think the tag line is literally, "a fresh take on note-taking". it behaves like one huge text file where you type stuff at the bottom of the scroll. you assign each post with a "theme". you can filter by theme, so they kinda act like tags, but so far, it feels better to keep these themes at as high level as possible.

i'm still exploring it, but what i like about this scheme is that i can see the most recent context by scrolling up. just having this immediate context is sufficient. maybe i don't need an elaborate system that is strictly organized. if anything, i appreciate the creator's philosophy of making something that is super easy to adopt. i can imagine then layering in more features like search and ai, while keeping the user experience basic.

🍳 Fried Eggs

I've been enjoying cooking fried eggs on my cast iron skillet. I heat up butter until it starts browning. Then crack the eggs. I break up the white near the yolk with a fork. Season with salt and pepper.

Simple, delicious, and my kids eat it. It's a little extra fun making fried eggs on Fridays.

Snek

https://toulou.itch.io/strgsnek (via waxy.org)

It took me a few sessions across multiple days, but I finally beat this game. This is the level of gaming I have these days. Nevertheless, it was fun.

Auto-resize boxes when cards get close to boundaries

let store =
  document.querySelector("#app").__vue_app__.config.globalProperties.$store;

let currentCardId = ""; let previousCardId = ""; let isDraggingCardId = "";

let intervalId = setInterval(() => { let isCardDetailsOpen = document.querySelector(".card-details");

if ( isCardDetailsOpen && isCardDetailsOpen.getAttribute("data-card-id") != currentCardId ) { previousCardId = currentCardId; currentCardId = isCardDetailsOpen.getAttribute("data-card-id"); document.dispatchEvent( new CustomEvent("cardEditEnded", { detail: { cardId: previousCardId } }) ); document.dispatchEvent( new CustomEvent("cardEditStarted", { detail: { cardId: currentCardId } }) ); }

if (!isCardDetailsOpen && currentCardId) { previousCardId = currentCardId; currentCardId = ""; document.dispatchEvent( new CustomEvent("cardEditEnded", { detail: { cardId: previousCardId } }) ); }

if (!isDraggingCardId && store.state.currentDraggingCardId) else if (isDraggingCardId && !store.state.currentDraggingCardId) { document.dispatchEvent( new CustomEvent("cardDragEnded", { detail: { cardId: isDraggingCardId } }) ); isDraggingCardId = ""; } }, 50);

let resizeBoxes = (card) => { if (!card) return;

Object.values(store.state.currentBoxes.boxes).forEach((box) => { if ( card.x + (card.resizeWidth ?? card.width) >= box.x && card.x < box.x + box.resizeWidth && card.y + (card.resizeHeight ?? card.height) >= box.y && card.y < box.y + box.resizeHeight ) { console.log( "📦", { card }, "is inside", { box }, card.x, card.resizeWidth, box.x, box.resizeWidth ); if ( card.x + (card.resizeWidth ? card.resizeWidth : card.width) > box.x + box.resizeWidth - 24 ) { // Handle east store.dispatch("currentBoxes/update", { ...box, resizeWidth: card.x + (card.resizeWidth ?? card.width) + 48 - box.x, }); } if ( card.y + (card.resizeHeight ? card.resizeHeight : card.height) > box.y + box.resizeHeight - 24 ) { // Handle south store.dispatch("currentBoxes/update", { ...box, resizeHeight: card.y + (card.resizeHeight ?? card.height) + 48 - box.y, }); } if (card.x < box.x) { store.dispatch("currentBoxes/update", { ...box, x: card.x - 20, resizeWidth: box.resizeWidth + box.x - card.x + 20, }); } if (card.y < box.y) { store.dispatch("currentBoxes/update", { ...box, y: card.y - 20, resizeHeight: box.resizeHeight + box.y - card.y + 20, }); } } }); };

document.addEventListener("cardEditStarted", (e) => { console.log("🎴", e.type, e.detail.cardId); resizeBoxes(store.state.currentCards.cards[e.detail.cardId]); });

document.addEventListener("cardEditEnded", (e) => { console.log("🎴", e.type, e.detail.cardId); resizeBoxes(store.state.currentCards.cards[e.detail.cardId]); });

document.addEventListener("cardDragEnded", (e) => { console.log("🎴", e.type, e.detail.cardId); resizeBoxes(store.state.currentCards.cards[e.detail.cardId]); });

Kinopio.club song

write a song about kinopio.club, the spatial thinking tool that works the way our brains work

Verse 1:

Kinopio.club, what a surprise,

You'll find the tools that'll help you think twice.

It's designed the way our minds do,

So you can use it to make something new.

Chorus:

Learning's fun when you use Kinopio.club,

Getting smarter and feeling good.

You can build your own thinking space, And explore the world at your own pace.

Verse 2:

You can create graphs, charts and maps,

Build networks and models, no need to collapse.

It's the perfect way to make your ideas grow,

You can even share with friends, so they can learn and know.

Chorus:

Learning's fun when you use Kinopio.club,

Getting smarter and feeling good.

You can build your own thinking space,

And explore the world at your own pace.

Verse 3:

Kinopio.club is here to stay,

Explore your ideas in a new way.

It's a tool that can help you think more,

And let's you explore the world and more

READ INSTRUCTION BEFORE USE

I made some coffee in my Bodum french press this morning and noticed the text on the glass. They are a weird mix of instructions, prohibitions, and parenting tips:

READ INSTRUCTION BEFORE USE

NOT FOR STOVE TOP USE

CHILDREN AND HOT FLUIDS SHOULD BE KEPT APART

ALWAYS USE COARSE GROUND COFFEE

ALWAYS STIR BEFORE PRESSING DOWN, USING A PLASTIC OR WOODEN SPOON, NOT METAL

BEFORE PRESSING DOWN, ENSURE THAT SAFETY LID IS IN THE CORRECT POSITION

PRESS DOWN VERY GENTLY

I did not follow any of these instructions. However, I agree with keeping kids and hot fluids separate and will be doing that from now on.

Kinopio coding ideas

Kinopio coding ideas

In the theme of the many coding advent activities starting this month (like this list I saw on my feed), I'll try to write some hacks to do fun or useful things in Kinopio. I've documented some things I've already done on the forum. Here are some ideas that have been swirling in my head:

✍️ analog

I'm on a quest to improve my handwriting and do more handwriting. This would be a welcome break from all the digital in my life. So, I bought a new pen, have dug up a bunch of used notebooks, and I'm experimenting.

I created a Kinopio space that collects some links on this topic.

Areas I'm dabbling:

The future

In my professional life as a software engineer, I live in the world of tech. We have an optimism about the future. Startups are born and strive to better the world in some way. The future is for the taking. We can invent new things, be pioneers.

Juxtapose this with what I believe. That the second Advent approaches, and until then, I am following Jesus. The destination is set, the end is written.