TeaWeb/shared/js/ui/modal/ModalAvatar.ts

72 lines
2.9 KiB
TypeScript
Raw Normal View History

2020-03-30 13:44:18 +02:00
//TODO: Test if we could render this image and not only the browser by knowing the type.
import {createErrorModal, createModal} from "tc-shared/ui/elements/Modal";
import {tra} from "tc-shared/i18n/localize";
import {arrayBufferBase64} from "tc-shared/utils/buffers";
2020-03-30 13:44:18 +02:00
export function spawnAvatarUpload(callback_data: (data: ArrayBuffer | undefined | null) => any) {
const modal = createModal({
header: tr("Avatar Upload"),
footer: undefined,
body: () => {
return $("#tmpl_avatar_upload").renderTag({});
}
});
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
let _data_submitted = false;
let _current_avatar;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
modal.htmlTag.find(".button-select").on('click', event => {
modal.htmlTag.find(".file-inputs").trigger('click');
});
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
modal.htmlTag.find(".button-delete").on('click', () => {
if(_data_submitted)
return;
_data_submitted = true;
modal.close();
callback_data(null);
});
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
modal.htmlTag.find(".button-cancel").on('click', () => modal.close());
const button_upload = modal.htmlTag.find(".button-upload");
button_upload.on('click', event => (!_data_submitted) && (_data_submitted = true, modal.close(), true) && callback_data(_current_avatar));
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
const set_avatar = (data: string | undefined, type?: string) => {
_current_avatar = data ? arrayBufferBase64(data) : undefined;
button_upload.prop("disabled", !_current_avatar);
modal.htmlTag.find(".preview img").attr("src", data ? ("data:image/" + type + ";base64," + data) : "img/style/avatar.png");
};
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
const input_node = modal.htmlTag.find(".file-inputs")[0] as HTMLInputElement;
input_node.multiple = false;
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
modal.htmlTag.find(".file-inputs").on('change', event => {
console.log("Files: %o", input_node.files);
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
const read_file = (file: File) => new Promise<string>((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result as string);
reader.onerror = error => reject(error);
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
reader.readAsDataURL(file);
});
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
(async () => {
const data = await read_file(input_node.files[0]);
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
if(!data.startsWith("data:image/")) {
console.error(tr("Failed to load file %s: Invalid data media type (%o)"), input_node.files[0].name, data);
createErrorModal(tr("Icon upload failed"), tra("Failed to select avatar {}.<br>File is not an image", input_node.files[0].name)).open();
return;
}
const semi = data.indexOf(';');
const type = data.substring(11, semi);
console.log(tr("Given image has type %s"), type);
2019-08-21 10:00:01 +02:00
2020-03-30 13:44:18 +02:00
set_avatar(data.substr(semi + 8 /* 8 bytes := base64, */), type);
})();
});
set_avatar(undefined);
modal.close_listener.push(() => !_data_submitted && callback_data(undefined));
modal.open();
2019-08-21 10:00:01 +02:00
}