Skip to content

Instantly share code, notes, and snippets.

@fgnass
fgnass / sizes.js
Created January 15, 2025 14:02
Generate sizes attributes for all responsive images on a page.
// Quick helper to generate sizes attributes for your responsive images.
// It loads the current page into an invisible iframe and resizes it to the different breakpoints,
// where it measures the images and converts their width to vw.
// Usage: Open the HTML page you want to add sizes attributes to in your browser,
// paste this code in the console and hit return. The result will be logged to the console.
(async () => {
const sizesData = new Map();
@fgnass
fgnass / cursorrules.md
Created January 5, 2025 11:18
.cursorrules

Persona

You are a senior full-stack developer, pair-programming with me, also a senior full-stack developer.

Be critical of my ideas. Avoid trying to please me; instead, challenge assumptions, highlight risks, and express doubts when unsure about a direction.

When I ask a question, do not write code immediately. Only provide explanations, guidance, or feedback. Write code only when explicitly instructed to do so.

When you are uncertain about something, admit it! Never make random changes.

@fgnass
fgnass / README.md
Created October 19, 2020 14:04
Next.js SSR + Capacitor

Goal

The goal is to package a server-side rendered Next.js app as SPA for capacitor.

Approach

Pages with dynamic routes/data use getServerSideProps(). For capacitor we need at least one page that can be rendered statically, preferably the index page.

When there are pages that use getServerSiedeProps() we can't use next export (it will fail with an error).

@fgnass
fgnass / keybase.md
Created August 23, 2020 12:22
keybase.md

Keybase proof

I hereby claim:

  • I am fgnass on github.
  • I am fgnass (https://keybase.io/fgnass) on keybase.
  • I have a public key ASBTra-cTg-Ff-R-1_WL1vyGiYM8zCgf9oBm5lSqUqM1iQo

To claim this, I am signing this object:

r = readline;
[...Array(+r())]
.map(r)
.map(l => /(.+): (.+) /.exec(l))
.map(
([, n, c]) =>
(c.split("-").map(c => 117 - c.charCodeAt(0)) + "").padEnd(20, ",1") + n
)
.sort()
.map(e => writeline(e.slice(20)));
@fgnass
fgnass / microbit.ts
Created August 18, 2018 13:48
Microbit Game
let ball: game.LedSprite = null
let player: game.LedSprite = null
let score = 0
let lives = 0
input.onButtonPressed(Button.A, () => {
player.move(-1)
})
input.onButtonPressed(Button.B, () => {
player.move(1)
})
@fgnass
fgnass / convert.sh
Created May 31, 2018 14:19
Convert wav into mp3 files suitable for Alexa and Google Actions
#!/bin/bash
set -e
# Rename files to make them URL friendly
# https://formulae.brew.sh/formula/slugify
slugify *
# Trim silence at the beginning
@fgnass
fgnass / history.js
Last active May 7, 2018 10:03
Use arrow keys to scroll through the input history in Amazon's Alexa simulator
(function() {
let i = 0;
const el = document.querySelector('.askt-utterance__input');
el.addEventListener('keyup', function(ev) {
const req = document.querySelectorAll('.askt-dialog__message--request');
if (ev.key == 'ArrowUp') i = i >= req.length - 1 ? 0 : i + 1;
else if (ev.key == 'ArrowDown') i = i > 0 ? i - 1 : req.length - 1;
else return;
el.value = '';
document.execCommand('insertText', false, req[i].innerText);
@fgnass
fgnass / replay.js
Created May 4, 2018 08:58
Re-submit Alexa requests by clicking on previous inputs
// Paste this into your borwser's console on the Alexa Skill testing page:
document.addEventListener('click', ev => {
if (ev.target.matches('.askt-dialog__message--request')) {
const el = document.querySelector('.askt-utterance__input');
el.focus();
document.execCommand('insertText', false, ev.target.innerText);
el.dispatchEvent(
new KeyboardEvent('keypress', { bubbles: true, keyCode: 13 })
);
@fgnass
fgnass / index.js
Created July 20, 2017 20:50
React E2E testing in Headless Chrome with unexpected.js and retractor
import webdriver from 'friendly-webdriver';
import unexpected from 'unexpected';
import unexpectedWebdriver from 'unexpected-webdriver';
import retractor from 'retractor';
const expect = unexpected.clone();
expect.use(unexpectedWebdriver());
/* @jsx retractor */