Hello! My name is Frank Hampus Weslien and I'm a hacker from Sweden. I mostly build stuff in the crypto/web3 and generative art domains.
My Projects
import { useEffect, useRef } from "react"; | |
type CanvasProps = { | |
width: number; | |
height: number; | |
}; | |
export function Canvas(props: CanvasProps) { | |
const canvasRef = useRef<HTMLCanvasElement | null>(null); |
import { useEffect, useRef } from "react"; | |
/** | |
* Only want to un the init code once? useRefOnce to the rescue! | |
* | |
* @param init the function that produces the inital value | |
* @returns | |
*/ | |
export default function useRefOnce<V>( | |
init: () => V |
import { | |
assertFails, | |
initializeTestEnvironment, | |
} from "@firebase/rules-unit-testing"; | |
import { test } from "vitest"; | |
import fs from "fs"; | |
import * as firstore from "firebase/firestore"; | |
type Interview = { | |
transcript?: string; |
Hello! My name is Frank Hampus Weslien and I'm a hacker from Sweden. I mostly build stuff in the crypto/web3 and generative art domains.
My Projects
import { RefObject, useEffect } from "react"; | |
/** | |
* | |
* @param resize the function that runs every time `lead` is resized | |
* @param leadRef the HTMLElement that we are tracking | |
*/ | |
export default function useOnResize<A extends HTMLElement>( | |
leadRef: RefObject<A>, | |
resize: (lead: A) => void, |
import { useEffect, useState } from "react"; | |
//////////////////////////////////////////////////////////////////////////////// | |
// Permissions | |
//////////////////////////////////////////////////////////////////////////////// | |
/** | |
* microphone and camera doesn't exist on all browsers! | |
*/ | |
type AllPermissionName = "microphone" | "camera" | PermissionName; |
/** | |
* Entry point for an integer parser | |
* | |
* @param error - error to throw if the parsed value is not an integer | |
* @returns a parser for integers | |
*/ | |
export function int(error?: (s: string) => any): typeof ValidatorBuilderNumber { | |
const obj = { ...ValidatorBuilderNumber }; | |
obj[onParseError] = error; | |
return obj; |
import React from "react"; | |
/** | |
* A hook that provides helper functions and properties to use in a form input | |
* | |
* @param initalValue - The initial value of the form input | |
* @param validate - A function that validates the value of the form input | |
* @returns an object with helper functions and properties to use in a form input | |
* | |
*/ |
# exports each selected object into its own file | |
import bpy | |
import os | |
# export to blend file location | |
basedir = os.path.dirname(bpy.data.filepath) | |
if not basedir: | |
raise Exception("Blend file is not saved") |
import React from 'react'; | |
// Some persmissions are not supported by all browsers, microphones are | |
// not supported by Safari for example. | |
export type PermissionNamePlus = PermissionName | 'microphone'; | |
export class PermissionError extends Error {} | |
// Cache the permissions so we don't have to show a loading state | |
// every time we check a permission. |