fix(modal,tags): five UX follow-ups
1. Hide 'archive' kind from /tags default view. Archive tags only appear when the user explicitly requests them via ?kind=archive. _get_tags_with_previews gains a default_excluded_kinds tuple that applies when no explicit kind filter is set. 2. Hide the 'Add' submit button on desktop (>=768px). Enter in the tag input (and in the fandom picker when no row is highlighted) already submits; the button is only needed for mobile virtual keyboards where Enter-to-submit is unreliable. 3. Fandom picker keyboard parity: ArrowUp/Down navigate rows, Enter picks a highlighted row or (if no row is highlighted) submits the whole add-tag form. Escape clears the highlight. Mirrors the main tagInput's keyboard block. 4. Tag editor merge bug: the edit modal populated nameInput.value with data.tag.display_name — for a character with a fandom, that value is 'Name (Fandom)'. Saving without stripping the suffix routed to a rename that never collided with the canonical bare name, so the merge offer never fired. Now uses data.tag.name (the bare form). The (Fandom) display is still shown in the fandom input which is rendered separately. 5. Fandom picker styling: match the main tag-form input — same padding, border, background, focus state. Drop the separate 'Fandom' label; the placeholder 'Fandom (optional)' now carries the label role. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -879,12 +879,30 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
}
|
||||
|
||||
let fandomPickerSelectedIdx = -1;
|
||||
|
||||
function highlightFandomItem(idx) {
|
||||
if (!fandomPickerAutocomplete) return;
|
||||
const items = fandomPickerAutocomplete.querySelectorAll('.tag-autocomplete-item');
|
||||
items.forEach((el, i) => el.classList.toggle('selected', i === idx));
|
||||
fandomPickerSelectedIdx = idx;
|
||||
}
|
||||
|
||||
function pickFandomRow(row) {
|
||||
if (!row || !fandomPickerInput) return;
|
||||
fandomPickerInput.value = row.dataset.fandomName;
|
||||
fandomPickerInput.dataset.fandomId = row.dataset.fandomId;
|
||||
clearFandomAutocomplete();
|
||||
fandomPickerSelectedIdx = -1;
|
||||
}
|
||||
|
||||
if (fandomPickerInput) {
|
||||
fandomPickerInput.addEventListener('input', () => {
|
||||
clearTimeout(fandomPickerDebounce);
|
||||
const term = fandomPickerInput.value.trim();
|
||||
// Any typing invalidates a previously-selected fandom id.
|
||||
// Any typing invalidates a previously-selected fandom id + highlight.
|
||||
delete fandomPickerInput.dataset.fandomId;
|
||||
fandomPickerSelectedIdx = -1;
|
||||
if (!term) {
|
||||
clearFandomAutocomplete();
|
||||
return;
|
||||
@@ -896,6 +914,33 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
.catch(() => clearFandomAutocomplete());
|
||||
}, 150);
|
||||
});
|
||||
|
||||
// Keyboard parity with the main tagInput: ArrowDown/Up to navigate rows,
|
||||
// Enter to pick a highlighted row (or submit the whole form when no row
|
||||
// is highlighted), Escape to clear the highlight.
|
||||
fandomPickerInput.addEventListener('keydown', (e) => {
|
||||
const rows = fandomPickerAutocomplete
|
||||
? fandomPickerAutocomplete.querySelectorAll('.tag-autocomplete-item')
|
||||
: [];
|
||||
const count = rows.length;
|
||||
if (e.key === 'ArrowDown' && count > 0) {
|
||||
e.preventDefault();
|
||||
highlightFandomItem(Math.min(fandomPickerSelectedIdx + 1, count - 1));
|
||||
} else if (e.key === 'ArrowUp' && count > 0) {
|
||||
e.preventDefault();
|
||||
highlightFandomItem(Math.max(fandomPickerSelectedIdx - 1, 0));
|
||||
} else if (e.key === 'Enter') {
|
||||
if (fandomPickerSelectedIdx >= 0 && rows[fandomPickerSelectedIdx]) {
|
||||
e.preventDefault();
|
||||
pickFandomRow(rows[fandomPickerSelectedIdx]);
|
||||
} else {
|
||||
e.preventDefault();
|
||||
submitTag();
|
||||
}
|
||||
} else if (e.key === 'Escape') {
|
||||
highlightFandomItem(-1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (fandomPickerAutocomplete) {
|
||||
@@ -903,11 +948,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const row = e.target.closest('[data-fandom-id]');
|
||||
if (!row) return;
|
||||
e.preventDefault(); // keep focus on the input
|
||||
if (fandomPickerInput) {
|
||||
fandomPickerInput.value = row.dataset.fandomName;
|
||||
fandomPickerInput.dataset.fandomId = row.dataset.fandomId;
|
||||
}
|
||||
clearFandomAutocomplete();
|
||||
pickFandomRow(row);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user