diff --git a/app/(tabs)/add.jsx b/app/(tabs)/add.jsx index 62e7947..e393d1b 100644 --- a/app/(tabs)/add.jsx +++ b/app/(tabs)/add.jsx @@ -90,6 +90,7 @@ export default function FormScreen() { const result = await launchCameraAsync({ allowsEditing: false, base64: true, + quality: 0.2, }); if (!result.canceled && result.assets && result.assets.length > 0) { diff --git a/app/(tabs)/index.jsx b/app/(tabs)/index.jsx index 3f32506..cb9725f 100644 --- a/app/(tabs)/index.jsx +++ b/app/(tabs)/index.jsx @@ -1,52 +1,61 @@ import { - View, - StyleSheet, - FlatList, + View, + StyleSheet, + FlatList, } from "react-native"; -import { useTheme, Card, Text, Button } from "react-native-paper"; -import { Link } from "expo-router"; +import {useTheme, Card, Text, Button, ActivityIndicator} from "react-native-paper"; +import {Link} from "expo-router"; import useLocationStore from "@/locationStore"; export default function Index() { - const theme = useTheme(); - const { locations } = useLocationStore(); + const theme = useTheme(); + const {locations} = useLocationStore(); + const loading = useLocationStore((state) => state.loading); - return ( - - item.id.toString()} - renderItem={({ item }) => ( - - - - {item.name} - - {item.description && item.description.split(".")[0]}... - - - - - - - - - )} - /> - - ); + if (loading) { + return ( + + + + ); + } + + return ( + + item.id.toString()} + renderItem={({item}) => ( + + + + {item.name} + + {item.description && item.description.split(".")[0]}... + + + + + + + + + )} + /> + + ); } const styles = StyleSheet.create({ - container: { - flex: 1, - backgroundColor: "#25292e", - justifyContent: "center", - alignItems: "center", - }, + container: { + flex: 1, + backgroundColor: "#25292e", + justifyContent: "center", + alignItems: "center", + }, }); diff --git a/app/_layout.jsx b/app/_layout.jsx index d83f581..cc4e1a6 100644 --- a/app/_layout.jsx +++ b/app/_layout.jsx @@ -16,7 +16,6 @@ export default function RootLayout() { fetchLocations(); }, []); - console.log(); const deleteLocation = useLocationStore((state) => state.deleteLocation); const handleDelete = async (id) => { diff --git a/app/location/[id].jsx b/app/location/[id].jsx index 74643e9..04568b6 100644 --- a/app/location/[id].jsx +++ b/app/location/[id].jsx @@ -1,6 +1,6 @@ import { View, ScrollView, StyleSheet } from "react-native"; import { useEffect } from "react"; -import { useTheme, Text, Card } from "react-native-paper"; +import {useTheme, Text, Card, ActivityIndicator} from "react-native-paper"; import { useLocalSearchParams } from "expo-router"; import useLocationStore from "@/locationStore"; @@ -19,14 +19,23 @@ export default function Location() { } }, [location, loading, fetchLocations]); - if (loading || !location) { + if (loading) { return ( - - Brak lokalizacji - {id} - + + + ); } + if (!location) { + return ( + + Brak lokalizacji - {id} + + ); + } + + return ( diff --git a/app/location/edit/[id].jsx b/app/location/edit/[id].jsx index 824b3b1..0cec096 100644 --- a/app/location/edit/[id].jsx +++ b/app/location/edit/[id].jsx @@ -6,10 +6,12 @@ import { KeyboardAvoidingView, View, ActivityIndicator, + Image, } from "react-native"; -import {TextInput, Button, Snackbar, useTheme} from "react-native-paper"; +import {TextInput, Button, Snackbar, useTheme, Text} from "react-native-paper"; import {useLocalSearchParams, useRouter} from "expo-router"; import useLocationStore from "@/locationStore"; +import {normalizeImageSource} from "@/api/locations"; export default function EditLocation() { const theme = useTheme(); @@ -89,6 +91,16 @@ export default function EditLocation() { } }; + const isBase64Image = (str) => { + let image = normalizeImageSource(str); + return image && ( + image.uri.startsWith('data:image/jpeg;base64,') || + image.uri.startsWith('data:image/png;base64,') || + image.uri.startsWith('data:image/gif;base64,') || + image.uri.startsWith('data:image/webp;base64,') + ); + }; + if (loading) { return ( + Brak lokalizacji - {id} + + ); + } + return ( {message} + + {isBase64Image(formData.image) ? ( + + + Aktualne zdjęcie: + + + + ) : ( + setFormData({...formData, image: e})} + /> + )} + setFormData({...formData, description: e})} /> - setFormData({...formData, image: e})} - /> ({ - locations: [], - loading: false, - error: null, + locations: [], + loading: false, + error: null, - fetchLocations: async () => { - set({ loading: true, error: null }); - try { - const data = await api.listLocations(); - set({ locations: data, loading: false }); - } catch (error) { - set({ error, loading: false }); - } - }, + fetchLocations: async () => { + set({loading: true, error: null}); + try { + const data = await api.listLocations(); + set({locations: data, loading: false}); + } catch (error) { + set({error, loading: false}); + } + }, -addLocation: async (location) => { - set({ loading: true, error: null }); - try { - const newLoc = await api.addLocation(location); - const normalizedLoc = { - ...newLoc, - imageSource: api.normalizeImageSource(newLoc.image) - }; - set((state) => ({ - locations: [...state.locations, normalizedLoc], - loading: false, - })); - return normalizedLoc; - } catch (error) { - set({ error, loading: false }); - return null; - } -}, + addLocation: async (location) => { + set({loading: true, error: null}); + try { + const newLoc = await api.addLocation(location); + const normalizedLoc = { + ...newLoc, + imageSource: api.normalizeImageSource(newLoc.image) + }; + set((state) => ({ + locations: [...state.locations, normalizedLoc], + loading: false, + })); + return normalizedLoc; + } catch (error) { + set({error, loading: false}); + return null; + } + }, - updateLocation: async (id, location) => { - set({ loading: true, error: null }); - try { - const updated = await api.updateLocation(id, location); - set((state) => ({ - locations: state.locations.map((loc) => - loc.id === id ? updated : loc - ), - - loading: false, - })); + updateLocation: async (id, location) => { + set({loading: true, error: null}); + try { + const updated = await api.updateLocation(id, location); + set((state) => ({ + locations: state.locations.map((loc) => + loc.id === id ? updated : loc + ), - return updated; - } catch (error) { - set({ error, loading: false }); - return null; - } - }, + loading: false, + })); - deleteLocation: async (id) => { - set({ loading: true, error: null }); - try { - const deleted = await api.deleteLocation(id); - set((state) => ({ - locations: state.locations.filter((loc) => loc.id !== id), - loading: false, - })); - if(deleted) { - return true; - } - } catch (error) { - set({ error, loading: false }); - return false; - } - }, + return updated; + } catch (error) { + set({error, loading: false}); + return null; + } + }, - getLocation: (id) => { - return get().locations.find((loc) => String(loc.id) === String(id)); - }, + deleteLocation: async (id) => { + set({loading: true, error: null}); + try { + const deleted = await api.deleteLocation(id); + set((state) => ({ + locations: state.locations.filter((loc) => loc.id !== id), + loading: false, + })); + return deleted; + } catch (error) { + set({error, loading: false}); + return false; + } + }, + + getLocation: (id) => { + const location = get().locations.find((loc) => String(loc.id) === String(id)); + if (location && !location.imageSource) { + return { + ...location, + imageSource: api.normalizeImageSource(location.image) + }; + } + return location; + }, })); export default useLocationStore; \ No newline at end of file