File size: 3,904 Bytes
8969f81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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`);
		}
	}
}