refactor(js): tag-utils uses display_name and tag_id
getTagDisplayName is now a passthrough; post-refactor names are bare and callers that need the character+fandom suffix pass tag.display_name from the server. createTagChipHtml builds ?tag_id=<int> URLs and uses display_name for the label. bulk-select.js callers pass display_name directly. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -270,7 +270,7 @@
|
|||||||
|
|
||||||
dom.commonTags.innerHTML = tags.map(t => {
|
dom.commonTags.innerHTML = tags.map(t => {
|
||||||
const icon = getTagIcon(t.kind);
|
const icon = getTagIcon(t.kind);
|
||||||
const display = getTagDisplayName(t.name, t.kind);
|
const display = t.display_name || t.name;
|
||||||
const escapedName = escapeHtml(t.name);
|
const escapedName = escapeHtml(t.name);
|
||||||
const escapedDisplay = escapeHtml(display);
|
const escapedDisplay = escapeHtml(display);
|
||||||
return `<span class="tag-chip removable" data-name="${escapedName}">
|
return `<span class="tag-chip removable" data-name="${escapedName}">
|
||||||
@@ -605,7 +605,7 @@
|
|||||||
|
|
||||||
dom.autocomplete.innerHTML = tags.map((t, i) => {
|
dom.autocomplete.innerHTML = tags.map((t, i) => {
|
||||||
const icon = getTagIcon(t.kind);
|
const icon = getTagIcon(t.kind);
|
||||||
const displayName = getTagDisplayName(t.name, t.kind);
|
const displayName = t.display_name || t.name;
|
||||||
return `<div class="tag-autocomplete-item" data-index="${i}" data-name="${escapeHtml(t.name)}">
|
return `<div class="tag-autocomplete-item" data-index="${i}" data-name="${escapeHtml(t.name)}">
|
||||||
<span>${icon} ${escapeHtml(displayName)}</span>
|
<span>${icon} ${escapeHtml(displayName)}</span>
|
||||||
<span class="tag-kind">${t.kind || 'user'}</span>
|
<span class="tag-kind">${t.kind || 'user'}</span>
|
||||||
|
|||||||
+31
-31
@@ -24,36 +24,36 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get display name for a tag, stripping the prefix if present
|
* Get display name for a tag.
|
||||||
* @param {string} name - Full tag name (e.g., "artist:Name")
|
*
|
||||||
* @param {string} [kind] - Optional tag kind for context
|
* Post-refactor tag names are stored bare (no kind: prefix), so this helper
|
||||||
* @returns {string} Display name without prefix
|
* is now a near-passthrough. Callers that need character+fandom qualified
|
||||||
|
* names (e.g. "Ruby Rose (RWBY)") should pass `tag.display_name` from the
|
||||||
|
* server response directly.
|
||||||
|
*
|
||||||
|
* @param {string} name - Bare tag name
|
||||||
|
* @returns {string} The name unchanged
|
||||||
*/
|
*/
|
||||||
function getTagDisplayName(name, kind) {
|
function getTagDisplayName(name) {
|
||||||
// For prefixed kinds, strip the prefix
|
|
||||||
if (kind && ['artist', 'character', 'series', 'fandom', 'rating'].includes(kind)) {
|
|
||||||
return name.includes(':') ? name.split(':', 2)[1] : name;
|
|
||||||
}
|
|
||||||
// If no kind specified but has colon, assume it's prefixed
|
|
||||||
if (!kind && name.includes(':')) {
|
|
||||||
return name.split(':', 2)[1];
|
|
||||||
}
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get display name for tag overlay (used in gallery items)
|
* Get overlay-formatted display name for a tag.
|
||||||
* Returns name with # prefix for unprefixed user tags
|
*
|
||||||
* @param {string} name - Full tag name
|
* User-kind (untyped) tags get a '#' hashtag prefix; every other kind
|
||||||
|
* gets the bare name (or whatever display form the caller passed).
|
||||||
|
*
|
||||||
|
* @param {string} name - Bare tag name or pre-rendered display_name
|
||||||
* @param {string} kind - Tag kind
|
* @param {string} kind - Tag kind
|
||||||
* @returns {string} Display name for overlay
|
* @returns {string} Overlay label
|
||||||
*/
|
*/
|
||||||
function getTagDisplayNameForOverlay(name, kind) {
|
function getTagDisplayNameForOverlay(name, kind) {
|
||||||
if (['artist', 'character', 'series', 'fandom', 'rating'].includes(kind)) {
|
if (!kind || kind === 'user') {
|
||||||
return name.includes(':') ? name.split(':', 2)[1] : name;
|
|
||||||
}
|
|
||||||
return '#' + name;
|
return '#' + name;
|
||||||
}
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Escape HTML special characters
|
* Escape HTML special characters
|
||||||
@@ -68,13 +68,13 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a tag for display with icon and name
|
* Format a tag for display with icon and name
|
||||||
* @param {Object} tag - Tag object with name and kind
|
* @param {Object} tag - Tag object with name, kind, and optional display_name
|
||||||
* @returns {string} Formatted HTML string
|
* @returns {string} Formatted HTML string
|
||||||
*/
|
*/
|
||||||
function formatTagHtml(tag) {
|
function formatTagHtml(tag) {
|
||||||
const icon = getTagIcon(tag.kind);
|
const icon = getTagIcon(tag.kind);
|
||||||
const displayName = getTagDisplayName(tag.name, tag.kind);
|
const label = tag.display_name || tag.name;
|
||||||
const escaped = escapeHtml(displayName);
|
const escaped = escapeHtml(label);
|
||||||
|
|
||||||
if (icon !== '#') {
|
if (icon !== '#') {
|
||||||
return `${icon} ${escaped}`;
|
return `${icon} ${escaped}`;
|
||||||
@@ -83,21 +83,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create tag chip HTML for gallery overlays
|
* Create tag chip HTML for gallery overlays.
|
||||||
* @param {Object} tag - Tag object with name and kind
|
*
|
||||||
|
* @param {Object} tag - Tag object with id, name, kind, and optional display_name
|
||||||
* @param {boolean} [stopPropagation=true] - Add onclick to stop propagation
|
* @param {boolean} [stopPropagation=true] - Add onclick to stop propagation
|
||||||
* @returns {string} HTML string for tag chip link
|
* @returns {string} HTML string for tag chip link
|
||||||
*/
|
*/
|
||||||
function createTagChipHtml(tag, stopPropagation = true) {
|
function createTagChipHtml(tag, stopPropagation = true) {
|
||||||
const icon = getTagIcon(tag.kind);
|
const icon = getTagIcon(tag.kind);
|
||||||
const displayName = getTagDisplayNameForOverlay(tag.name, tag.kind);
|
const label = tag.display_name || getTagDisplayNameForOverlay(tag.name, tag.kind);
|
||||||
const encodedName = encodeURIComponent(tag.name);
|
const escapedLabel = escapeHtml(label);
|
||||||
const escapedTitle = escapeHtml(tag.name);
|
const escapedTitle = escapeHtml(tag.display_name || tag.name);
|
||||||
const escapedDisplay = escapeHtml(displayName);
|
const prefix = icon !== '#' ? icon + ' ' : '';
|
||||||
const prefix = icon !== '#' ? icon + ' ' : '#';
|
|
||||||
const onclick = stopPropagation ? ' onclick="event.stopPropagation()"' : '';
|
const onclick = stopPropagation ? ' onclick="event.stopPropagation()"' : '';
|
||||||
|
|
||||||
return `<a class="tag-chip" href="/gallery?tag=${encodedName}" title="Filter by ${escapedTitle}"${onclick}>${prefix}${escapedDisplay}</a>`;
|
return `<a class="tag-chip tag-chip-${tag.kind || 'user'}" href="/gallery?tag_id=${tag.id}" title="Filter by ${escapedTitle}"${onclick}>${prefix}${escapedLabel}</a>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export to window.TagUtils
|
// Export to window.TagUtils
|
||||||
|
|||||||
Reference in New Issue
Block a user