Update project files
This commit is contained in:
+75
-3
@@ -23,7 +23,7 @@ async function loadGroups() {
|
||||
list.innerHTML = `<div class="group-grid">` + groups.map(g => {
|
||||
const schedSet = g.day_of_week != null && g.time_start && g.time_end;
|
||||
return `
|
||||
<div class="group-card">
|
||||
<div class="group-card" data-group-id="${g.id}">
|
||||
${g.cover_path
|
||||
? `<img class="group-cover" src="${API}${g.cover_path}" data-group-id="${g.id}" data-group-name="${esc(g.name)}" title="Фото группы (хронология)" alt="">`
|
||||
: `<div class="group-cover empty-cover" data-group-id="${g.id}" data-group-name="${esc(g.name)}" title="Фото группы (хронология)">📷</div>`}
|
||||
@@ -149,7 +149,8 @@ function photoHTML(p) {
|
||||
const uploaded = `Загружено: ${new Date(p.created_at).toLocaleDateString('ru')}`;
|
||||
const isCover = currentCover && p.photo_path === currentCover;
|
||||
return `
|
||||
<div class="photo-item" data-photo-id="${p.id}" data-photo-path="${esc(p.photo_path)}">
|
||||
<div class="photo-item" data-photo-id="${p.id}" data-photo-path="${esc(p.photo_path)}" draggable="true">
|
||||
<div class="drag-hint" title="Перетащите, чтобы изменить порядок">⠿</div>
|
||||
<img src="${API}${p.photo_path}" data-img="${API}${p.photo_path}" alt="">
|
||||
<div class="p-cap">${esc(p.caption || '')}</div>
|
||||
<div class="p-date">${taken ? taken + ' · ' : ''}${uploaded}</div>
|
||||
@@ -236,6 +237,8 @@ async function deletePhoto(id) {
|
||||
if (!confirm('Удалить это фото безвозвратно?')) return;
|
||||
const res = await fetch(`${API}/api/groups/${currentGroupId}/photos/${id}`, { method: 'DELETE', headers: hdr() });
|
||||
if (!res.ok) { const e = await res.json(); alert(e.error || 'Ошибка'); return; }
|
||||
const p = photos.find(x => x.id === id);
|
||||
if (p && currentCover === p.photo_path) currentCover = null;
|
||||
showToast('Фото удалено');
|
||||
loadGroupPhotos();
|
||||
loadGroups();
|
||||
@@ -306,6 +309,73 @@ document.getElementById('groupList').addEventListener('click', e => {
|
||||
}
|
||||
});
|
||||
|
||||
function updateGroupCoverUI(coverPath) {
|
||||
const card = document.querySelector(`.group-card[data-group-id="${currentGroupId}"]`);
|
||||
if (!card) return;
|
||||
const g = allGroups.find(x => String(x.id) === String(currentGroupId));
|
||||
const name = g ? g.name : currentGroupName;
|
||||
const existing = card.querySelector('.group-cover');
|
||||
if (existing && existing.tagName === 'IMG') { existing.src = API + coverPath; return; }
|
||||
const el = document.createElement('img');
|
||||
el.className = 'group-cover';
|
||||
el.src = API + coverPath;
|
||||
el.dataset.groupId = String(currentGroupId);
|
||||
el.dataset.groupName = name;
|
||||
el.title = 'Фото группы (хронология)';
|
||||
el.alt = '';
|
||||
if (existing) existing.replaceWith(el);
|
||||
else card.insertBefore(el, card.firstChild);
|
||||
}
|
||||
|
||||
let dragPhotoId = null;
|
||||
|
||||
async function persistPhotoOrder() {
|
||||
const items = [...document.querySelectorAll('#photoGrid .photo-item')];
|
||||
const order = items.map(el => parseInt(el.dataset.photoId, 10));
|
||||
if (JSON.stringify(order) === JSON.stringify(photos.map(p => p.id))) return;
|
||||
const res = await fetch(`${API}/api/groups/${currentGroupId}/photos/reorder`, {
|
||||
method: 'PUT',
|
||||
headers: hdrJson(),
|
||||
body: JSON.stringify({ order })
|
||||
});
|
||||
if (res.ok) showToast('Порядок фото сохранён');
|
||||
else {
|
||||
try { const err = await res.json(); alert(err.error || 'Ошибка'); } catch { alert('Ошибка'); }
|
||||
loadGroupPhotos();
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('photoGrid').addEventListener('dragstart', e => {
|
||||
const item = e.target.closest('.photo-item');
|
||||
if (!item) return;
|
||||
e.stopPropagation();
|
||||
dragPhotoId = parseInt(item.dataset.photoId, 10);
|
||||
item.classList.add('dragging');
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
e.dataTransfer.setData('text/plain', String(dragPhotoId));
|
||||
});
|
||||
|
||||
document.getElementById('photoGrid').addEventListener('dragover', e => {
|
||||
e.preventDefault();
|
||||
e.dataTransfer.dropEffect = 'move';
|
||||
const target = e.target.closest('.photo-item');
|
||||
const dragged = dragPhotoId != null ? document.querySelector(`.photo-item[data-photo-id="${dragPhotoId}"]`) : null;
|
||||
if (!target || !dragged || target === dragged) return;
|
||||
if (target.contains(dragged)) return;
|
||||
const rect = target.getBoundingClientRect();
|
||||
const grid = document.getElementById('photoGrid');
|
||||
grid.insertBefore(dragged, e.clientX > rect.left + rect.width / 2 ? target.nextSibling : target);
|
||||
});
|
||||
|
||||
document.getElementById('photoGrid').addEventListener('dragend', e => {
|
||||
const item = e.target.closest('.photo-item');
|
||||
if (item) item.classList.remove('dragging');
|
||||
if (dragPhotoId != null) persistPhotoOrder();
|
||||
dragPhotoId = null;
|
||||
});
|
||||
|
||||
document.getElementById('photoGrid').addEventListener('drop', e => e.preventDefault());
|
||||
|
||||
document.getElementById('photoGrid').addEventListener('click', async e => {
|
||||
const coverBtn = e.target.closest('.p-cover');
|
||||
if (coverBtn) {
|
||||
@@ -320,9 +390,11 @@ document.getElementById('photoGrid').addEventListener('click', async e => {
|
||||
if (res.ok) {
|
||||
const g = await res.json();
|
||||
currentCover = g.cover_path || null;
|
||||
const grp = allGroups.find(x => String(x.id) === String(currentGroupId));
|
||||
if (grp) grp.cover_path = currentCover;
|
||||
showToast('Обложка обновлена');
|
||||
updateGroupCoverUI(currentCover);
|
||||
loadGroupPhotos();
|
||||
loadGroups();
|
||||
} else {
|
||||
const err = await res.json();
|
||||
alert(err.error || 'Ошибка');
|
||||
|
||||
Reference in New Issue
Block a user