feat: v1.7.9 — category badges, category search, AI guards

- Category badge on every inventory item (icon + label); 'altro' items
  refined asynchronously via new guess_category Gemini endpoint
  (data/category_ai_cache.json) — no AI call when key not configured
- Category search: inventory search now matches by macro-category key
  and translated label (e.g. 'biscotti' finds all cookie items)
- Brand fast-path in guessCategoryFromName (Oreo, Barilla, Lavazza…)
- Fix: duplicate banner alerts — _bannerLoading guard + _queuedItemIds Set
- Fix: mapToLocalCategory with en:dairies (dairi stem added)
- Fix: mapToLocalCategory no longer blocks on 'altro' — falls back to
  guessCategoryFromName(productName) before returning 'altro'
- Fix: 'Tonno all'olio' was resolving to condimenti — moved tonno\b
  check before olio\b in conserve regex block
- AI guards: _refineCategoryBadgesAsync and fetchAllPrices now check
  _geminiAvailable (JS); getShoppingPrice returns no_api_key (PHP)
  when GEMINI_API_KEY is not set — all AI functions are now explicit
This commit is contained in:
dadaloop82
2026-05-11 05:53:15 +00:00
parent 763b7fd057
commit da62647089
10 changed files with 333 additions and 44 deletions
+10 -3
View File
@@ -11,7 +11,7 @@
<title>EverShelf</title>
<link rel="manifest" href="manifest.json">
<link rel="icon" type="image/png" href="assets/img/logo/logo_icon.png">
<link rel="stylesheet" href="assets/css/style.css?v=20260508c">
<link rel="stylesheet" href="assets/css/style.css?v=20260511a">
<!-- QuaggaJS for barcode scanning -->
<script src="https://cdn.jsdelivr.net/npm/@ericblade/quagga2@1.8.4/dist/quagga.min.js"></script>
<!-- @xenova/transformers: ES-module bootstrap that exposes a lazy category-classifier as window._categoryPipelinePromise -->
@@ -67,7 +67,7 @@
<!-- Title — left-aligned; grows to fill space -->
<div class="header-title-wrap">
<h1 class="header-title" onclick="showPage('dashboard')">
<img src="assets/img/logo/logo_icon.png" alt="" class="header-logo-icon" aria-hidden="true" /><span data-i18n="nav.title">EverShelf</span><span class="header-version">v1.7.6</span>
<img src="assets/img/logo/logo_icon.png" alt="" class="header-logo-icon" aria-hidden="true" /><span data-i18n="nav.title">EverShelf</span><span class="header-version">v1.7.9</span>
</h1>
<!-- Update badge — shown alongside title, never replaces it -->
<span class="header-update-badge" id="header-update-badge" style="display:none"></span>
@@ -94,6 +94,13 @@
</div>
</header>
<!-- Offline / server-unreachable banner -->
<div id="offline-banner" class="offline-banner" style="display:none" role="alert" aria-live="assertive">
<span class="offline-banner-icon" aria-hidden="true">🔌</span>
<span class="offline-banner-text" data-i18n="error.server_offline">Connessione al server persa</span>
<button class="offline-banner-retry" onclick="_heartbeatRetry()" data-i18n="error.server_retry">Riprova</button>
</div>
<!-- Main Content Area -->
<main class="app-content" id="app-content">
@@ -1462,6 +1469,6 @@
</div>
</div>
<script src="assets/js/app.js?v=20260510k"></script>
<script src="assets/js/app.js?v=20260511a"></script>
</body>
</html>