XciD's picture
XciD HF staff
initial commit
8969f81
import { Utils } from './lib/Utils';
import html2canvas from 'html2canvas';
import { c } from './lib/Log';
import { Api } from './Api';
abstract class Modal {
protected div: HTMLDivElement;
protected doneBtn: HTMLAnchorElement | null;
protected loader: HTMLImageElement;
constructor(className: string) {
this.div = document.querySelector(`div.modal.${className}`) as HTMLDivElement;
this.doneBtn = this.div.querySelector<HTMLAnchorElement>('.js-close');
this.loader = this.div.querySelector('.js-loader') as HTMLImageElement;
this.doneBtn?.addEventListener('click', (e) => {
e.preventDefault();
this.hide();
});
this.div.addEventListener('click', (e) => {
if (e.target === this.div) {
c.debug(`modal:background.click`);
this.hide();
}
});
}
/**
* Hooks: Implement those to perform the actual work done on show and hide.
*/
abstract performBeforeShow(): Promise<void>;
abstract performShow(): Promise<void>;
abstract performHide(): Promise<void>;
async show() {
await this.performBeforeShow();
this.div.classList.add('fadeout');
this.div.classList.remove('hide');
await Utils.delay(100);
this.div.classList.remove('fadeout');
await this.performShow();
this.loader.classList.add('hide');
}
async hide() {
this.div.classList.add('fadeout');
await Utils.delay(200);
this.div.classList.add('hide');
this.div.classList.remove('fadeout');
await this.performHide();
}
}
export class ShareScreenshotModal extends Modal {
private imResult = this.div.querySelector('.js-result') as HTMLImageElement;
constructor() {
super(`share-screenshot`);
}
async performBeforeShow() {
this.loader.classList.remove('hide');
}
async performShow() {
await Utils.delay(800); /// <- for good ux
const el = document.querySelector('div.page-inner') as HTMLDivElement;
const canvas = await html2canvas(el, {
logging: false, /// <- inoperant in our version of html2canvas.
onclone: (doc) => {
const clonedEl = doc.querySelector('div.page-inner') as HTMLDivElement;
clonedEl.classList.add('html2canvas');
const watermark = doc.querySelector('div.watermark') as HTMLDivElement;
watermark.style.visibility = `visible`;
}
});
this.imResult.src = canvas.toDataURL();
}
async performHide() {
this.imResult.src = "";
}
}
export class SavePublishModal extends Modal {
private saveBtn = this.div.querySelector('.js-save') as HTMLAnchorElement;
private form = this.div.querySelector('form') as HTMLFormElement;
constructor(
private quill: Quill
) {
super(`save-publish`);
/// vv Url fields auto-select.
const urlInputs = Array.from(
this.div.querySelectorAll('.doc-url')
) as HTMLInputElement[];
for (const x of urlInputs) {
x.addEventListener('focus', () => {
x.select();
});
}
this.saveBtn.addEventListener('click', (e) => {
e.preventDefault();
if (! this.form.reportValidity()) {
/// Form is invalid.
return ;
}
this.save();
});
this.form.addEventListener('submit', (e) => {
e.preventDefault();
this.saveBtn.click();
});
}
async performBeforeShow() {}
async performShow() {}
async performHide() {}
async save() {
this.loader.classList.remove('hide');
const inputTitle = this.div.querySelector('.doc-title') as HTMLInputElement;
const title = inputTitle.value;
const contents = this.quill.getContents();
c.log(JSON.stringify({ title, contents }));
const success = await Api.shared.postEdit({ title, contents });
await Utils.delay(800); /// <- for good ux
if (success) {
this.loader.classList.add('hide');
this.hide();
/// For now we always redirect to the edit url here:
/// vv
const inputEditUrl = this.div.querySelector('.doc-edit-url') as HTMLInputElement;
window.location.href = inputEditUrl.value;
} else {
window.alert(`did not manage to save`);
}
}
}