diff --git a/README.md b/README.md index dcf5432..356469b 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,11 @@ ```bash npm run web ``` + +## Contributing + +Currently we're not looking for contributors. + +## License + +This work is licensed under [CC BY-NC-ND 4.0](https://creativecommons.org/licenses/by-nc-nd/4.0/) diff --git a/app/Nav.tsx b/app/Nav.tsx index 3877efc..958dbb3 100644 --- a/app/Nav.tsx +++ b/app/Nav.tsx @@ -15,7 +15,7 @@ const Nav = ({ toggleProfile }: { toggleProfile: () => void; }) => { return ( - + setMenuVisible(false)} anchor={menuAnchor}> { setMenuVisible(false); setAboutVisible(true);}} title="About Us"/> @@ -25,12 +25,12 @@ const Nav = ({ toggleProfile }: { toggleProfile: () => void; }) => { setMenuAnchor({ x: event.nativeEvent.pageX, y: event.nativeEvent.pageY + 40 }); setMenuVisible(true); }} - iconColor={theme.colors.inversePrimary} /> + iconColor={theme.colors.primary} /> - + setAboutVisible(false)} style={{ backgroundColor: theme.colors.background }}> diff --git a/app/ProfileScreen.tsx b/app/ProfileScreen.tsx index 1464946..704cf59 100644 --- a/app/ProfileScreen.tsx +++ b/app/ProfileScreen.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import { Platform } from "react-native"; import { Button, TextInput, Dialog, Portal, Avatar, useTheme } from "react-native-paper"; import { Asset } from 'expo-asset'; @@ -12,11 +12,24 @@ interface ProfileScreenProps { setName: (name: string) => void; image: string; setImage: (image: string) => void; + setChanged: (dataChanged: boolean) => void; onClose: () => void; } -const ProfileScreen: React.FC = ({ visible, name, setName, image, setImage, onClose }) => { +const ProfileScreen: React.FC = ({ visible, name, setName, image, setImage, setChanged, onClose }) => { const { colors } = useTheme(); + const isNameEmpty = !name.trim(); + + // Track the initial values when the component first mounts + const [initialName, setInitialName] = useState(name); + const [initialImage, setInitialImage] = useState(image); + + useEffect(() => { + if (visible) { + setInitialName(name); // Store initial name when the profile opens + setInitialImage(image); // Store initial image when the profile opens + } + }, [visible]); // Reset when the dialog is opened useEffect(() => { const loadDefaultImage = async () => { @@ -45,23 +58,43 @@ const ProfileScreen: React.FC = ({ visible, name, setName, i }; const loadImage = async () => { - if (!image) { + if (!image || image === "") { + console.log("Loading ", image); await loadDefaultImage(); } }; - loadImage().then(r => null); + loadImage().then(() => null); }, [image]); const pickImage = async () => { let result = await ImagePicker.launchImageLibraryAsync({ base64: true }); if (!result.canceled && result.assets.length > 0) { - setImage(result.assets[0].base64 || image); + if (result.assets[0].base64 !== image) { // Only update if the image actually changes + setImage(result.assets[0].base64 || image); + console.log("Picking Image"); + } } }; + const handleSave = () => { + // Check if the name or image has changed + const hasChanged = name !== initialName || image !== initialImage; + if (hasChanged) { + setChanged(true); + } + onClose(); // Close the profile screen + }; + return ( - + { + if (!isNameEmpty) { // Prevent closing if name is empty + onClose(); + } + }} + style={{ backgroundColor: colors.background }}> Edit Your Profile = ({ visible, name, setName, i label="Your Pet's Name" mode="outlined" value={name} - onChangeText={setName} + onChangeText={(newName) => { + if (newName !== name) { // Only trigger change if it's different + setName(newName); + console.log("Name change"); + } + }} style={{ marginBottom: 15, backgroundColor: colors.surface }} placeholderTextColor={colors.onSurface} theme={{ colors: { text: colors.onSurface } }} @@ -89,38 +127,20 @@ const ProfileScreen: React.FC = ({ visible, name, setName, i + disabled={isNameEmpty} // Disable if name is empty + style={{ + backgroundColor: isNameEmpty ? colors.tertiary : colors.secondary, // Dim the button + opacity: isNameEmpty ? 0.5 : 1, // Visually dim the button + }} + labelStyle={{ color: colors.onPrimary }} + > + Save + - /* - - - Edit Your Profile - - - - - - - - - - - */ ); }; diff --git a/app/StatusPage.tsx b/app/StatusPage.tsx index 36205bc..9ed2011 100644 --- a/app/StatusPage.tsx +++ b/app/StatusPage.tsx @@ -188,7 +188,7 @@ const StatusPage: React.FC = ({ id, name, image, currentStatus, set - On the Way + On the Way {messages.filter(msg => msg.Status === "On the Way") .sort((a, b) => new Date(a.Timestamp).getTime() - new Date(b.Timestamp).getTime()) .map(item => ( @@ -207,7 +207,7 @@ const StatusPage: React.FC = ({ id, name, image, currentStatus, set - Arrived + Arrived {messages.filter(msg => msg.Status === "Arrived") .sort((a, b) => new Date(a.Timestamp).getTime() - new Date(b.Timestamp).getTime()) .map(item => ( @@ -234,9 +234,9 @@ const StatusPage: React.FC = ({ id, name, image, currentStatus, set onPress={() => handleStatusPress("On the Way")} style={[ styles.actionButton, - { backgroundColor: currentStatus === "On the Way" ? pulseColorOnTheWay : theme.colors.primary } + { backgroundColor: currentStatus === "On the Way" ? pulseColorOnTheWay : theme.colors.inversePrimary } ]} - labelStyle={{ color: theme.colors.onPrimary }}> + labelStyle={{ color: currentStatus === "On the Way" ? theme.colors.inversePrimary : theme.colors.primary }}> {getButtonLabel("On the Way")} @@ -246,9 +246,9 @@ const StatusPage: React.FC = ({ id, name, image, currentStatus, set onPress={() => handleStatusPress("Arrived")} style={[ styles.actionButton, - { backgroundColor: currentStatus === "Arrived" ? pulseColorArrived : theme.colors.primary } + { backgroundColor: currentStatus === "Arrived" ? pulseColorArrived : theme.colors.inversePrimary } ]} - labelStyle={{ color: theme.colors.onPrimary }}> + labelStyle={{ color: currentStatus === "Arrived" ? theme.colors.inversePrimary : theme.colors.primary }}> {getButtonLabel("Arrived")} diff --git a/app/index.tsx b/app/index.tsx index 020762c..971eac8 100644 --- a/app/index.tsx +++ b/app/index.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import {View, StyleSheet } from "react-native"; +import {View, StyleSheet, Text } from "react-native"; import { useTheme } from "react-native-paper"; import { v4 as uuidv4 } from "uuid"; import AsyncStorage from "@react-native-async-storage/async-storage"; @@ -10,10 +10,12 @@ import Nav from "@/app/Nav"; const Index = () => { const { colors } = useTheme(); const [isProfileActive, setProfileActive] = useState(false); - const [userId, setUserId] = useState(uuidv4()); + const [userId, setUserId] = useState(""); const [userName, setUserName] = useState(""); const [userImage, setUserImage] = useState(""); const [userStatus, setUserStatus] = useState(""); + const [userDataChanged, setUserDataChanged] = useState(false); + const [isLoading, setIsLoading] = useState(true); // New loading state useEffect(() => { const loadUserData = async () => { @@ -21,40 +23,56 @@ const Index = () => { const storedUserId = await AsyncStorage.getItem("userId"); const storedUserName = await AsyncStorage.getItem("userName"); const storedUserImage = await AsyncStorage.getItem("userImage"); - if(storedUserId) { + + if (storedUserId) { setUserId(storedUserId || uuidv4()); setUserName(storedUserName || ""); setUserImage(storedUserImage || ""); setProfileActive(false); - }else{ + } else { setUserId(uuidv4()); setUserName(""); setUserImage(""); setProfileActive(true); } - + console.log("Loading data ", userId); } catch (error) { console.error("Error loading user data:", error); + } finally { + setIsLoading(false); // Mark loading as complete } }; loadUserData(); }, []); useEffect(() => { + if (!userDataChanged) return; + const saveUserData = async () => { try { + console.log("Saving data ", userId); await AsyncStorage.setItem("userId", userId); await AsyncStorage.setItem("userName", userName); await AsyncStorage.setItem("userImage", userImage); + setUserDataChanged(false); } catch (error) { console.error("Error saving user data:", error); } }; saveUserData(); - }, [userId, userName, userImage]); + }, [userDataChanged]); + + if (isLoading) { + console.log("Still loading"); + return ( + + Loading... + + ); + } return ( - +