File boilerplate generato automaticamente dal dev container, non
appartiene al progetto e fallirebbe (referenzia MyApp inesistente).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Aggiunge sezione "Controllo aggiornamenti" nelle funzionalità del README.
Aggiorna struttura test in README e CLAUDE.md con le nuove cartelle
shared/services e shared/widgets. Contatore test 110 → 130.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
parseTagName: v-prefix, body senza prefisso, JSON malformato, tag_name
assente, body vuoto. Widget test del dialog: titolo, versione nel testo,
pulsanti Più tardi e Scarica, chiusura dialog, chiamata MethodChannel
verificata con mock. 130/130 test passati.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sposta la logica del dialog in lib/shared/widgets/update_dialog.dart
per renderla importabile nei test senza duplicare il codice.
Estrae parseTagName come metodo @visibleForTesting in UpdateService
isolando il parsing JSON dalla chiamata HTTP. app.dart semplificato
di conseguenza.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copre parseVersion (semver standard, parti mancanti, valori non numerici)
e isNewer (patch/minor/major bump, versione uguale, versione più vecchia,
componenti multi-cifra come 2.0.10 > 2.0.9). 10/10 test passati su ARM64.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All'avvio l'app chiama l'API GitHub releases per confrontare la versione
installata con l'ultima disponibile (comparazione semantica major.minor.patch).
Se esiste una versione più recente, mostra un AlertDialog con i pulsanti
"Più tardi" e "Scarica" — quest'ultimo apre releases/latest nel browser.
Il controllo è silenzioso in caso di assenza di rete o errori, e disabilitato
su Flutter web (dart:io non disponibile).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Aggiunge INTERNET permission e la query ACTION_VIEW/https richiesta da
Android 11+ per la package visibility. Espone il MethodChannel
'com.davide.biteplan/launcher' che lancia un Intent.ACTION_VIEW con
l'URL ricevuto, senza dipendere da plugin Flutter esterni.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Valori aggiornati da misurazioni dirette (Muzzone 2024 + INRAN via matematicaincucina),
più accurati rispetto al proxy CREA kcal crudo/cotto usato in precedenza.
bieta 0.83→0.86 · cavolfiore 0.97→0.93 · finocchi 0.88→0.86 · agretti 0.88→0.86
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Changelog: documenta la migrazione completa da Vue 3 + Capacitor a Flutter
- conversioni.md: corregge il path del file dati da src/data/ ad assets/data/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rimuove il blocco flutter create da build.sh: android/ è ora versionata
con la configurazione corretta (com.davide.biteplan), il fallback era
diventato codice morto con un --org errato
- Aggiorna docker/README.md: distingue collaboratore (riceve keystore
dall'autore) da fork/uso personale (genera keystore proprio), spiega
l'impatto sulla compatibilità degli aggiornamenti sui dispositivi
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rende il repo clonabile e buildabile da chiunque senza passi manuali:
- android/ rimosso da .gitignore: contiene applicationId, label, icone
e MainActivity con il package corretto (com.davide.biteplan)
- pubspec.lock aggiunto: necessario per --enforce-lockfile nella build
- File generati/macchina-specifici già esclusi da android/.gitignore
(.gradle/, local.properties, GeneratedPluginRegistrant.java)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Valida BITEPLAN_KEYSTORE_PASS prima della build e stampa istruzioni chiare
- Passa --ks-pass a apksigner tramite env var (stdin era chiuso nel container)
- Aggiunge rm -f su biteplan-aligned.apk prima di zipalign per evitare errori
su run consecutive
- Documenta export BITEPLAN_KEYSTORE_PASS nel docker/README.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Pinna Flutter a 3.41.9 (ARG FLUTTER_VERSION) in entrambi i Dockerfile
- Aggiunge /opt/android-sdk/build-tools/34.0.0 al PATH (zipalign era missing)
- Sostituisce mount ${HOME}/.gradle con named volume gradle-cache
- Aggiunge --enforce-lockfile a flutter pub get per bloccare le dipendenze
- Aggiunge .flutter-version con la versione Flutter attesa
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Migrazione completa da Vue 3 + Vite a Flutter:
- rimossa sorgente Vue 3/Vite/Playwright
- app riscritta in Flutter con Material 3, Provider, SharedPreferences
- aggiunto supporto QR code per condivisione piano pasti
- aggregazione duplicati nella lista della spesa
- guida utente con 3 tab (Pasti, Converti, Spesa)
- containerizzazione Docker per dev e build APK
- suite di 110 test (unit + widget)
- ottimizzazioni APK: spazio e allocazioni a runtime
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Comprimi icon-only.png da 5.2 MB a 72 KB (512×512, quantizzazione 256 colori)
- Rimuovi setState() ridondante in ConverterPage.onChanged: search() chiama già notifyListeners()
- Cattura pendingItems/checkedItems in variabili locali nel build di ShoppingListPage per evitare filtraggio ripetuto a ogni paint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CLAUDE.md: rimossi riferimenti a noVNC/Vue3/sop.md, aggiornata
architettura reale (features/*/presentation/), rimossi file fantasma
(checkbox_item.dart, conversion_service.dart), aggiunta feature guide,
corretta struttura test, aggiornati comandi Docker.
README.md: riscritto per Flutter (rimosso stack Vue3/Node.js), aggiunta
sezione test con comandi e struttura cartelle, link docs/.
docker/README.md: aggiunta sezione test completa con comandi per tutti
i test, singolo file e singola feature; aggiornato flusso completo.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
add() usava millisecondsSinceEpoch come ID: chiamate ravvicinate nello
stesso millisecondo producevano ID identici, causando toggle e remove
incorretti su più elementi. Introdotto _idSeq come contatore progressivo,
allineato all'approccio già usato in addAll().
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
buildQrPayload e parseMealPlanFromQr erano metodi privati non testabili.
Estratti in un modulo dedicato e importati da qr_share_sheet e qr_scan_page.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
build.sh: il permesso CAMERA viene iniettato dentro il container
Docker subito dopo flutter create (sed gira come root, evita il
problema di permessi su android/ owned by root).
entrypoint.sh: stesso approccio, sed eseguito già dentro il container.
Il sed inserisce <uses-permission android:name="android.permission.CAMERA" />
prima di <application>, posizione corretta nel manifest Android.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Porta la funzionalità QR code dalla versione Vue a Flutter.
Condividi: pulsante in fondo alla tab Pasti (attivo solo con piano
non vuoto) → bottom sheet con QR code generato da qr_flutter.
Payload: { "v": 1, "meals": { ... } }, limite 2953 byte.
Ricevi: pulsante sempre visibile → QrScanPage full-screen con
fotocamera via mobile_scanner, cornice di mira, validazione
struttura JSON e importazione via MealPlannerProvider.importPlan().
Nuovi package: qr_flutter ^4.1.0, mobile_scanner ^5.0.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Quando si genera la lista dal piano pasti, gli alimenti ripetuti in
più giorni o slot vengono aggregati in un unico elemento con contatore.
Es. zucchine lunedì + mercoledì → "zucchine (x2)".
- ShoppingItem: aggiunto campo quantity (default 1, persistito in JSON)
- ShoppingListProvider.addAll: conta le occorrenze per nome
(case-insensitive) e crea un ShoppingItem con quantity = conteggio
- ShoppingItemTile: mostra "(xN)" colorato in primary quando quantity > 1,
diventa muted insieme al nome quando l'elemento è completato
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Guida utente:
- Pulsante info nell'AppBar principale
- InfoBottomSheet: icona app, versione, autore, licenza, link alla guida
- GuidePage: tre tab (Pasti / Converti / Spesa) con card e step numerati,
portata dalla DocsPanel Vue originale
AppBar globale in app.dart con titolo dinamico per tab corrente.
Icona launcher:
- flutter_launcher_icons eseguito in build.sh prima di flutter build apk
(sia debug che release) per applicare assets/icon-only.png all'APK.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docker/build/: build headless APK Android
- Dockerfile: Ubuntu 22.04 + Java 17 + Flutter stable + Android SDK
- build.sh: genera android/ automaticamente se mancante, poi
flutter build apk; --release aggiunge zipalign + apksigner
docker/dev/: ambiente di sviluppo web con hot reload
- Dockerfile: Ubuntu 22.04 + Flutter stable (solo web, senza Android SDK)
- docker-compose.yml: espone porta 5173, monta il progetto come volume
- entrypoint.sh: inizializza web/ se mancante, flutter pub get,
flutter run -d web-server su 0.0.0.0:5173
docker/README.md: documentazione aggiornata per entrambi i container;
rimossi Dockerfile e build.sh Vue/Capacitor non più usati.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Riscrittura completa da Vue 3 + Capacitor a Flutter/Dart.
Architettura feature-based (lib/features/):
- meal_planner: modello MealPlan/DayPlan, provider, pagina e widget
- converter: modello ConversionEntry, provider con ricerca, pagina
- shopping_list: modello ShoppingItem, provider con deduplicazione, pagina e widget
Core:
- Material 3 con seed color #2d6a4f
- NavigationBar + IndexedStack (preserva stato dei tab)
- Portrait lock via SystemChrome
- Persistenza con shared_preferences
- 50+ alimenti × metodi cottura in assets/data/conversions.json
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Il progetto viene riscritto in Flutter. Eliminati tutti i file
Vue 3 (src/, tests/, public/), le configurazioni Vite/Vitest e
i test Playwright che non saranno più mantenuti.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Riscritto sop.md con stack Flutter + Docker (container dev noVNC +
container build headless). Aggiornato CLAUDE.md con roadmap, architettura
target e mapping Vue→Flutter come riferimento per la riscrittura.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Aggiunta documentazione per Claude Code (comandi, architettura, testing,
pipeline Android). Rimossa la skill UX da .claude/skills/ non più necessaria.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Dockerfile: aggiunge android:screenOrientation="portrait" all'activity
in AndroidManifest.xml per bloccare il portrait nativamente sull'APK
- App.vue: fixOrientation() rileva il landscape tramite dimensioni viewport
e applica un counter-rotate CSS in modo che l'app rimanga visivamente
in portrait anche da browser mobile (dev server)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Sposta .btn-clear da ShoppingList.vue (scoped) a style.css (globale)
- Aggiunge hasMeals, clearAll e btn-clear in MealPlanner.vue
- Aggiunge 4 test di integrazione per il nuovo pulsante
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Aggiunge due pulsanti in fondo alla schermata Piano Pasti:
- "Condividi": genera un QR code con i dati della settimana
- "Ricevi": apre la fotocamera per scansionare il QR e importare il piano
Dipendenze aggiunte: qrcode, jsqr
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Con --head la DIST_DIR puntava alla directory temporanea che veniva cancellata
dal trap EXIT prima che l'utente potesse recuperare l'APK. L'APK viene ora
copiato esplicitamente in PROJECT_ROOT/dist/ dopo il docker run.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>