async function getHTML(endpoint, options = {}) {
let query = {};
if (options._query !== undefined) {
query = options._query;
delete options._query;
}
const params = new URLSearchParams(query);
const res = await fetch(`${endpoint}?${params}`, options);
return { body: await res.text(), status: res.status };
}
const validateBase64Img = dataURL => new Promise(resolve => {
const img = new Image();
img.onload = () => {
resolve(img.width === 88 && img.height === 31);
};
img.src = dataURL;
});
export const b = {
init: 'badgeEditorInit',
}
const badgeEditorEndpoint = '/hyperapi/badges/editor/'
const MAX_BADGES = 10;
let badgesCount = 0;
let customImageDatas = {};
export async function badgeEditorInit(_, __, el) {
const res = await getHTML(badgeEditorEndpoint);
if (res.status != 200) {
return;
}
el.innerHTML = res.body;
badgesCount = el.querySelectorAll('.sortable-item').length;
b.trigger('badgeEditorAssignImgId');
b.trigger('setBadgeCount');
}
export function badgeEditorAssignImgId(_, __, el) {
if (el.dataset.imgId) return;
const id = b.uuid();
const filePicker = el.querySelector('input[type=file]');
const img = el.querySelector('img.badge-button');
console.log(img);
el.dataset.imgId = id;
filePicker.dataset.imgId = id;
img.dataset.imgId = id;
}
export function badgeEditorSetPreview(ev, sender, el) {
if (!sender.parentNode.contains(el)) return;
const selectedItem = sender.selectedOptions[0];
if (selectedItem.value !== 'custom') {
el.src = selectedItem.dataset.filePath;
} else if (customImageDatas[el.dataset.imgId]) {
el.src = customImageDatas[el.dataset.imgId];
} else {
el.removeAttribute('src');
}
}
export function badgeEditorSetPreviewCustom(payload, _, el) {
if (!payload.badge.contains(el)) return;
if (!customImageDatas[el.dataset.imgId]) {
el.removeAttribute('src');
} else {
el.src = customImageDatas[el.dataset.imgId];
}
}
export function badgeEditorToggleFilePicker(ev, sender, el) {
if (!sender.parentNode.parentNode.contains(el)) return;
const selectedItem = sender.selectedOptions[0];
const picker = el.querySelector('input[type=file]');
if (selectedItem.value !== 'custom') {
el.classList.add('hidden');
picker.required = false;
picker.setCustomValidity('');
} else {
el.classList.remove('hidden');
picker.required = true;
picker.setCustomValidity(picker.dataset.validity || '');
}
}
export function badgeEditorAddBadge(ev, sender, el) {
// TODO: page templates do not get updated on mutation
const badge = document.getElementById('badge-template').innerText;
el.innerHTML += badge;
b.trigger('badgeEditorAssignImgId');
badgesCount++;
b.trigger('setBadgeCount');
}
export function badgeEditorDelete(ev, sender, el) {
if (!el.contains(sender)) return;
el.remove();
badgesCount--;
b.trigger('setBadgeCount');
}
export function badgeEditorShowFilePicker(ev, sender, el) {
if (sender.nextElementSibling !== el) return;
el.showPicker();
}
export async function badgeEditorFileSelected(ev, sender, el) {
const file = sender.files[0];
const badge = sender.parentNode.parentNode;
if (
!['image/png', 'image/jpeg', 'image/jpg', 'image/webp'].includes(file.type)
) {
sender.dataset.validity = 'The badge file must be an image.';
sender.setCustomValidity(sender.dataset.validity);
sender.reportValidity();
customImageDatas[sender.dataset.imgId] = null;
b.send({ badge: badge }, 'badgeEditorSetPreviewCustom');
return;
}
if (file.size >= 1000 * 500) {
sender.dataset.validity = 'The badge image must be smaller than 500KB.';
sender.setCustomValidity(sender.dataset.validity);
sender.reportValidity();
customImageDatas[sender.dataset.imgId] = null;
b.send({ badge: badge }, 'badgeEditorSetPreviewCustom');
return;
}
const reader = new FileReader();
reader.onload = async e => {
const dimsValid = await validateBase64Img(e.target.result);
if (!dimsValid) {
sender.setCustomValidity('The badge image must be exactly 88x31 pixels.');
sender.reportValidity();
customImageDatas[sender.dataset.imgId] = null;
b.send({ badge: badge }, 'badgeEditorSetPreviewCustom');
return;
}
customImageDatas[sender.dataset.imgId] = e.target.result;
sender.dataset.validity = '';
sender.setCustomValidity('');
b.send({ badge: badge }, 'badgeEditorSetPreviewCustom');
}
reader.readAsDataURL(file);
}
export function setBadgeCount(_, __, el) {
if (el instanceof HTMLButtonElement) {
el.disabled = badgesCount === MAX_BADGES;
} else {
el.innerText = `${badgesCount}/${MAX_BADGES}`;
}
}