Merge develop: feat #77 French + Spanish translations (v1.7.17)
This commit is contained in:
@@ -11,6 +11,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
- **Recipe scraps tips** — During cooking steps, detect "waste" generated (peels, cores, bones, eggshells, coffee grounds, citrus zest, etc.) and surface AI-powered tips on how to reuse them (compost, natural cleaner, broth, candied peel, etc.). Could be shown as an optional collapsible hint card below the step that generates the scrap.
|
- **Recipe scraps tips** — During cooking steps, detect "waste" generated (peels, cores, bones, eggshells, coffee grounds, citrus zest, etc.) and surface AI-powered tips on how to reuse them (compost, natural cleaner, broth, candied peel, etc.). Could be shown as an optional collapsible hint card below the step that generates the scrap.
|
||||||
|
|
||||||
|
## [1.7.17] - 2026-05-19
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- **French translation (🇫🇷 Français)** — Complete `translations/fr.json` with all 1049 translation keys. Resolves [#77](https://github.com/dadaloop82/EverShelf/issues/77).
|
||||||
|
- **Spanish translation (🇪🇸 Español)** — Complete `translations/es.json` with all 1049 translation keys. Resolves [#77](https://github.com/dadaloop82/EverShelf/issues/77).
|
||||||
|
- Language selector in Settings now shows all 5 languages: 🇮🇹 Italiano, 🇬🇧 English, 🇩🇪 Deutsch, 🇫🇷 Français, 🇪🇸 Español.
|
||||||
|
- Default fallback language changed from Italian to English (for users with unsupported browser locale).
|
||||||
|
- Setup wizard "Done" screen and navigation buttons localised for French and Spanish.
|
||||||
|
|
||||||
## [1.7.16] - 2026-05-17
|
## [1.7.16] - 2026-05-17
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -24,8 +24,8 @@
|
|||||||
[](https://www.php.net/)
|
[](https://www.php.net/)
|
||||||
[](https://www.sqlite.org/)
|
[](https://www.sqlite.org/)
|
||||||
[](Dockerfile)
|
[](Dockerfile)
|
||||||
[](translations/)
|
[](translations/)
|
||||||
[](CHANGELOG.md)
|
[](CHANGELOG.md)
|
||||||
[](https://github.com/dadaloop82/EverShelf/stargazers)
|
[](https://github.com/dadaloop82/EverShelf/stargazers)
|
||||||
[](https://github.com/dadaloop82/EverShelf/commits/main)
|
[](https://github.com/dadaloop82/EverShelf/commits/main)
|
||||||
[](https://github.com/dadaloop82/EverShelf/graphs/contributors)
|
[](https://github.com/dadaloop82/EverShelf/graphs/contributors)
|
||||||
@@ -365,6 +365,8 @@ The app supports multiple languages via JSON translation files in the `translati
|
|||||||
| 🇮🇹 Italian (it) | ✅ Complete (base) |
|
| 🇮🇹 Italian (it) | ✅ Complete (base) |
|
||||||
| 🇬🇧 English (en) | ✅ Complete |
|
| 🇬🇧 English (en) | ✅ Complete |
|
||||||
| 🇩🇪 German (de) | ✅ Complete |
|
| 🇩🇪 German (de) | ✅ Complete |
|
||||||
|
| 🇫🇷 French (fr) | ✅ Complete |
|
||||||
|
| 🇪🇸 Spanish (es) | ✅ Complete |
|
||||||
|
|
||||||
**Want to add your language?** See the [Translation Guide](CONTRIBUTING.md#-adding-translations) — just copy `translations/it.json`, translate the values, and submit a PR!
|
**Want to add your language?** See the [Translation Guide](CONTRIBUTING.md#-adding-translations) — just copy `translations/it.json`, translate the values, and submit a PR!
|
||||||
|
|
||||||
|
|||||||
+8
-6
@@ -1043,9 +1043,9 @@ async function discoverScaleGateway() {
|
|||||||
// ===== i18n TRANSLATION SYSTEM =====
|
// ===== i18n TRANSLATION SYSTEM =====
|
||||||
let _i18nStrings = null; // current language translations (flat)
|
let _i18nStrings = null; // current language translations (flat)
|
||||||
let _i18nFallback = null; // Italian fallback (flat)
|
let _i18nFallback = null; // Italian fallback (flat)
|
||||||
let _currentLang = localStorage.getItem('evershelf_lang') || navigator.language?.slice(0, 2) || 'it';
|
let _currentLang = localStorage.getItem('evershelf_lang') || navigator.language?.slice(0, 2) || 'en';
|
||||||
const _SUPPORTED_LANGS = { it: 'Italiano', en: 'English', de: 'Deutsch' };
|
const _SUPPORTED_LANGS = { it: 'Italiano', en: 'English', de: 'Deutsch', fr: 'Français', es: 'Español' };
|
||||||
if (!_SUPPORTED_LANGS[_currentLang]) _currentLang = 'it';
|
if (!_SUPPORTED_LANGS[_currentLang]) _currentLang = 'en';
|
||||||
|
|
||||||
// Flatten nested JSON: { a: { b: "x" } } → { "a.b": "x" }
|
// Flatten nested JSON: { a: { b: "x" } } → { "a.b": "x" }
|
||||||
function _flattenI18n(obj, prefix = '') {
|
function _flattenI18n(obj, prefix = '') {
|
||||||
@@ -14566,9 +14566,11 @@ function _setupSteps() {
|
|||||||
`
|
`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '✅ ' + (_currentLang === 'it' ? 'Tutto pronto!' : _currentLang === 'de' ? 'Alles bereit!' : 'All set!'),
|
title: '✅ ' + (_currentLang === 'it' ? 'Tutto pronto!' : _currentLang === 'de' ? 'Alles bereit!' : _currentLang === 'fr' ? 'Tout est prêt !' : _currentLang === 'es' ? '¡Todo listo!' : 'All set!'),
|
||||||
desc: _currentLang === 'it' ? 'La configurazione è completata. Puoi sempre modificare queste impostazioni dalla pagina Configurazione.'
|
desc: _currentLang === 'it' ? 'La configurazione è completata. Puoi sempre modificare queste impostazioni dalla pagina Configurazione.'
|
||||||
: _currentLang === 'de' ? 'Die Konfiguration ist abgeschlossen. Du kannst diese Einstellungen jederzeit ändern.'
|
: _currentLang === 'de' ? 'Die Konfiguration ist abgeschlossen. Du kannst diese Einstellungen jederzeit ändern.'
|
||||||
|
: _currentLang === 'fr' ? 'La configuration est terminée. Vous pouvez toujours modifier ces paramètres depuis la page Paramètres.'
|
||||||
|
: _currentLang === 'es' ? 'La configuración está completa. Puedes cambiar estos ajustes desde la página Ajustes.'
|
||||||
: 'Setup is complete. You can always change these settings from the Settings page.',
|
: 'Setup is complete. You can always change these settings from the Settings page.',
|
||||||
render: () => {
|
render: () => {
|
||||||
let summary = '<div style="text-align:center;font-size:2.5rem;margin:12px 0">🎉</div>';
|
let summary = '<div style="text-align:center;font-size:2.5rem;margin:12px 0">🎉</div>';
|
||||||
@@ -14618,9 +14620,9 @@ function _renderSetupStep() {
|
|||||||
prevBtn.textContent = t('btn.back');
|
prevBtn.textContent = t('btn.back');
|
||||||
|
|
||||||
if (_setupStep === totalPending - 1) {
|
if (_setupStep === totalPending - 1) {
|
||||||
nextBtn.textContent = _currentLang === 'it' ? '🚀 Inizia!' : _currentLang === 'de' ? '🚀 Los geht\'s!' : '🚀 Start!';
|
nextBtn.textContent = _currentLang === 'it' ? '🚀 Inizia!' : _currentLang === 'de' ? '🚀 Los geht\'s!' : _currentLang === 'fr' ? '🚀 Allons-y !' : _currentLang === 'es' ? '🚀 ¡Empezar!' : '🚀 Start!';
|
||||||
} else {
|
} else {
|
||||||
nextBtn.textContent = _currentLang === 'it' ? 'Avanti →' : _currentLang === 'de' ? 'Weiter →' : 'Next →';
|
nextBtn.textContent = _currentLang === 'it' ? 'Avanti →' : _currentLang === 'de' ? 'Weiter →' : _currentLang === 'fr' ? 'Suivant →' : _currentLang === 'es' ? 'Siguiente →' : 'Next →';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -11,7 +11,7 @@
|
|||||||
<title>EverShelf</title>
|
<title>EverShelf</title>
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
<link rel="icon" type="image/png" href="assets/img/logo/logo_icon.png">
|
<link rel="icon" type="image/png" href="assets/img/logo/logo_icon.png">
|
||||||
<link rel="stylesheet" href="assets/css/style.css?v=20260516b">
|
<link rel="stylesheet" href="assets/css/style.css?v=20260519a">
|
||||||
<!-- QuaggaJS for barcode scanning -->
|
<!-- QuaggaJS for barcode scanning -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@ericblade/quagga2@1.8.4/dist/quagga.min.js"></script>
|
<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 -->
|
<!-- @xenova/transformers: ES-module bootstrap that exposes a lazy category-classifier as window._categoryPipelinePromise -->
|
||||||
@@ -1560,6 +1560,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="assets/js/app.js?v=20260516b"></script>
|
<script src="assets/js/app.js?v=20260519a"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"name": "EverShelf",
|
"name": "EverShelf",
|
||||||
"short_name": "EverShelf",
|
"short_name": "EverShelf",
|
||||||
"description": "Gestione completa della dispensa di casa con scansione barcode",
|
"description": "Gestione completa della dispensa di casa con scansione barcode",
|
||||||
"version": "1.7.15",
|
"version": "1.7.17",
|
||||||
"start_url": "/evershelf/",
|
"start_url": "/evershelf/",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"background_color": "#f0f4e8",
|
"background_color": "#f0f4e8",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user