Skip to content

Commit

Permalink
feat: refactor to fix circular dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
Th0rgal committed Dec 13, 2024
1 parent b32b833 commit 46c3814
Show file tree
Hide file tree
Showing 12 changed files with 227 additions and 208 deletions.
10 changes: 10 additions & 0 deletions components/addmeal/ReviewMeal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import LongTextInputDialog from "./FixBugDialog";
import { useAuth } from "../../shared/AuthContext";
import Ionicons from "@expo/vector-icons/Ionicons";
import { StoredMeal } from "../../types";
import { useMealsDatabase } from "../../shared/MealsStorageContext";

const SNAP_POINTS = ["90%"];

Expand All @@ -28,6 +29,7 @@ const ReviewMeal = ({
const colorScheme = useColorScheme();
const [dialogVisible, setDialogVisible] = useState(false);
const { jwt } = useAuth();
const { updateMeal } = useMealsDatabase();

const ingredients =
mealData?.last_analysis?.ingredients?.map((item) => ({
Expand Down Expand Up @@ -81,6 +83,14 @@ const ReviewMeal = ({
}
};

const handleUpdate = async (updates: Partial<StoredMeal>) => {
await updateMeal({
meal_id: mealData.meal_id,
...updates,
});
onUpdate?.(updates);
};

return (
<BottomSheet
ref={bottomSheetRef}
Expand Down
11 changes: 5 additions & 6 deletions components/cards/PastMeals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,32 +48,31 @@ const PastMeals = ({
overdrag={true}
>
{dailyMeals.length > 0 ? (
sortedMeals.map((meal, index) =>
sortedMeals.map((meal) =>
meal.status === "analyzing" ? (
<LoadingMealCard
key={meal.meal_id}
mealId={meal.meal_id}
id={meal.id}
key={index.toString()}
imageUri={meal.image_uri}
createdAt={meal.created_at}
/>
) : meal.status === "failed" ? (
<FailedMealCard
key={index.toString()}
key={meal.meal_id}
mealId={meal.meal_id}
imageUri={meal.image_uri}
errorMessage={meal.error_message || "Unknown error occurred"}
/>
) : (
<PastMealCard
key={index.toString()}
key={meal.meal_id}
meal={meal}
onPress={() => onMealPress(meal)}
/>
)
)
) : (
<EmptyMealCard key={0} />
<EmptyMealCard key="empty" />
)}
</PagerView>
);
Expand Down
10 changes: 4 additions & 6 deletions components/cards/pastmeals/LoadingMealCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,30 @@ const ANALYSIS_TIMEOUT = 60000; // 1 minute in milliseconds
const LoadingMealCard = ({
imageUri,
mealId,
id,
createdAt,
}: {
imageUri: string;
mealId: string;
id: number;
createdAt: number;
}) => {
console.log("loading meal id:", mealId);
const scheme = useColorScheme();
const { deleteMealById, updateMealById } = useMealsDatabase();
const { deleteMealById, updateMeal } = useMealsDatabase();

useEffect(() => {
const timeoutId = setTimeout(() => {
const now = Date.now() / 1000;
if (now - createdAt > 60) {
// 60 seconds
updateMealById(id, {
updateMeal({
meal_id: mealId,
status: "failed",
error_message: "Analysis timed out after 1 minute",
});
}
}, ANALYSIS_TIMEOUT);

return () => clearTimeout(timeoutId);
}, [id, createdAt]);
}, [mealId, createdAt]);

const styles = StyleSheet.create({
container: {
Expand Down
51 changes: 11 additions & 40 deletions components/library/FullLibrary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,15 @@ const FullLibrary = ({
}: {
handlePrefillMeal: (meal: MealTemplate | undefined) => void;
}) => {
const { meals, setMeals, isLoading, error, loadMeals, removeMeal } =
useMealLibrary();
const {
meals,
setMeals,
isLoading,
error,
loadMeals,
removeMeal,
toggleFavorite,
} = useMealLibrary();

useEffect(() => {
loadMeals();
Expand Down Expand Up @@ -44,10 +51,11 @@ const FullLibrary = ({
{Array.isArray(meals) ? (
meals.map((meal) => (
<MealItem
key={meal.id}
key={meal.meal_id}
meal={meal}
setMeals={setMeals}
removeMeal={removeMeal}
toggleFavorite={toggleFavorite}
handlePrefillMeal={handlePrefillMeal}
/>
))
Expand All @@ -67,43 +75,6 @@ const styles = StyleSheet.create({
flexDirection: "row",
flexWrap: "wrap",
},
mealContainer: {
width: "50%",
padding: 5,
},
mealImage: {
width: "100%",
height: 150,
justifyContent: "space-between",
},
imageStyle: {
borderRadius: 10,
},
iconContainer: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
width: "100%",
padding: 5,
},
centerIcon: {
position: "absolute",
left: 0,
right: 0,
top: 50,
alignItems: "center",
},
titleContainer: {
position: "absolute",
bottom: 0,
width: "100%",
padding: 5,
},
mealName: {
fontWeight: "bold",
textAlign: "center",
color: "white",
},
});

export default FullLibrary;
65 changes: 31 additions & 34 deletions components/library/MealItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,28 @@ import {
useColorScheme,
} from "react-native";
import Ionicons from "@expo/vector-icons/Ionicons";
import { useMealsDatabase } from "../../shared/MealsStorageContext";
import { StoredMeal, MealTemplate } from "../../types";
import { useMealLibrary } from "../../hooks/useMealLibrary";

const MealItem = ({
interface MealItemProps {
meal: StoredMeal;
setMeals: React.Dispatch<React.SetStateAction<StoredMeal[]>>;
removeMeal: (meal: StoredMeal) => Promise<void>;
handlePrefillMeal: (meal: MealTemplate) => void;
toggleFavorite: (meal: StoredMeal) => Promise<void>;
}

const MealItem: React.FC<MealItemProps> = ({
meal,
setMeals,
removeMeal,
handlePrefillMeal,
}: {
meal: StoredMeal;
setMeals: React.Dispatch<React.SetStateAction<StoredMeal[]>>;
removeMeal: (meal: StoredMeal) => void;
handlePrefillMeal: (meal: MealTemplate | undefined) => void;
toggleFavorite,
}) => {
const scheme = useColorScheme();
const { toggleFavorite } = useMealLibrary();
const animatedOpacity = useRef(
new Animated.Value(meal.favorite ? 1 : 0)
).current;

// Add handlePrefill function
const handlePrefill = () => {
if (!meal.last_analysis) return;

Expand All @@ -58,11 +58,10 @@ const MealItem = ({
});
};

// Optimistically update UI before the backend catches up
const handleFavoriteToggle = async () => {
setMeals((currentMeals) => {
const newMeals = currentMeals.map((m) =>
m.id === meal.id ? { ...m, favorite: !m.favorite } : m
m.meal_id === meal.meal_id ? { ...m, favorite: !m.favorite } : m
);
return newMeals;
});
Expand All @@ -73,19 +72,13 @@ const MealItem = ({
console.error("Error toggling favorite:", error);
setMeals((currentMeals) =>
currentMeals.map((m) =>
m.id === meal.id ? { ...m, favorite: meal.favorite } : m
m.meal_id === meal.meal_id ? { ...m, favorite: meal.favorite } : m
)
);
}
};

const handleLongPress = () => {
if (meal.favorite) {
handleFavoriteToggle();
} else {
handleFavoriteToggle();
}
};
const handleLongPress = handleFavoriteToggle;

useEffect(() => {
Animated.timing(animatedOpacity, {
Expand All @@ -95,7 +88,6 @@ const MealItem = ({
}).start();
}, [meal.favorite]);

// JSX for rendering a single meal
return (
<TouchableOpacity
style={styles.mealContainer}
Expand All @@ -109,18 +101,15 @@ const MealItem = ({
imageStyle={styles.imageStyle}
>
<View
style={{
position: "absolute",
top: 0,
bottom: 0,
left: 0,
right: 0,
borderRadius: 10,
backgroundColor:
scheme === "dark"
? "rgba(0, 0, 0, 0.5)"
: "rgba(255, 255, 255, 0.5)",
}}
style={[
styles.overlay,
{
backgroundColor:
scheme === "dark"
? "rgba(0, 0, 0, 0.5)"
: "rgba(255, 255, 255, 0.5)",
},
]}
/>
<View style={styles.iconContainer}>
<TouchableOpacity onPress={() => removeMeal(meal)}>
Expand All @@ -145,7 +134,7 @@ const MealItem = ({
{ color: scheme === "dark" ? "#fff" : "#000" },
]}
>
{meal.name}
{meal.last_analysis?.meal_name || "Unnamed Meal"}
</Text>
</View>
</ImageBackground>
Expand Down Expand Up @@ -198,6 +187,14 @@ const styles = StyleSheet.create({
textAlign: "center",
color: "white",
},
overlay: {
position: "absolute",
top: 0,
bottom: 0,
left: 0,
right: 0,
borderRadius: 10,
},
});

export default MealItem;
16 changes: 11 additions & 5 deletions components/screens/Summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import UploadingMeal from "../addmeal/UploadingMeal";
import useResizedImage from "../../hooks/useResizedImage";
import ReviewMeal from "../addmeal/ReviewMeal";
import { useMealsDatabase } from "../../shared/MealsStorageContext";
import { StoredMeal } from "../../types";

const Summary = ({ navigation }) => {
const scheme = useColorScheme();
Expand All @@ -22,7 +23,7 @@ const Summary = ({ navigation }) => {
const [imageURI, setImageURI] = useState<string | undefined>();
const resizedImage = useResizedImage(imageURI);
const [reviewingMeal, setReviewingMeal] = useState(null);
const { updateMealById } = useMealsDatabase();
const { updateMeal } = useMealsDatabase();
const [libraryStatus, requestLibraryPermission] =
ImagePicker.useMediaLibraryPermissions();

Expand Down Expand Up @@ -86,6 +87,14 @@ const Summary = ({ navigation }) => {
}
};

const onMealUpdate = (meal: StoredMeal, updatedData: any) => {
updateMeal({
meal_id: meal.meal_id,
status: updatedData.status,
last_analysis: updatedData.last_analysis,
});
};

return (
<View style={dynamicStyles.container}>
<Text style={dynamicStyles.title}>Summary</Text>
Expand Down Expand Up @@ -120,10 +129,7 @@ const Summary = ({ navigation }) => {
imageURI={reviewingMeal.image_uri}
mealData={reviewingMeal}
onUpdate={(updatedData) => {
updateMealById(reviewingMeal.id, {
status: updatedData.status,
last_analysis: updatedData.last_analysis,
});
onMealUpdate(reviewingMeal, updatedData);
setReviewingMeal(null);
}}
onClose={() => setReviewingMeal(null)}
Expand Down
Loading

0 comments on commit 46c3814

Please sign in to comment.