import * as electronRemote from '@electron/remote'; const electronConsole = electronRemote.getGlobal('console') as Console; import Logger from '../../../logger/logger'; import Q from '../q-module'; const LOG = Logger.create(__filename, electronConsole); import ElementsUtil from './require/elements-util'; export interface CreateErrorIndicatorProps { container: HTMLElement; classes?: string[]; message: string; taskFunc: (() => Promise); resolveFunc: ((result: unknown) => void); rejectFunc: ((err: Error) => void); } // resolveFunc and rejectFunc should be the resolve/reject functions from the withPotentialError promise export default function createErrorIndicator(q: Q, props: CreateErrorIndicatorProps): HTMLElement { let { container, classes, message, taskFunc, resolveFunc, rejectFunc } = props; classes = classes || []; let element = q.create({ class: [ 'error-indicator', ...classes ], content: [ { tag: 'img', src: './img/error.png', alt: 'error' }, { content: [ { content: message }, { class: 'retry-button', content: 'Try Again' } ] } ] }) as HTMLElement; let observer = new MutationObserver(() => { if (element.parentElement == null) { rejectFunc(new Error('indicator removed')); observer.disconnect(); } }); observer.observe(container, { childList: true }); let retrying = false; q.$$$(element, '.retry-button').addEventListener('click', async () => { if (retrying) return; retrying = true; q.$$$(element, '.retry-button').innerText = 'Fetching...'; try { observer.disconnect(); await taskFunc(); resolveFunc(null); } catch (e) { observer.observe(container, { childList: true }); LOG.error('error during retry', e); q.$$$(element, '.retry-button').innerText = 'Try Again'; await ElementsUtil.shakeElement(q.$$$(element, '.retry-button'), 400); } retrying = false; }); return element; }