Files
register/marko_unpacked/marko/cms/_public/assets/js/file-img.js
T
Admin Nasledstvo ac168868ee Initial import
2026-05-01 20:52:04 +03:00

455 lines
18 KiB
JavaScript

var newFiles = {};
var sl = {};
function checkAll(el) {
const objectKey = el.dataset.objectKey;
sl[objectKey] = [];
all('#' + objectKey + ' .file-img [data-del]', e => {
e.checked = el.checked === true;
if (el.checked) {
if (e.dataset.del) {
sl[objectKey].push(e.dataset.del);
}
e.parentNode.addClass('checked');
} else {
e.parentNode.removeClass('checked');
}
})
updateActionButtons(objectKey);
}
function checkSingle(e) {
const objectKey = e.dataset.objectKey;
sl[objectKey] = sl[objectKey] || [];
if (e.checked) {
if (e.dataset.del) {
sl[objectKey].push(e.dataset.del);
}
e.parentNode.addClass('checked');
} else {
one('#' + e.dataset.objectKey + ' .all-files input').checked = false;
e.parentNode.removeClass('checked');
if (e.dataset.del) {
const f = sl[objectKey].indexOf(e.dataset.del);
sl[objectKey].splice(f, 1);
}
}
updateActionButtons(objectKey);
}
function updateActionButtons(id) {
let checkedCounter = 0;
let checkedCounterUploaded = 0;
all('#' + id + ' .file-img input', c => {
if (c.checked === true)
checkedCounter++;
if (c.checked === true && c.dataset.del)
checkedCounterUploaded++;
})
const btnDelete = one('#' + id + ' .btnDelete');
const delCount = one('#' + id + ' .delCount');
const btnEdit = one('#' + id + ' .btnEdit');
if (btnDelete) {
if (checkedCounter > 0) {
btnDelete.removeClass('disabled');
delCount.innerHTML = '(' + checkedCounter + ')'
} else {
btnDelete.addClass('disabled');
delCount.innerHTML = '(0)'
}
}
if (btnEdit) {
if (checkedCounterUploaded === 1) {
btnEdit.removeClass('disabled');
} else {
btnEdit.addClass('disabled');
}
}
}
function addFileImage(e) {
const max_file_size = one('#' + e.dataset.objectKey + ' .max_file_size').value;
const error_message = one('#' + e.dataset.objectKey + ' .error_message').value;
const file = document.createElement('input');
let filesContainer = one('#' + e.dataset.objectKey + ' .files-container');
newFiles[e.dataset.objectKey] = newFiles[e.dataset.objectKey] || [];
file.type = 'file';
file.name = e.dataset.objectKey
file.multiple = !e.dataset.singleFile;
//file.accept = 'image/jpeg, image/png'
file.click();
file.addEventListener('change', function () {
var cIndex = 0;
for (let i = 0; i < this.files.length; i++) {
const f = this.files[i];
if (f.size > max_file_size * (1024 * 1024)) {
flash.error(error_message);
}
else if(f.type !== 'image/jpeg' && f.type !== 'image/jpg' && f.type !== 'image/png') {
flash.error('Позволените формати са jpeg и png')
}
else {
filesContainer.style.display = 'flex';
const fileContainer = one('file-img', filesContainer);
const imgId = e.dataset.objectKey + '_' + cIndex;
cIndex++;
const img = new Image();
img.src = URL.createObjectURL(f);
img.id = imgId;
const check = document.createElement('input')
check.type = 'checkbox';
check.setAttribute('data-del', '');
check.setAttribute('data-id', imgId);
check.setAttribute('data-object-key', e.dataset.objectKey)
check.addEventListener('click', e => {
checkSingle(check);
})
fileContainer.appendChild(img);
fileContainer.appendChild(check);
one('crops', fileContainer);
const progress = one('progress', fileContainer);
img.addEventListener('load', function () {
fileContainer.addClass('visible');
check.focus();
});
img.addEventListener('click', () => {
editSingleFileImage(img);
})
orderItem(fileContainer, function (img_id, order_index) {
newFiles[img_id][3] = order_index.toString();
})
newFiles[imgId] = [f, progress, e.dataset.objectKey, fileContainer.dataset.index, check];
if (e.dataset.singleFile) {
e.addClass('disabled');
}
}
}
uploadAllFilesByAttach(e.dataset.objectKey, cIndex, e.dataset.editMode);
});
}
function removeFileImage(el) {
let checkedCounter = 0;
let forDelete = [];
all('#' + el.dataset.objectKey + ' .file-img input', c => {
if (c.checked === true) {
checkedCounter++;
forDelete.push(c);
}
});
let message = '';
if (checkedCounter > 1) {
message = 'Сигурни ли сте, че истате да премахнете тези ' + checkedCounter + ' изображения';
} else {
message = 'Сигурни ли сте, че искате да премахнете 1 изображение';
}
modal.confirm(message, function () {
forDelete.forEach(fd => {
fd.parentNode.remove();
delete newFiles[fd.dataset.id];
});
el.querySelector('.delCount').innerHTML = '(0)';
el.addClass('disabled');
one('#' + el.dataset.objectKey + ' .btnEdit').addClass('disabled');
if (sl[el.dataset.objectKey].length > 0) {
let del_ids = JSON.stringify(sl[el.dataset.objectKey]);
request({
url: '/delete-file-cms/',
post: {
del_ids: del_ids
},
done: r => {
if (r.success) {
flash.success(r.success, true);
}
}
});
}
const addButton = one('#' + el.dataset.objectKey + ' [data-single-file]');
if (all('#' + el.dataset.objectKey + ' .file-img input').length === 0) {
one('#' + el.dataset.objectKey + ' .files-container').style.display = 'none';
if (addButton.dataset.singleFile) {
addButton.removeClass('disabled');
}
}
one('#' + el.dataset.objectKey + ' .all-files input').checked = false;
})
}
function uploadAllFilesByAttach(object_key, for_upload, editMode) {
console.log(newFiles);
const
newFilesIds = Object.keys(newFiles),
media_key = one('[name="media_key"]').value,
model_class = one('[name="model_class"]').value,
model_id = one('[name="model_id"]').values
if (newFilesIds.length > 0) {
var cc = 0;
all(`#${object_key} .file-img`).forEach(e => {
e.addClass('no-events');
})
newFilesIds.forEach(id => {
if (newFiles[id][5] === undefined) {
const f = newFiles[id][0];
const progressBar = newFiles[id][1];
const object_key = newFiles[id][2];
const order_index = newFiles[id][3];
const check = newFiles[id][4];
let formData = new FormData();
console.log(object_key);
formData.append('media_key', media_key);
formData.append('model_class', model_class);
formData.append('object_key', object_key);
formData.append('order_index', order_index);
formData.append('model_id', model_id);
formData.append(id, f);
if (editMode) {
formData.append('has_article', 1)
}
request({
url: '/upload-file-cms/',
post: formData,
progress: percentage => {
if (progressBar) {
progressBar.style.width = percentage + '%'
if (percentage < 100) {
progressBar.parentNode.addClass('disabled')
} else {
if (progressBar) {
if (progressBar.parentNode)
progressBar.parentNode.removeClass('disabled')
progressBar.remove()
}
}
}
},
done: data => {
check.setAttribute('data-del', data.id);
check.setAttribute('data-file-type', data.fileType)
check.setAttribute('data-src-raw', data.srcRaw)
check.setAttribute('data-media-key', data.mediaKey)
check.setAttribute('data-file-name', data.fileName)
check.setAttribute('data-crop-files', '[]')
newFiles[id][5] = 'uploaded';
cc++
if (for_upload === cc) {
all(`#${object_key} .file-img`).forEach(e => {
e.removeClass('disabled');
e.removeClass('no-events');
})
}
}
})
}
});
}
}
function editSingleFileImage(e) {
const check = e.parentNode.querySelector('input');
editFileSelectedImage(check, check.dataset.objectKey)
}
function editFileImage(e) {
const check = one('#' + e.dataset.objectKey + ' .file-img input:checked');
editFileSelectedImage(check, e.dataset.objectKey)
}
function editFileSelectedImage(check, objectKey) {
const bufferFiles = {};
const allowed_resolutions = JSON.parse(one('#' + objectKey + ' .allowed_resolutions').value);
const cropFiles = JSON.parse(check.dataset.cropFiles);
const img = document.createElement('img');
img.src = check.dataset.srcRaw;
img.style.height = '100%';
img.style.width = 'auto';
let aspectRation = 1;
let rez = '1:1';
if (allowed_resolutions.length > 0) {
aspectRation = allowed_resolutions[0][0] / allowed_resolutions[0][1];
rez = allowed_resolutions[0][0] + ':' + allowed_resolutions[0][1];
}
const cropContainer = document.createElement('div');
cropContainer.addClass('crop-container');
const cropImgContainer = one('crop-container-img', cropContainer);
const cropsContainer = one('crops-container', cropContainer);
const select = document.createElement('select');
cropImgContainer.addClass('invisible')
const options = [];
allowed_resolutions.forEach(r => {
options.push('<option data-rez="' + r[0] + ':' + r[1] + '" value="' + (r[0] / r[1]) + '">Резолюция ' + r[0] + ':' + r[1] + '</option>');
});
select.innerHTML = options.join('');
cropsContainer.innerHTML = '';
select.addEventListener('change', function () {
cropper.setAspectRatio(parseFloat(this.value));
const s = select.querySelector('option[value="' + this.value + '"]');
rez = s.dataset.rez;
});
cropsContainer.appendChild(select);
const cropBtn = one('btn-ib btn-default', cropsContainer);
cropBtn.innerHTML = '<i class="la la-crop"></i> Изрежи';
cropImgContainer.appendChild(img);
const cropsImgContainer = one('crops-img-container', cropsContainer);
cropsContainer.addClass('disabled');
const cropper = new Cropper(img, {
autoCrop: false,
aspectRatio: aspectRation,
viewMode: 0,
ready() {
this.cropper.crop();
cropImgContainer.removeClass('invisible')
cropImgContainer.removeClass('invisible')
cropsContainer.removeClass('disabled')
},
});
cropBtn.addEventListener('click', function () {
const modalBtnConfirm = one('.modal-button-confirm');
modalBtnConfirm.removeClass('disabled');
const existCrop = one('[data-row-rez="' + rez + '"]');
if (existCrop) {
if (existCrop.querySelector('img'))
existCrop.querySelector('img').remove();
if (existCrop.querySelector('canvas'))
existCrop.querySelector('canvas').remove();
const canvas = cropper.getCroppedCanvas();
existCrop.prepend(canvas);
canvas.toBlob(function (blob) {
bufferFiles[rez] = new File([blob], check.dataset.fileName, {type: check.dataset.fileType});
}, check.dataset.fileType, 0.5)
} else {
createCanvasCropRow(cropper, cropsImgContainer, rez, canvas => {
canvas.toBlob(function (blob) {
bufferFiles[rez] = new File([blob], check.dataset.fileName, {type: check.dataset.fileType});
}, check.dataset.fileType, 0.5)
}, del_rez => {
delete bufferFiles[rez];
if (Object.keys(bufferFiles).length === 0) {
modalBtnConfirm.addClass('disabled');
}
})
}
});
Object.keys(cropFiles).forEach(k => {
createImageCropRow(cropFiles[k], cropsImgContainer, k, check);
})
modal.confirm(cropContainer,
() => {
const keyRez = Object.keys(bufferFiles);
check.checked = false;
check.parentNode.removeClass('checked');
updateActionButtons(check.dataset.objectKey);
const form = one('form');
form.addClass('form-wait');
const waitingType = !one('.waiting-tape') ? one('waiting-tape', document.body) : null;
const fd = new FormData();
fd.append('object_key', check.dataset.objectKey);
fd.append('media_key', check.dataset.mediaKey);
fd.append('file_name', check.dataset.fileName);
fd.append('resolutions', JSON.stringify(keyRez));
keyRez.forEach(rez => {
const file = bufferFiles[rez];
fd.append(rez, file);
});
request({
url: '/upload-crop/',
post: fd,
done: r => {
if (r.resolutions) {
const crops = check.parentNode.querySelector('.crops');
crops.innerHTML = '';
r.resolutions.forEach(rez => {
const cr = document.createElement('span');
cr.innerHTML = rez;
crops.appendChild(cr);
})
}
if (r.files) {
check.setAttribute('data-crop-files', JSON.stringify(r.files))
}
form.removeClass('form-wait');
waitingType.remove();
flash.success('Изображението с резолюцията ' + keyRez.join(', ') + ' е актуализирано успешно', true);
}
})
},
() => {
},
{
width: '80%',
height: '75%'
},
() => {
const modalBtnConfirm = one('.modal-button-confirm');
modalBtnConfirm.addClass('disabled');
}
);
}
function createCanvasCropRow(cropper, cropsImgContainer, rez, callback, callbackDel) {
const canvas = cropper.getCroppedCanvas();
const cropsImgRow = one('crops-img-row', cropsImgContainer);
const cropsImgRez = one('crops-img-rez', cropsImgRow);
cropsImgRez.innerHTML = rez;
const cropsImgDel = one('crops-img-del btn-ib btn-default', cropsImgRow);
cropsImgDel.innerHTML = '<i class="la la-trash"></i>';
cropsImgDel.title = 'Изтрий резолюцията';
cropsImgDel.addEventListener('click', function () {
cropsImgDel.parentNode.remove();
callbackDel(rez);
flash.success('Резолюцията е изтрита');
})
cropsImgRow.prepend(canvas);
cropsImgRow.setAttribute('data-row-rez', rez);
callback(canvas);
}
function createImageCropRow(src, cropsImgContainer, rez, check) {
const img = new Image();
img.src = src + '?t=' + (new Date().getTime());
const cropsImgRow = one('crops-img-row', cropsImgContainer);
const cropsImgRez = one('crops-img-rez', cropsImgRow);
cropsImgRez.innerHTML = rez;
const cropsImgDel = one('crops-img-del btn-ib btn-default', cropsImgRow);
cropsImgDel.innerHTML = '<i class="la la-trash"></i>';
cropsImgDel.title = 'Изтрий резолюцията';
cropsImgDel.addEventListener('click', function () {
cropsImgDel.parentNode.remove();
request({
url: '/delete-crop/',
post: {
del_id: check.dataset.del,
rez: rez
},
done: r => {
if (r.resolutions) {
const crops = check.parentNode.querySelector('.crops');
crops.innerHTML = '';
r.resolutions.forEach(rez => {
const cr = document.createElement('span');
cr.innerHTML = rez;
crops.appendChild(cr);
})
}
if (r.files) {
check.setAttribute('data-crop-files', JSON.stringify(r.files))
}
flash.success('Резолюцията е изтрита', true);
}
})
})
cropsImgRow.prepend(img);
cropsImgRow.setAttribute('data-row-rez', rez);
}
//region [ORDER]
orderItems('.file-img', '/update-file-indexes/');
//endregion