Rename app from "Shoppy" to "Shoppinguin" across codebase and documentation. Handle migration of legacy storage keys.

This commit is contained in:
2026-10-16 15:40:55 +02:00
parent 9b80580f9c
commit 6938afb26c
9 changed files with 37 additions and 28 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ export default function HomeScreen({ preferences, recentProducts, shoppingList,
return (
<ScreenContainer>
<AppHeader
title="Shoppy"
title="Shoppinguin"
subtitle="Scanne Produkte im Supermarkt und erhalte eine persönliche Kaufempfehlung."
/>
+1 -1
View File
@@ -77,7 +77,7 @@ export default function ScanScreen({ preferences, productCache, onScanBarcode, o
<View style={styles.permissionBox}>
<Text style={styles.permissionTitle}>Kamera-Berechtigung benötigt</Text>
<Text style={styles.permissionCopy}>
Shoppy braucht die Kamera, um Barcodes direkt im Laden zu erfassen.
Shoppinguin braucht die Kamera, um Barcodes direkt im Laden zu erfassen.
</Text>
<PrimaryButton label="Kamera erlauben" onPress={requestPermission} />
</View>
+3 -3
View File
@@ -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.'
}
];
+17 -8
View File
@@ -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);
}
}