This commit is contained in:
2026-09-13 21:55:23 +02:00
parent 399f2be456
commit ba5bc18b98
32 changed files with 1739 additions and 270 deletions
+51 -15
View File
@@ -12,8 +12,14 @@
const tagsContainer = document.querySelector("#tags");
const inner = tagsContainer ? (tagsContainer.querySelector(".tags-inner") || tagsContainer) : null;
const usernameEl = document.querySelector("a#a_username");
const currentSub = (window.albumGallery && typeof window.albumGallery.getCurrentSubf0ck === 'function')
? window.albumGallery.getCurrentSubf0ck()
: null;
const subf0ck_id = currentSub ? (currentSub.slug || currentSub.id) : (tagsContainer?.dataset?.subf0ckSlug || tagsContainer?.dataset?.subf0ckId || null);
return {
postid: /^\d+$/.test(String(rawId).trim()) ? parseInt(rawId, 10) : rawId.trim(),
subf0ck_id,
// data-username holds the raw DB username; data-author-id holds the user's numeric ID.
// Never fall back to innerText — it may be a display name or the literal string 'unknown'.
poster: (usernameEl?.dataset?.username || '').trim() || null,
@@ -81,7 +87,7 @@
contentEl.textContent = tag.tag;
} else {
contentEl = document.createElement("a");
contentEl.href = `/tag/${tag.normalized}`;
contentEl.href = "/tag/" + tag.normalized;
contentEl.style = "color: inherit !important";
contentEl.textContent = tag.tag;
}
@@ -102,19 +108,27 @@
span.classList.add('can-cycle');
}
} else if (!window.f0ckSession?.is_anonymized && window.f0ckSession?.logged_in && !window.f0ckSession?.is_anon && (tag.display_name || tag.user)) {
span.setAttribute('tooltip', tag.display_name || tag.user);
span.setAttribute("tooltip", tag.display_name || tag.user);
}
span.appendChild(contentEl);
if (!isRating && tag.can_exclude) {
const excludeBtn = document.createElement("button");
excludeBtn.type = "button";
excludeBtn.className = "tag-exclude-btn";
excludeBtn.setAttribute("title", tag.is_excluded ? "Excluded (click to unexclude)" : "Exclude tag");
excludeBtn.setAttribute("aria-label", "Exclude tag");
excludeBtn.innerHTML = `<i class="fa-solid ${tag.is_excluded ? 'fa-circle-check' : 'fa-ban'}"></i>`;
span.appendChild(excludeBtn);
}
if (!isRating) {
const delbutton = document.createElement("a");
delbutton.innerHTML = '<i class="fa-solid fa-xmark"></i>';
delbutton.href = "javascript:void(0)";
// Class for delegation
delbutton.href = "#";
delbutton.classList.add("admin-deltag", "removetag");
span.appendChild(document.createTextNode('\u00A0'));
delbutton.innerHTML = '<i class="fa-solid fa-xmark"></i>';
span.appendChild(document.createTextNode(" "));
span.appendChild(delbutton);
}
@@ -188,7 +202,7 @@
e.stopImmediatePropagation();
const ctx = getContext();
if (!ctx) return;
const { postid } = ctx;
const { postid, subf0ck_id } = ctx;
let target = e.target;
if (target.nodeType === 3) target = target.parentElement;
@@ -202,8 +216,12 @@
if (typeof ModAction === 'undefined') return alert('Error: ModAction module not loaded');
ModAction.confirm((window.f0ckI18n && window.f0ckI18n.tag_delete_title) || 'Delete Tag', `${(window.f0ckI18n && window.f0ckI18n.tag_delete_confirm) || 'Are you sure you want to delete the tag'} <strong style="color:#d9534f">${tagname}</strong>?`, async (reason) => {
// Send reason via query param for DELETE request
const res = await (await fetch("/api/v2/tags/" + postid + "/" + encodeURIComponent(tagname) + (reason ? "?reason=" + encodeURIComponent(reason) : ""), {
const qs = new URLSearchParams();
if (reason) qs.set('reason', reason);
if (subf0ck_id) qs.set('subf0ck_id', subf0ck_id);
const qsStr = qs.toString();
const res = await (await fetch("/api/v2/tags/" + postid + "/" + encodeURIComponent(tagname) + (qsStr ? "?" + qsStr : ""), {
method: 'DELETE',
headers: { "X-CSRF-Token": window.f0ckSession?.csrf_token }
})).json();
@@ -211,6 +229,10 @@
if (!res.success) {
throw new Error(res.msg || "Error deleting tag");
}
if (window.albumGallery && typeof window.albumGallery.getCurrentSubf0ck === 'function') {
const cur = window.albumGallery.getCurrentSubf0ck();
if (cur && res.tags) cur.tags = res.tags;
}
renderTags(res.tags);
if (window.flashMessage) window.flashMessage((window.f0ckI18n?.tag_deleted_success) || 'Tag deleted', 2500, 'success');
}, { allowEmpty: window.f0ckSession?.is_admin });
@@ -220,7 +242,7 @@
if (e) e.preventDefault();
const ctx = getContext();
if (!ctx) return;
const { postid, tags } = ctx;
const { postid, subf0ck_id, tags } = ctx;
const anchor = document.querySelector("a#a_addtag");
if (!anchor) return;
@@ -229,13 +251,27 @@
existingTags: tags,
anchorEl: anchor,
onSubmit: async (tag) => {
const res = await post("/api/v2/tags/" + postid, { tagname: tag });
if (res.success && window.invalidateItemCache) {
window.invalidateItemCache(postid);
const payload = { tagname: tag };
if (subf0ck_id) payload.subf0ck_id = subf0ck_id;
const res = await post("/api/v2/tags/" + postid, payload);
if (res.success) {
if (window.albumGallery && typeof window.albumGallery.getCurrentSubf0ck === 'function') {
const cur = window.albumGallery.getCurrentSubf0ck();
if (cur && res.tags) cur.tags = res.tags;
}
if (window.invalidateItemCache) {
window.invalidateItemCache(postid);
}
}
return res;
},
renderTags
renderTags: (newTags, hl) => {
if (window.albumGallery && typeof window.albumGallery.getCurrentSubf0ck === 'function') {
const cur = window.albumGallery.getCurrentSubf0ck();
if (cur) cur.tags = newTags;
}
renderTags(newTags, hl);
}
});
};