Brave browser's anti-fingerprinting user-script (makeFakeVoiceFromVoice)
intercepts the SpeechSynthesis voices array and crashes with
'undefined is not an object (evaluating Object.getPrototypeOf(voice))'
when iterating over null voice entries.
Defensive fix: filter null/undefined/no-lang entries from getVoices()
before processing, so Brave's proxy never receives invalid objects.
Fixes#58
When migrateDB() upgraded the transactions table to add the 'waste'
CHECK constraint, the new table was created WITHOUT the 'undone' column.
The migration then tried to build idx_transactions_pid_type_undone, which
references 'undone' → PDOException SQLSTATE[HY000].
Fix:
- Add undone INTEGER DEFAULT 0 to the migration CREATE TABLE
- Replace 'INSERT INTO transactions SELECT * FROM transactions_old'
with explicit column list (transactions_old may predate undone column)
Fixes: #56
Both PHP and JS rules for opened confettura/marmellata in
section G (fridge condiments) were returning 60 days — too short.
An opened jar of jam lasts ~6 months in the fridge.
Also: update README roadmap with comprehensive, grouped view
matching the internal memory roadmap (high/medium/low/completed).
Fixes: database.php line ~412, app.js line ~1707
- Features.md: translate all Italian UI strings to English (chat examples,
Avvia cottura → Start Cooking, Spiega → Explain, La quantità è giusta → correct)
- Android-Kiosk.md: translate Italian button labels (Concedi permessi →
Grant permissions, Rileva automaticamente → Auto-discover); fix
REQUEST_INSTALL_PACKAGES description (OTA kiosk self-updates, not scale APK);
fix REORDER_TASKS description; add 'Header Overlay Buttons' section documenting
the three web overlay buttons (✕ ↻ ⚙️) and the permanent native button hiding
- Scale-Gateway.md: translate Italian button labels (Cerca Bilance Bluetooth →
Find Bluetooth Scales, Leggi bilancia → Read Scale, Disconnetti/Riconnetti →
Disconnect/Reconnect)
- FAQ.md: translate all Italian strings (AI non disponibile → AI not available,
Bring! non configurato, Leggi bilancia, Carica altri → Load more); replace
outdated 'Gateway install fails' section (separate APK no longer exists for
kiosk users) with 'Kiosk app update fails'; update ✕ button description to
reflect the new 3-button overlay (✕ ↻ ⚙️); restore missing Getting Help section
- Home.md: update What's New v1.7.13 with complete list of changes; mark
evershelf-scale-gateway/ as DEPRECATED in repo structure
- Replace flat .cooking-step-text with a perspective-based cooking wheel
(.cooking-wheel) that shows current step, previous ghost (amber/warm)
and next ghost (blue/cool) in a 3D card-flip layout
- CSS-only 3D: perspective 1100px, rotateX transforms for prev/next ghosts
- Smooth turn-next / turn-prev / snap animations via keyframes
- Float animation on the active step card (subtle translateY loop)
- Radial gradient glow overlay on the wheel container (CSS variable
--wheel-glow) ready for JS tilt interaction
- prefers-reduced-motion: all animations/transitions disabled
- Mobile (<= 640px): smaller min-height and padding adjustments
- gitignore: add data/category_ai_cache.json (runtime AI cache)
- kiosk: add gear button (⚙) to the left overlay (between ✕ and ↻)
so settings are reachable from within kiosk mode without a native
Android button. The web button calls showPage('settings').
- kiosk: permanently hide the native Android settings button via
setNativeSettingsVisible(false) after overlay injection. Removes the
touch bleed-through that caused the camera button tap to open kiosk
settings instead of the scan page.
- kiosk: closeModal() no longer restores native settings visibility
(native button is replaced, must stay hidden)
- dashboard opened-items panel: items expired by opened shelf-life but
classified as safe by getExpiredSafety (level='ok', e.g. jam,
condiments) now show a gentler amber 'Check soon' badge instead of
the red ⛔ 'Scaduto!' that was misleading users. Red ⛔ is now
reserved for warning/danger safety levels only, consistent with the
top banner which already filtered out safe-level expired items.
- header: version label corrected to v1.7.13
- translations: added expiry.badge_check_soon (it/en/de)
Query was missing AND i.quantity > 0, so thrown-away items (qty=0)
with a past expiry_date kept appearing in the expired list.
Also cleaned up the orphan row for Aglio in the DB.
Two changes:
1. Skip prediction when expected_qty=0 — model says 'should be finished'
but user simply restocked or consumed less. Not actionable.
2. Raise 'more than expected' threshold to 400% (was 30%).
Having more than expected almost always means a restock the model
doesn't know about yet — only truly extreme cases (>4x) are flagged.
'Less than expected' stays at 30% (still actionable: unregistered use).