move some files around to confuse everyone
This commit is contained in:
parent
710f7be68c
commit
30fa1aaca1
46 changed files with 45 additions and 45 deletions
|
|
@ -1,38 +0,0 @@
|
|||
import { Dispatch, SetStateAction, useCallback, useState } from "react";
|
||||
|
||||
// like useState, but it is persisted in localStorage
|
||||
// important: values must be JSON-(de-)serializable
|
||||
export function usePersistentState<T>(key: string, initial: T): [T, Dispatch<SetStateAction<T>>] {
|
||||
const [state, setState] = useState(() => {
|
||||
const recovered = localStorage.getItem(key);
|
||||
let parsed;
|
||||
if (recovered !== null) {
|
||||
try {
|
||||
parsed = JSON.parse(recovered);
|
||||
return parsed;
|
||||
} catch (e) {
|
||||
// console.warn(`failed to recover state for option '${key}'`, e,
|
||||
// '(this is normal when running the app for the first time)');
|
||||
}
|
||||
}
|
||||
return initial;
|
||||
});
|
||||
|
||||
const setStateWrapped = useCallback((val: SetStateAction<T>) => {
|
||||
setState((oldState: T) => {
|
||||
let newVal;
|
||||
if (typeof val === 'function') {
|
||||
// @ts-ignore: i don't understand why 'val' might not be callable
|
||||
newVal = val(oldState);
|
||||
}
|
||||
else {
|
||||
newVal = val;
|
||||
}
|
||||
const serialized = JSON.stringify(newVal);
|
||||
localStorage.setItem(key, serialized);
|
||||
return newVal;
|
||||
});
|
||||
}, [setState]);
|
||||
|
||||
return [state, setStateWrapped];
|
||||
}
|
||||
68
src/util/util.ts
Normal file
68
src/util/util.ts
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
export function formatTime(timeMs: number) {
|
||||
const leadingZeros = "00" + Math.floor(timeMs) % 1000;
|
||||
const formatted = `${Math.floor(timeMs / 1000)}.${(leadingZeros).substring(leadingZeros.length-3)}`;
|
||||
return formatted;
|
||||
}
|
||||
|
||||
export function compactTime(timeMs: number) {
|
||||
if (timeMs % 1000 === 0) {
|
||||
return `${timeMs / 1000}s`;
|
||||
}
|
||||
return `${timeMs} ms`;
|
||||
}
|
||||
|
||||
export function memoize<InType,OutType>(fn: (i: InType) => OutType) {
|
||||
const cache = new Map();
|
||||
return (i: InType) => {
|
||||
const found = cache.get(i);
|
||||
if (found) {
|
||||
return found;
|
||||
}
|
||||
const result = fn(i);
|
||||
cache.set(i, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// compare arrays by value
|
||||
export function arraysEqual<T>(a: T[], b: T[], cmp: (a: T, b: T) => boolean = (a,b)=>a===b): boolean {
|
||||
if (a === b)
|
||||
return true;
|
||||
|
||||
if (a.length !== b.length)
|
||||
return false;
|
||||
|
||||
for (let i=0; i<a.length; i++)
|
||||
if (!cmp(a[i],b[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function setsEqual<T>(a: Set<T>, b: Set<T>): boolean {
|
||||
if (a === b)
|
||||
return true;
|
||||
|
||||
if (a.size !== b.size)
|
||||
return false;
|
||||
|
||||
for (const itemA of a)
|
||||
if (!b.has(itemA))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function objectsEqual<T>(a: {[key: string]: T}, b: {[key: string]: T}, cmp: (a: T, b: T) => boolean = (a,b)=>a===b): boolean {
|
||||
if (a === b)
|
||||
return true;
|
||||
|
||||
if (Object.keys(a).length !== Object.keys(b).length)
|
||||
return false;
|
||||
|
||||
for (const [keyA, valueA] of Object.entries(a))
|
||||
if (!cmp(b[keyA], valueA))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue