Commit Graph

308 Commits

Author SHA1 Message Date
dadaloop82 0830b1b168 fix: remove BLE scan UUID filter to support non-standard scales (LePulse, etc)
Many consumer scales like LePulse FI2016LB don't advertise standard
Weight Scale (0x181D) or Body Composition (0x181B) service UUIDs.
Remove the scan filter so all BLE devices are discovered.
The GATT fallback already handles proprietary services.
2026-04-14 17:18:41 +00:00
dadaloop82 7ff7f56e0b fix: fix invalid XML in launcher foreground vector drawable latest 2026-04-14 16:54:11 +00:00
dadaloop82 2740be3bdf fix: add missing launcher icon resources (mipmap + adaptive icon) 2026-04-14 16:49:50 +00:00
dadaloop82 d1c46a0bcb fix: add gradle.properties with android.useAndroidX=true for APK build 2026-04-14 16:45:23 +00:00
dadaloop82 df9de2d257 ci: fix broken YAML - multiline notes had zero indentation breaking the literal block 2026-04-14 16:42:35 +00:00
dadaloop82 fb134128fe ci: trigger workflow with direct commit on main 2026-04-14 16:39:39 +00:00
dadaloop82 329eed5082 Merge branch 'develop' 2026-04-14 16:38:09 +00:00
dadaloop82 0a11214d3d ci: remove paths filter - run on every push to main to ensure APK is always built 2026-04-14 16:38:07 +00:00
dadaloop82 390221ed4c Merge branch 'develop' 2026-04-14 16:33:38 +00:00
dadaloop82 38d8fa7afe ci: fix workflow - use gradle directly instead of ./gradlew (wrapper jar not in repo) 2026-04-14 16:33:35 +00:00
dadaloop82 18af2e9ef4 Merge branch 'develop' 2026-04-14 16:31:59 +00:00
dadaloop82 3fcded1d9b ci: also trigger workflow on changes to the workflow file itself 2026-04-14 16:31:56 +00:00
dadaloop82 b7dd197944 Merge branch 'develop' 2026-04-14 16:29:12 +00:00
dadaloop82 9523b68fea ci: add GitHub Actions workflow to build & release Scale Gateway APK
- Add .github/workflows/build-scale-gateway.yml
  Triggers on push to main (evershelf-scale-gateway/** path filter)
  Builds debug APK with Gradle/JDK 17, renames to evershelf-scale-gateway.apk
  Creates/updates 'latest' GitHub Release so the direct download URL resolves
- Bump web app version v1.2.0 -> v1.3.0 (index.html)
- Bump Android versionCode 1->2, versionName 1.0.0->1.3.0 (app/build.gradle.kts)
2026-04-14 16:29:00 +00:00
dadaloop82 0893742f05 feat: add smart scale BLE gateway integration
- Add evershelf-scale-gateway/ Android app (Kotlin):
  - BLE scanning and GATT connection to smart scales
  - Supports BT SIG Weight Scale (0x181D), Body Composition (0x181B), and generic heuristic parser
  - WebSocket server on port 8765 (local LAN)
  - Real-time weight broadcasting to EverShelf browser client
- Add scale status indicator in header (green/orange/grey dot)
- Add Settings tab for scale configuration (URL, enable toggle, test, APK download link)
- Add 'Read from scale' button in Add/Use forms when unit is g or ml
- Add scale WebSocket client logic in app.js with auto-reconnect
- Fix recipe suggestion: expiry-prioritized ingredients now only injected into
  AI prompt when user explicitly selects 'Priorità Scadenze' or 'Zero Sprechi'
- Update README with smart scale section and website link
- Update all translations (it, en, de) with scale strings
2026-04-14 15:59:40 +00:00
dadaloop82 7fa8395e9e docs: move screenshots section to end of README, translate to English 2026-04-13 11:02:56 +00:00
dadaloop82 f2b518dd4b docs: move screenshots section to end of README, translate to English 2026-04-13 11:02:49 +00:00
dadaloop82 2f21be8829 docs: merge screenshots and README update from develop 2026-04-13 11:00:45 +00:00
dadaloop82 7e9ae24f88 docs: add 9 app screenshots to README and assets
- Add 9 curated screenshots to assets/img/screenshots/ covering all main features
- Update README with 3x3 screenshot table with Italian descriptions
- Anchor /screenshots/ gitignore rule so assets/img/screenshots/ is tracked
- Screenshots cover: dashboard, inventory, barcode scanner, recipe detail,
  recipes list, cooking mode, AI chat, shopping list, smart predictions
2026-04-13 11:00:25 +00:00
dadaloop82 0c6a07ee95 fix: preserve version badge during i18n translatePage
Move data-i18n to inner <span> so translatePage() with textContent
does not overwrite the sibling .header-version span.
2026-04-13 10:23:26 +00:00
dadaloop82 66b75b1537 Merge develop: v1.2.0 - EverShelf rebrand
Merging all changes from develop into main for v1.2.0 release:
- Project renamed from Dispensa Manager to EverShelf
- Contact email: evershelfproject@gmail.com
- All localStorage keys migrated: dispensa_* -> evershelf_*
- SQLite DB renamed: dispensa.db -> evershelf.db
- Docker/Apache resources renamed to evershelf
- Version badge added to app header
- App name updated in all translations (it, en, de)
- Asset version strings bumped to bust browser cache
- JS file truncation fix (safe Python-based replacements)
- CHANGELOG, manifest.json, OpenAPI spec updated for v1.2.0
v1.2.0
2026-04-13 10:21:28 +00:00
dadaloop82 874a242149 release: v1.2.0 - EverShelf rebrand + version badge
- Add v1.2.0 version badge to app header
- Update CHANGELOG with v1.2.0 entries
- Bump manifest.json version to 1.2.0
- Bump OpenAPI spec version to 1.2.0
2026-04-13 10:21:16 +00:00
dadaloop82 a1873d3f81 fix: bump asset versions to bust browser cache (20260413a)
After JS truncation and recovery, browsers may have cached the broken app.js.
Bumping ?v= query strings forces fresh download of app.js and style.css.
2026-04-13 10:18:56 +00:00
dadaloop82 c52a91e779 fix: restore app.js after sed truncation, update nav title to EverShelf
- Recover app.js from pre-rebrand commit and re-apply all substitutions safely
- Fix all localStorage keys: dispensa_* -> evershelf_* (settings, setup, lang)
- Fix TTS test strings: 'Dispensa Manager' -> 'EverShelf'
- Set nav.title to EverShelf in it/en/de translations and HTML fallback
- Fix JS syntax error (Unexpected end of input) that broke the site
- CI JavaScript Lint should now pass
2026-04-13 10:14:40 +00:00
dadaloop82 20f734d54a rebrand: rename project from Dispensa Manager to EverShelf
- Update app name across all files (manifest, index.html, README, docs)
- Update contact email to evershelfproject@gmail.com
- Rename Docker service/container/volume to evershelf
- Rename localStorage keys: dispensa_* → evershelf_*
- Rename SQLite DB reference: dispensa.db → evershelf.db
- Update SSH remote to dadaloop82/EverShelf
- Update Apache conf file name to evershelf.conf
- Update CI workflow Docker image/container names
- Update cron job example path
- Add data/dispensa.db to .gitignore to prevent accidental commit
2026-04-13 10:09:33 +00:00
dadaloop82 2ea0c68f2e Merge develop: offline browser TTS 2026-04-10 10:19:02 +00:00
dadaloop82 da962581c0 feat: offline browser TTS engine with voice selector
Add Web Speech API as alternative TTS engine (fully offline, no config needed).
- Engine selector in settings: 'browser' (offline) or 'server' (HTTP endpoint)
- Voice picker populated from speechSynthesis.getVoices(), Italian voices first
- Auto-selects Paola voice on macOS/iOS if available
- Rate and pitch sliders (0.5x-2x, 0-2)
- testTTS() and speakCookingStep() branch on selected engine
- Existing users with tts_url keep 'server' as default engine
2026-04-10 10:19:02 +00:00
dadaloop82 499552e4df Merge develop: fix wizard password check 2026-04-10 06:57:46 +00:00
dadaloop82 4b5979333e fix: use bring_password_set and gemini_key_set flags from server API
The server never exposes bring_password in plaintext (only bring_password_set).
Fix wizard to check the boolean flag instead of the empty string.
2026-04-10 06:57:46 +00:00
dadaloop82 c9b3eb01cc Merge develop: fix wizard server settings check 2026-04-10 06:55:40 +00:00
dadaloop82 82f147d8d5 fix: check server-side credentials before showing setup wizard steps
Bring! and Gemini keys stored in .env are now fetched from the server
before deciding which wizard steps to show. This prevents the wizard
from prompting for credentials that are already configured server-side.
2026-04-10 06:55:40 +00:00
dadaloop82 38866e3daf Merge develop: smart setup wizard 2026-04-10 06:53:03 +00:00
dadaloop82 ef654b9dfc feat: smart setup wizard - only prompts for missing settings
The wizard now detects which specific settings are missing and shows
only those steps. Existing configurations are preserved. If a future
feature adds a new required setting, it will automatically prompt for
just that one.
2026-04-10 06:53:03 +00:00
dadaloop82 0b863b1cad Merge develop: update roadmap 2026-04-10 06:08:32 +00:00
dadaloop82 d75b889d8e docs: update roadmap with completed features 2026-04-10 06:08:32 +00:00
dadaloop82 d66bdc146c Merge develop: fix Docker build 2026-04-10 06:07:16 +00:00
dadaloop82 faaae1eede fix: add libonig-dev dependency for mbstring in Dockerfile 2026-04-10 06:07:16 +00:00
dadaloop82 52efa719d3 Merge develop: v1.1.0 release v1.1.0 2026-04-10 06:03:22 +00:00
dadaloop82 d13f744aea feat: v1.1.0 - Docker, i18n, setup wizard, rate limiting, OpenAPI
New features:
- Docker support (Dockerfile + docker-compose.yml)
- GitHub Actions CI pipeline (PHP lint, JS lint, Docker build, i18n validation)
- Internationalization system with 3 languages (it, en, de) and 347 translation keys
- First-run setup wizard (4-step configuration)
- File-based API rate limiting (120/15/5 req/min tiers)
- OpenAPI 3.1.0 specification for all 43 API endpoints
- CONTRIBUTING.md with translation and development guide
- Screenshots directory placeholder

Modified:
- README.md: Docker badges, install instructions, translations section
- api/index.php: rate limiting middleware
- assets/js/app.js: i18n system, setup wizard, t() function
- assets/css/style.css: setup wizard styles
- index.html: data-i18n attributes, setup wizard overlay, language settings
- .gitignore: rate_limits exclusion
2026-04-10 06:03:11 +00:00
dadaloop82 e0956c6043 Prepare for public distribution v1.0.0
- Remove all personal data from source code (HA IP, JWT tokens)
- Move secrets to .env configuration (gitignored)
- Create .env.example template for new installations
- Add centralized env() helper, eliminate code duplication (~120 lines removed)
- Add input validation on inventory operations (quantity bounds, location whitelist)
- Remove sensitive credential exposure in API responses
- Remove database and runtime files from Git tracking
- Disable database push-to-GitHub backup (local-only backup now)
- Update .gitignore for distribution
- Add comprehensive README with installation guide
- Add CHANGELOG.md for version tracking
- Add MIT LICENSE
- Add author/license headers to all source files
- TTS defaults now empty (configured per-installation via .env)
v1.0.0
2026-04-10 05:24:27 +00:00
dadaloop82 35cf133be4 Pre-distribution snapshot: current working state 2026-04-10 05:16:17 +00:00
dadaloop82 655ec63aaf 📦 Backup database automatico - 2026-04-10 03:00 2026-04-10 03:00:01 +00:00
dadaloop82 6531765921 Priorità verdura/frutta aperta in ricette + stime corrette
Stime opened (PHP+JS):
- Avocado -> 2d; fragole/banane/pesca/mango -> 2d
- Mela/pera/kiwi/ananas/melone/uva -> 3d
- Zucchina/melanzana/pomodoro/peperone -> 3d (era 7d)
- Broccolo/cavolfiore/sedano/finocchio -> 3d (era 7d)
- Cipolla/cipollotto/scalogno/porro -> 4d (era 7d)
- Carota -> 5d (era 7d); Aglio -> 10d
- Insalata/rucola/spinaci -> 2d (era 4d)

Recipe generator (index.php):
- SQL include i.opened_at
- getItemPriority: rileva opened_at su QUALSIASI unità (non solo conf)
- Elementi [APERTO] con scadenza <=5gg promossi in 'fortemente consigliati'
- Label '📦 PRODOTTI APERTI' aggiornata
- [APERTO] mostrato nel testo ingredienti del prompt AI
- Stesso fix nel contesto chat (opened_at + [APERTO] label)

DB migration: ricalcolate scadenze aperti con nuove stime
2026-04-09 12:56:10 +00:00
dadaloop82 d690ad826c Suggerisci confezione da usare per prima (scad. più vicina)
- Nel form USA, se il prodotto ha >=2 slot in inventario con scadenze
  diverse (es. 2 lotti dispensa, o frigo+dispensa), mostra un banner
  giallo: '⚠️ Usa prima quella in Frigo — scade il 12/04 (tra 3 giorni)!'
- Logica: filtra item con expiry_date, ordina per scadenza ASC,
  mostra hint solo se ci sono almeno 2 scadenze diverse O 2 location diverse
- Nessun hint se tutto ha la stessa scadenza (inutile)
2026-04-09 05:12:25 +00:00
dadaloop82 346f69426f Fix: 'Modifica scheda prodotto' duplicato
Ogni chiamata a showProductAction() creava un nuovo div e lo appendeva
con .after() senza rimuovere il precedente -> link moltiplicato.
Fix: il div ha id='catalog-edit-link', viene riutilizzato se esiste;
se il prodotto non è in inventario il link viene rimosso.
2026-04-09 05:08:47 +00:00
dadaloop82 f86059cdcd Auto-refresh: 5min pagina corrente + 2min lista spesa bg
- Intervallo pagina corrente: 5 minuti (era 10) -> dashboard, inventario,
  scadenze aperte, ricette, log si aggiornano automaticamente
- Intervallo lista spesa: 2 minuti in background anche se non sei sulla
  pagina Shopping -> badge/contatore aggiornato, e se sei sulla pagina
  Shopping vedi i nuovi prodotti aggiunti da Bring! da un altro device
- refreshCurrentPage() ora copre anche 'recipe' e 'log'
- visibilitychange: refresh immediato su qualsiasi pagina (già presente)
2026-04-09 05:07:16 +00:00
dadaloop82 7f0d4d817b Auto-refresh dati ogni 10 min + visibilitychange
- setInterval ogni 10 minuti ricarica la pagina corrente (dashboard,
  inventario, spesa) silenziosamente, senza reload — i contatori di
  scadenza restano sempre aggiornati anche se la scheda è aperta da ore
- visibilitychange ora aggiorna SEMPRE la pagina corrente, non solo
  la lista spesa, quando la tab torna in foreground
2026-04-09 05:03:47 +00:00
dadaloop82 978c298cc3 📦 Backup database automatico - 2026-04-09 03:00 2026-04-09 03:00:01 +00:00
dadaloop82 48543ee8c4 Fix opened expiry: estimation rewrite + 0ml display + HTTPS info
- Restructure estimateOpenedExpiryDays (PHP+JS): check 'eternal' items FIRST
  before any location check, so they never get 5/30d regardless of shelf:
  - Salt/sugar/honey/vinegar/bicarbonato -> 9999d (never expires)
  - Spirits -> 730d, aroma/extracts/tea -> 730d, olio/coffee -> 365d
  - Pasta/rice/dry legumes (non-frigo) -> 365d; Polenta/flour -> 180d
  - Maionese/ketchup/senape -> 90d, soy sauce -> 90d anywhere
  - Dispensa fallback: 60d (was 30d); pantry salsa di pomodoro -> 5d
  - Fruit/veg in fridge: specific rules (banana 10d, citrus 14d, etc.)
  - burro 30d, panna 4d, mortadella/wurstel 5d (improved from old values)
- Fix dashboard (getStats): remove min() with stored expiry_date (was from old
  wrong estimation); use opened_at + new estimate directly
- Filter opened list: skip items with days_to_expiry > 365 (non-perishables)
- Fix useFromInventory (both paths): min(opened_estimate, sealed_expiry)
  so original sealed expiry is respected if it expires sooner
- DB migration: re-compute expiry_date for all 22 opened inventory rows
  (maionese: +90d, salt/sugar/aceto: +9999d, muesli/biscotti: +60d, etc.)
- Clear opened_at for 'inchusa' birra (user confirmed: not actually opened)
- Fix '4 conf + 0ml' display: only show remainder if remainderAmt >= 1
- Add ' Stabile' expiry badge for days > 365 (JS)
- Add dispensa-ca.crt to /data/ for browser import (HTTPS trust)
2026-04-08 14:29:44 +00:00
dadaloop82 19489a0265 Smart opened-product expiry: days countdown, edibility, correct sort
PHP getStats() opened section:
- Primary detection: opened_at IS NOT NULL (reliable, set by useFromInventory)
  Fallback: fractional-qty pattern (legacy items)
- Per-item compute opened_expiry = min(opened_at + estimateOpenedExpiryDaysPHP, original_expiry)
  → vacuum_sealed items get 1.5× multiplier
  → always take sooner of 'opened shelf life' vs 'original sealed expiry'
- Add days_to_expiry, opened_expiry, is_edible, has_opened_at to each item
- Filter legacy items (no opened_at) with expiry > 14 days (too much noise)
- Sort by days_to_expiry ASC (soonest/spoiled first) instead of updated_at DESC

JS dashboard opened render:
- Expiry badge:  Scaduto / ⚠️ Scade oggi /  Xgg (urgent≤2, soon≤5, ok>5)
- 🔒 icon added when vacuum_sealed=1
- Spoiled items shown with strikethrough name + muted styling (.alert-item-spoiled)
- Cap display at 10 items; 'e altri N prodotti aperti...' note if more
- Sort comes from server (removed JS openedFraction sort)

CSS:
- .opened-expiry-{ok,soon,urgent,today,spoiled} badge classes
- .alert-item-spoiled strikethrough styling
- .alert-more-note
2026-04-08 12:30:36 +00:00