fix(filter): apply preset on full tile click and suppress i18n double-translate warnings

- Move preset apply handler from span.preset-name to div.filter-preset so
  clicking anywhere on the tile triggers the preset, not just the label text.
- Add whitespace heuristic in showToast() to skip translate() for plain
  messages that are already translated at the call site. This prevents
  i18next from logging 'Translation key not found' for pre-translated
  strings like 'Preset "name" applied'.
This commit is contained in:
Will Miao
2026-07-20 17:57:14 +08:00
parent f53f859a71
commit aebf2e37dd
2 changed files with 14 additions and 15 deletions

View File

@@ -743,8 +743,16 @@ export class FilterPresetManager {
presetEl.classList.add('active'); presetEl.classList.add('active');
} }
presetEl.addEventListener('click', (e) => { // Apply preset on click (toggle if already active)
e.stopPropagation(); // Bind to the whole .filter-preset div so clicking anywhere inside triggers apply
presetEl.addEventListener('click', async () => {
this.cancelPendingDelete();
if (this.activePreset === preset.name) {
await this.filterManager.clearFilters();
} else {
await this.applyPreset(preset.name);
}
}); });
const presetName = document.createElement('span'); const presetName = document.createElement('span');
@@ -757,18 +765,6 @@ export class FilterPresetManager {
deleteBtn.innerHTML = '<i class="fas fa-times"></i>'; deleteBtn.innerHTML = '<i class="fas fa-times"></i>';
deleteBtn.title = translate('header.filter.presetDeleteTooltip', {}, 'Delete preset'); deleteBtn.title = translate('header.filter.presetDeleteTooltip', {}, 'Delete preset');
// Apply preset on name click (toggle if already active)
presetName.addEventListener('click', async (e) => {
e.stopPropagation();
this.cancelPendingDelete();
if (this.activePreset === preset.name) {
await this.filterManager.clearFilters();
} else {
await this.applyPreset(preset.name);
}
});
// Two-step delete on delete button click // Two-step delete on delete button click
deleteBtn.addEventListener('click', (e) => { deleteBtn.addEventListener('click', (e) => {
e.stopPropagation(); e.stopPropagation();

View File

@@ -134,7 +134,10 @@ export async function copyToClipboard(text, successMessage = null) {
} }
export function showToast(key, params = {}, type = 'info', fallback = null) { export function showToast(key, params = {}, type = 'info', fallback = null) {
const message = translate(key, params, fallback); // Plain messages (contain spaces) are not i18n dot-notation keys — use verbatim
// to avoid spurious "Translation key not found" warnings from i18next
const isPlainMessage = typeof key === 'string' && /\s/.test(key);
const message = isPlainMessage ? key : translate(key, params, fallback);
const toast = document.createElement('div'); const toast = document.createElement('div');
toast.className = `toast toast-${type}`; toast.className = `toast toast-${type}`;
toast.textContent = message; toast.textContent = message;