import { Colors } from './color.js';
import * as Color from './color.js';
export class HistoryItem {
name: string;
cols: Colors;
constructor(name: string, cols: Colors) {
this.cols = cols;
this.name = name;
}
asHtml(): HTMLButtonElement {
const { lines, outer, belly1: belly, fins1: fins } = this.cols;
const content = `
${this.name}
`;
const button = document.createElement('button');
button.className = 'history-item';
button.dataset.name = this.name;
button.innerHTML = content;
return button;
}
}
export class History {
items: string[];
constructor(items: string[] = []) { this.items = items; }
add(name: string): void { this.items.push(name); }
*iterNames(maxLength: number = 100): Iterable {
const seen = new Set;
let done = 0;
for (let i = this.items.length - 1; i >= 0; i--) {
if (maxLength >= 0 && done > maxLength) break;
const name = this.items[i]!;
if (!name || seen.has(name)) continue;
yield name;
seen.add(name);
done++;
}
}
// pass a negative number to iterate over all
*iterItems(maxLength?: number): Iterable {
for (const name of this.iterNames(maxLength)) {
const cols = Color.colors(new Color.Rand(name), Color.KNOWN[name]);
yield new HistoryItem(name, cols);
}
}
static validate(x: unknown): History | undefined {
if (Array.isArray(x) && x.every(i => typeof i == 'string'))
return new History(x);
}
toJSON(): unknown { return this.items; }
save(persist = true): void {
const storage = persist ? localStorage : sessionStorage;
storage.setItem('history', JSON.stringify(this));
}
// if no history exists, or it's invalid, just start a new one
static load(): History {
const json =
sessionStorage.getItem('history') ??
localStorage.getItem('history');
if (json === null) return new History;
return History.validate(JSON.parse(json)) ?? new History;
}
addSave(name: string, persist = true): void {
this.add(name);
this.save(persist);
}
prune(maxLength?: number): void {
const keep = [];
for (const name of this.iterNames(maxLength)) keep.push(name);
this.items = keep.reverse();
}
}