import {css, html} from "../nexus/html.js" import {interval} from "../tools/interval.js" import {defaultNexus} from "../nexus/nexus.js" import {RenderResult} from "../nexus/parts/types.js" import {makeLoadingEffect} from "./make-loading-effect.js" // // error indicator // const errorStyle = css` :host { color: red; font-family: monospace; } ` const AsciiErrorIndicator = defaultNexus.shadowView(use => (reason: string) => { use.name("error-indicator") use.styles(errorStyle) return html`${reason || "unknown error"}` }) // // loading indicator // const loadingStyle = css` :host { font-family: monospace; } ` const AsciiLoadingIndicator = defaultNexus.shadowView(use => (hz: number, animation: RenderResult[]) => { use.name("loading-indicator") use.styles(loadingStyle) const frame = use.signal(0) use.mount(() => interval.hz(hz, () => { const next = frame.value + 1 frame.value = (next < animation.length) ? next : 0 })) return html`${animation[frame.value]}` }) // // function to setup animated effects // export const makeAnimatedLoadingEffect = (hz: number, animation: RenderResult[]) => makeLoadingEffect({ error: reason => AsciiErrorIndicator([reason]), loading: () => AsciiLoadingIndicator([hz, animation]), }) // // ready-made effects // /** animated loading indicators */ export const loading = { /** animated pattern that looks like "01101" */ binary: makeAnimatedLoadingEffect(20, [ "00000", "00001", "00010", "00101", "01011", "10110", "01100", "11001", "10011", "00111", "01110", "11101", "11011", "10110", "01101", "11010", "10100", "01000", "10000", ]), /** animated braille-style spinner that looks like "⣾" */ braille: makeAnimatedLoadingEffect(20, [ "⣾", "⣷", "⣯", "⣟", "⡿", "⢿", "⣻", "⣽", ]), }