js/template/ImageUploadModalTemplate.js
import ModalController from '~/controllers/ModalController';
import ModalTemplate from '~/template/ModalTemplate';
import ImgurUpload from '~/models/Request/ImgurUpload';
import Random from '~/modern/Random';
import Theme from '~/models/Theme';
const MAX_FILE_SIZE = 10000000; // In bytes
const NO_FILE_TEXT = 'No Selected';
function uploadButton(text) {
return <button class="button button--color-accent button--size-small button--padding-top">{ text }</button>;
}
/**
* Image upload Modal dialog.
* @extends {ModalTemplate}
*/
export default class ImageUploadModalTemplate extends ModalTemplate {
/** @override */
constructor(delegate = null) {
let templateId = Random.ofDefault(),
urlId = `url-${templateId}`,
fileId = `file-${templateId}`,
fileViewId = `file-view-${templateId}`;
let urlUpload = <input id={urlId} class="text-input text-input--type-url" type="text" />,
urlUploadButton = uploadButton('Add Image');
let fileUpload = <input class="file invisible" id={fileId} type="file" accept="image/*"/>,
filePreview = <span class="file preview" id={fileViewId}>{ NO_FILE_TEXT }</span>,
fileUploadButton = uploadButton('Upload Image');
super(
"Upload an image",
<div class="md-upload-split">
<div class="label-group item-wrap">
<label>From URL</label>
{ urlUpload }
{ urlUploadButton }
</div>
<div class="label-group item-wrap">
<label>From File</label>
<div class="file container">
<label class="file trigger" for={fileId}>Choose File</label>
{ filePreview }
</div>
{ fileUpload }
{ fileUploadButton }
</div>
</div>
);
/** @type {ActionControllerDelegate} */
this.delegate = delegate;
this._urlInput = urlUpload;
this._urlButton = urlUploadButton;
this._fileInput = fileUpload;
this._filePreview = filePreview;
this._fileButton = fileUploadButton;
fileUpload.addEventListener("change", ::this._didSelectFile);
urlUploadButton.addEventListener("click", ::this._uploadURL);
fileUploadButton.addEventListener("click", ::this._uploadFile);
}
async _uploadURL(event) {
let request = new ImgurUpload({
url: this._urlInput.value
});
this._setLoading();
this.delegate?.didChangeProgressState(this, true);
try {
this._insertWithURL(await request.run());
} finally {
this.delegate?.didChangeProgressState(this, false);
}
}
async _uploadFile(event) {
let request = new ImgurUpload({
file: this._selectedFile
});
this._setLoading();
this.delegate?.didChangeProgressState(this, true);
try {
this._insertWithURL(await request.run());
} finally {
this.delegate?.didChangeProgressState(this, false);
}
}
_setLoading() {
const buttons = [this._urlButton, this._fileButton];
for (const button of buttons) {
const loadingSvg = <img src={ Theme.light.imageForTheme('loading') }/>;
button.classList.add('button--color-disabled');
while (button.firstChild) {
button.removeChild(button.firstChild);
}
button.appendChild(loadingSvg);
}
}
_didSelectFile(event) {
let file = this._selectedFile;
if (!file) {
this._setFilePreview(NO_FILE_TEXT);
} else {
this._setFilePreview(file.name);
}
}
get _selectedFile() {
return this._fileInput.files[0];
}
_setFilePreview(filename) {
while (this._filePreview.lastChild) {
this._filePreview.removeChild(this._filePreview.lastChild);
}
this._filePreview.appendChild(document.createTextNode(filename));
}
_insertWithURL(url) {
this.delegate?.didSetStateTo(this, url);
ModalController.shared.dismiss();
}
}