From 6938afb26cf7128c5fa6bc4e72f6bc0d9f226729 Mon Sep 17 00:00:00 2001 From: fretuks Date: Fri, 16 Oct 2026 15:40:55 +0200 Subject: [PATCH] Rename app from "Shoppy" to "Shoppinguin" across codebase and documentation. Handle migration of legacy storage keys. --- App.js | 4 ++-- README.md | 10 ++++----- app.json | 10 ++++----- package-lock.json | 4 ++-- package.json | 2 +- src/screens/HomeScreen.js | 2 +- src/screens/ScanScreen.js | 2 +- src/services/shoppingListWarningsService.js | 6 ++--- src/services/storageService.js | 25 ++++++++++++++------- 9 files changed, 37 insertions(+), 28 deletions(-) diff --git a/App.js b/App.js index e8c3519..1f61c97 100644 --- a/App.js +++ b/App.js @@ -85,7 +85,7 @@ export default function App() { setManualPrices(nextPrices || {}); setRecentProducts(Array.isArray(nextRecent) ? nextRecent : []); setIsHydrated(true); - }).catch(() => setStorageError('Bitte starte Shoppy erneut, um die lokalen Daten zu laden.')); + }).catch(() => setStorageError('Bitte starte Shoppinguin erneut, um die lokalen Daten zu laden.')); } useEffect(() => { @@ -378,7 +378,7 @@ export default function App() { if (!isHydrated) { return ( - {storageError || 'Shoppy wird geladen...'} + {storageError || 'Shoppinguin wird geladen...'} {storageError ? Erneut versuchen : null} ); diff --git a/README.md b/README.md index 53da090..7195335 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ -# Shoppy +# Shoppinguin Smart Shopping Companion ## App-Idee -Shoppy ist eine mobile Einkaufshilfe für den Supermarkt. Nutzerinnen und Nutzer scannen Produkte per Smartphone-Kamera oder Barcode, erhalten direkt eine persönliche Einschätzung und treffen dadurch bessere Kaufentscheidungen. +Shoppinguin ist eine mobile Einkaufshilfe für den Supermarkt. Nutzerinnen und Nutzer scannen Produkte per Smartphone-Kamera oder Barcode, erhalten direkt eine persönliche Einschätzung und treffen dadurch bessere Kaufentscheidungen. Die Bewertung berücksichtigt Zutaten, Preis, Nachhaltigkeitsmerkmale und individuelle Ziele wie Allergien, Ernährung, Budget und Nachhaltigkeit. ## Zielgruppe -Die App richtet sich an Privatpersonen, die im Supermarkt schnell bessere Kaufentscheidungen treffen möchten. Besonders relevant ist Shoppy für Menschen mit Allergien oder Unverträglichkeiten, ernährungsbewusste Käuferinnen und Käufer, Studierende und Familien mit Budgetfokus sowie Konsumentinnen und Konsumenten mit Nachhaltigkeitsanspruch. +Die App richtet sich an Privatpersonen, die im Supermarkt schnell bessere Kaufentscheidungen treffen möchten. Besonders relevant ist Shoppinguin für Menschen mit Allergien oder Unverträglichkeiten, ernährungsbewusste Käuferinnen und Käufer, Studierende und Familien mit Budgetfokus sowie Konsumentinnen und Konsumenten mit Nachhaltigkeitsanspruch. ## Wichtigste Funktionen @@ -49,7 +49,7 @@ Der One-Pager aus Aufgabe 6.1 beschreibt das Go-to-Market-Konzept: ## Ordnerstruktur ```text -Shoppy/ +Shoppinguin/ |-- assets/ |-- src/ | |-- assets/ @@ -92,7 +92,7 @@ Der Workflow in `.gitea/workflows/android-release.yml` startet bei jedem Push in ein Gitea-Repository. Er installiert die Abhängigkeiten mit `npm ci`, erzeugt das nicht versionierte Android-Projekt per Expo und kompiliert mit Gradle eine Release-APK. Die APK ist im jeweiligen Gitea-Actions-Lauf als -Artefakt `shoppy-android-release-` herunterladbar. +Artefakt `shoppinguin-android-release-` herunterladbar. Voraussetzungen: Gitea Actions ist für das Repository aktiviert und ein Linux-Runner mit dem Label `ubuntu-latest` ist registriert. Der Runner benötigt diff --git a/app.json b/app.json index 75e30a1..e871bad 100644 --- a/app.json +++ b/app.json @@ -1,7 +1,7 @@ { "expo": { - "name": "Shoppy", - "slug": "shoppy", + "name": "Shoppinguin", + "slug": "shoppinguin", "version": "1.0.0", "orientation": "portrait", "userInterfaceStyle": "automatic", @@ -14,10 +14,10 @@ "ios": { "supportsTablet": true, "infoPlist": { - "NSCameraUsageDescription": "Shoppy nutzt die Kamera, um Produkt-Barcodes im Supermarkt zu scannen.", + "NSCameraUsageDescription": "Shoppinguin nutzt die Kamera, um Produkt-Barcodes im Supermarkt zu scannen.", "ITSAppUsesNonExemptEncryption": false }, - "bundleIdentifier": "net.fretux.shoppy" + "bundleIdentifier": "net.fretux.shoppinguin" }, "android": { "permissions": [ @@ -26,7 +26,7 @@ "adaptiveIcon": { "backgroundColor": "#f7f3ea" }, - "package": "net.fretux.shoppy" + "package": "net.fretux.shoppinguin" }, "extra": { "eas": { diff --git a/package-lock.json b/package-lock.json index fd06c11..0520624 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "shoppy", + "name": "shoppinguin", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "shoppy", + "name": "shoppinguin", "version": "1.0.0", "dependencies": { "@expo/metro-runtime": "~6.1.2", diff --git a/package.json b/package.json index b6bd65d..082d2d0 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "shoppy", + "name": "shoppinguin", "version": "1.0.0", "private": true, "main": "node_modules/expo/AppEntry.js", diff --git a/src/screens/HomeScreen.js b/src/screens/HomeScreen.js index 558357d..e88237d 100644 --- a/src/screens/HomeScreen.js +++ b/src/screens/HomeScreen.js @@ -17,7 +17,7 @@ export default function HomeScreen({ preferences, recentProducts, shoppingList, return ( diff --git a/src/screens/ScanScreen.js b/src/screens/ScanScreen.js index acfa82b..e7502af 100644 --- a/src/screens/ScanScreen.js +++ b/src/screens/ScanScreen.js @@ -77,7 +77,7 @@ export default function ScanScreen({ preferences, productCache, onScanBarcode, o Kamera-Berechtigung benötigt - Shoppy braucht die Kamera, um Barcodes direkt im Laden zu erfassen. + Shoppinguin braucht die Kamera, um Barcodes direkt im Laden zu erfassen. diff --git a/src/services/shoppingListWarningsService.js b/src/services/shoppingListWarningsService.js index b5c14a6..afb5c31 100644 --- a/src/services/shoppingListWarningsService.js +++ b/src/services/shoppingListWarningsService.js @@ -6,7 +6,7 @@ const dailyLimitRules = [ unit: 'mg', nutritionKey: 'caffeineMgPer100g', severity: 'critical', - message: 'Mehr Koffein als der Tagesrichtwert in Shoppy. Auf mehrere Tage aufteilen.' + message: 'Mehr Koffein als der Tagesrichtwert in Shoppinguin. Auf mehrere Tage aufteilen.' }, { key: 'sugar', @@ -15,7 +15,7 @@ const dailyLimitRules = [ unit: 'g', nutritionKey: 'sugarPer100g', severity: 'warning', - message: 'Mehr Zucker als der Tagesrichtwert in Shoppy. Auf mehrere Tage aufteilen.' + message: 'Mehr Zucker als der Tagesrichtwert in Shoppinguin. Auf mehrere Tage aufteilen.' }, { key: 'salt', @@ -24,7 +24,7 @@ const dailyLimitRules = [ unit: 'g', nutritionKey: 'saltPer100g', severity: 'warning', - message: 'Mehr Salz als der Tagesrichtwert in Shoppy. Auf mehrere Tage aufteilen.' + message: 'Mehr Salz als der Tagesrichtwert in Shoppinguin. Auf mehrere Tage aufteilen.' } ]; diff --git a/src/services/storageService.js b/src/services/storageService.js index 27fdf1d..158d8d9 100644 --- a/src/services/storageService.js +++ b/src/services/storageService.js @@ -1,21 +1,30 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; const keys = { - preferences: 'shoppy.preferences', - shoppingList: 'shoppy.shoppingList', - productCache: 'shoppy.productCache', - manualPrices: 'shoppy.manualPrices', - recentProducts: 'shoppy.recentProducts' + preferences: 'shoppinguin.preferences', + shoppingList: 'shoppinguin.shoppingList', + productCache: 'shoppinguin.productCache', + manualPrices: 'shoppinguin.manualPrices', + recentProducts: 'shoppinguin.recentProducts' }; +const legacyPrefix = 'shoppy.'; + async function readJson(key, fallbackValue) { try { - const rawValue = await AsyncStorage.getItem(key); + let rawValue = await AsyncStorage.getItem(key); + if (rawValue === null) { + const legacyKey = key.replace(/^shoppinguin\./, legacyPrefix); + rawValue = await AsyncStorage.getItem(legacyKey); + if (rawValue !== null) { + await AsyncStorage.setItem(key, rawValue); + } + } return rawValue ? JSON.parse(rawValue) : fallbackValue; } catch (error) { // A damaged value should not prevent the app from starting. The next save // will replace it with a valid value. - console.warn(`Shoppy konnte ${key} nicht laden.`, error); + console.warn(`Shoppinguin konnte ${key} nicht laden.`, error); return fallbackValue; } } @@ -25,7 +34,7 @@ async function writeJson(key, value) { await AsyncStorage.setItem(key, JSON.stringify(value)); } catch (error) { // Storage is best-effort; the in-memory state remains usable. - console.warn(`Shoppy konnte ${key} nicht speichern.`, error); + console.warn(`Shoppinguin konnte ${key} nicht speichern.`, error); } }