Handle error states and accessibility improvements
This commit is contained in:
@@ -33,32 +33,31 @@ export default function App() {
|
||||
const [manualPrices, setManualPrices] = useState({});
|
||||
const [recentProducts, setRecentProducts] = useState([]);
|
||||
const [isHydrated, setIsHydrated] = useState(false);
|
||||
const [storageError, setStorageError] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
|
||||
async function hydrate() {
|
||||
const [
|
||||
storedPreferences,
|
||||
storedShoppingList,
|
||||
storedProductCache,
|
||||
storedManualPrices,
|
||||
storedRecentProducts
|
||||
] = await Promise.all([
|
||||
storageService.loadPreferences(defaultPreferences),
|
||||
storageService.loadShoppingList(initialShoppingList),
|
||||
storageService.loadProductCache(),
|
||||
storageService.loadManualPrices(),
|
||||
storageService.loadRecentProducts()
|
||||
]);
|
||||
try {
|
||||
const [storedPreferences, storedShoppingList, storedProductCache, storedManualPrices, storedRecentProducts] = await Promise.all([
|
||||
storageService.loadPreferences(defaultPreferences),
|
||||
storageService.loadShoppingList(initialShoppingList),
|
||||
storageService.loadProductCache(),
|
||||
storageService.loadManualPrices(),
|
||||
storageService.loadRecentProducts()
|
||||
]);
|
||||
|
||||
if (isMounted) {
|
||||
setPreferences(storedPreferences);
|
||||
setShoppingList(storedShoppingList);
|
||||
setProductCache(storedProductCache);
|
||||
setManualPrices(storedManualPrices);
|
||||
setRecentProducts(storedRecentProducts);
|
||||
setIsHydrated(true);
|
||||
if (isMounted) {
|
||||
setPreferences({ ...defaultPreferences, ...storedPreferences });
|
||||
setShoppingList({ ...initialShoppingList, ...storedShoppingList, items: storedShoppingList?.items || [] });
|
||||
setProductCache(storedProductCache || {});
|
||||
setManualPrices(storedManualPrices || {});
|
||||
setRecentProducts(Array.isArray(storedRecentProducts) ? storedRecentProducts : []);
|
||||
setIsHydrated(true);
|
||||
}
|
||||
} catch (error) {
|
||||
if (isMounted) setStorageError('Deine lokalen Daten konnten nicht geladen werden.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +67,27 @@ export default function App() {
|
||||
};
|
||||
}, []);
|
||||
|
||||
function retryHydration() {
|
||||
setStorageError('');
|
||||
setIsHydrated(false);
|
||||
// Reloading the app is not necessary for the normal path, but this keeps
|
||||
// the retry action explicit if a storage adapter fails temporarily.
|
||||
Promise.all([
|
||||
storageService.loadPreferences(defaultPreferences),
|
||||
storageService.loadShoppingList(initialShoppingList),
|
||||
storageService.loadProductCache(),
|
||||
storageService.loadManualPrices(),
|
||||
storageService.loadRecentProducts()
|
||||
]).then(([nextPreferences, nextList, nextCache, nextPrices, nextRecent]) => {
|
||||
setPreferences({ ...defaultPreferences, ...nextPreferences });
|
||||
setShoppingList({ ...initialShoppingList, ...nextList, items: nextList?.items || [] });
|
||||
setProductCache(nextCache || {});
|
||||
setManualPrices(nextPrices || {});
|
||||
setRecentProducts(Array.isArray(nextRecent) ? nextRecent : []);
|
||||
setIsHydrated(true);
|
||||
}).catch(() => setStorageError('Bitte starte Shoppy erneut, um die lokalen Daten zu laden.'));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isHydrated) storageService.savePreferences(preferences);
|
||||
}, [isHydrated, preferences]);
|
||||
@@ -132,11 +152,13 @@ export default function App() {
|
||||
}
|
||||
|
||||
return (
|
||||
<HomeScreen
|
||||
onOpenProduct={openProduct}
|
||||
onStartScan={() => setActiveTab('scan')}
|
||||
preferences={preferences}
|
||||
recentProducts={recentProducts}
|
||||
<HomeScreen
|
||||
onOpenProduct={openProduct}
|
||||
onOpenList={() => setActiveTab('list')}
|
||||
onStartScan={() => setActiveTab('scan')}
|
||||
preferences={preferences}
|
||||
recentProducts={recentProducts}
|
||||
shoppingList={shoppingList}
|
||||
/>
|
||||
);
|
||||
}, [activeTab, manualPrices, preferences, productCache, recentProducts, shoppingList]);
|
||||
@@ -356,7 +378,8 @@ export default function App() {
|
||||
if (!isHydrated) {
|
||||
return (
|
||||
<View style={styles.loading}>
|
||||
<Text style={styles.loadingText}>Shoppy wird geladen...</Text>
|
||||
<Text style={styles.loadingText}>{storageError || 'Shoppy wird geladen...'}</Text>
|
||||
{storageError ? <Text onPress={retryHydration} style={styles.retryText}>Erneut versuchen</Text> : null}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -443,5 +466,11 @@ const styles = StyleSheet.create({
|
||||
color: colors.muted,
|
||||
fontSize: 16,
|
||||
fontWeight: '700'
|
||||
},
|
||||
retryText: {
|
||||
color: colors.primary,
|
||||
fontSize: 15,
|
||||
fontWeight: '800',
|
||||
marginTop: 16
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user