diff --git a/app/game.tsx b/app/game.tsx index 063945a..18a5e80 100644 --- a/app/game.tsx +++ b/app/game.tsx @@ -1,118 +1,56 @@ -import { View, useWindowDimensions } from "react-native"; -import { Text } from "~/components/ui/text"; -import { Button } from "~/components/ui/button"; -import { router } from "expo-router"; +import { View } from "react-native"; import SwipeCard from "./components/swipe-card"; -import { useEffect, useMemo, useState, useRef } from "react"; -import { supabase } from "~/lib/supabase/client"; -import { useSharedValue } from "react-native-reanimated"; - -// Card data type -export type ClientScenario = { - situation: string; - optionA: { text: string; id: number }; - optionB: { text: string; id: number }; -}; +import { useState } from "react"; +import { useScenarioManager } from "~/hooks/useScenarioManager"; const STARTING_SCENARIO_ID = 5; export default function GameScreen() { const [isAnimating, setIsAnimating] = useState(false); - // Add sample cards const [cards, setCards] = useState([1, 2, 3]); - const [MainCardContent, setMainCardContent] = useState( - "This is the first card" - ); - - const [isLoading, setIsLoading] = useState(false); - const [currentScenario, setCurrentScenario] = useState( - undefined - ); - const choiseScenarios = useRef<{ - optionA: ClientScenario | undefined; - optionB: ClientScenario | undefined; - }>({ - optionA: undefined, - optionB: undefined, - }); - - useEffect(() => { - const initializeScenario = async () => { - try { - const { data } = await supabase.functions.invoke("generateScenario", { - body: { scenarioId: STARTING_SCENARIO_ID }, - }); - - const generatedScenario: ClientScenario = data.data; - (["optionA", "optionB"] as const).map((key) => { - console.log(generatedScenario[key].id); - supabase.functions - .invoke("generateScenario", { - body: { scenarioId: generatedScenario[key].id }, - }) - .then((s) => { - console.log(key); - console.log(s.data.data); - choiseScenarios.current = { - ...choiseScenarios.current, - [key]: s.data.data, - }; - }); - }); - console.log(generatedScenario); - setCurrentScenario(generatedScenario); - - // // Prefetch the next two scenarios - - // ); - } catch (error) { - console.error("Failed to load scenario:", error); - } finally { - setIsLoading(false); - } - }; - - initializeScenario(); - }, []); // Empty dependency array means this runs once on mount + const { + currentScenario, + isLoading, + choiceScenarios, + nextCard, + setNextCard, + } = useScenarioManager(STARTING_SCENARIO_ID); const handleDismiss = (direction: "optionA" | "optionB") => { setIsAnimating(true); console.log(`Card swiped ${direction}`); + setTimeout(() => { - // The animation should be stopped after 400ms setIsAnimating(false); - // Remove card which was swiped setCards((prevCards) => prevCards.slice(1)); setCurrentScenario(nextCard!); }, 400); }; - const [nextCard, setNextCard] = useState({ situation: "This is the next card", optionA: { text: "Option A", id: 1 }, optionB: { text: "Option B", id: 2 } }); - - useEffect(() => { - console.log(nextCard); - }, [nextCard]); - const cardComponents = - - // Memoize the card components - - cards.map((card, index) => ( - - )); + const cardComponents = cards.map((card, index) => ( + + )); + + if (isLoading) { + return ( + + Loading... + + ); + } return ( diff --git a/app/hooks/useScenarioManager.ts b/app/hooks/useScenarioManager.ts new file mode 100644 index 0000000..3c03e71 --- /dev/null +++ b/app/hooks/useScenarioManager.ts @@ -0,0 +1,60 @@ +import { useState, useRef, useEffect } from 'react'; +import { supabase } from "~/lib/supabase/client"; +import type { ClientScenario } from '~/types/game'; + +export function useScenarioManager(startingScenarioId: number) { + const [currentScenario, setCurrentScenario] = useState(); + const [isLoading, setIsLoading] = useState(false); + const [nextCard, setNextCard] = useState(); + + const choiceScenarios = useRef<{ + optionA: ClientScenario | undefined; + optionB: ClientScenario | undefined; + }>({ + optionA: undefined, + optionB: undefined, + }); + + const generateScenario = async (scenarioId: number) => { + const { data } = await supabase.functions.invoke("generateScenario", { + body: { scenarioId }, + }); + return data.data; + }; + + const prefetchNextScenarios = async (scenario: ClientScenario) => { + for (const key of ["optionA", "optionB"] as const) { + const nextScenario = await generateScenario(scenario[key].id); + choiceScenarios.current = { + ...choiceScenarios.current, + [key]: nextScenario, + }; + } + }; + + const initializeScenario = async () => { + try { + setIsLoading(true); + const generatedScenario = await generateScenario(startingScenarioId); + setCurrentScenario(generatedScenario); + await prefetchNextScenarios(generatedScenario); + } catch (error) { + console.error("Failed to load scenario:", error); + } finally { + setIsLoading(false); + } + }; + + useEffect(() => { + initializeScenario(); + }, []); + + return { + currentScenario, + setCurrentScenario, + isLoading, + choiceScenarios, + nextCard, + setNextCard, + }; +} \ No newline at end of file diff --git a/app/types/game.ts b/app/types/game.ts new file mode 100644 index 0000000..638b4dd --- /dev/null +++ b/app/types/game.ts @@ -0,0 +1,5 @@ +export type ClientScenario = { + situation: string; + optionA: { text: string; id: number }; + optionB: { text: string; id: number }; +}; \ No newline at end of file