Fork of atp.tools as a universal profile for people on the ATmosphere

submit only once

Changed files
+92 -58
src
routes
rnfgrertt
+92 -58
src/routes/rnfgrertt/borgle.lazy.tsx
··· 35 35 }; 36 36 37 37 function AutoSubmitPlaythrough({ 38 - evaluations, 39 - gameState, 38 + record, 39 + error, 40 + isSubmitting, 40 41 }: { 41 - evaluations: EvaluationsArray; 42 - gameState: GameState; 42 + record: string; 43 + error: string; 44 + isSubmitting: boolean; 43 45 }) { 44 - const [record, setRecord] = useState(""); 45 - const [error, setError] = useState(""); 46 - const qt = useContext(QtContext); 47 - 48 - // Convert evaluations to the lexicon format for submission 49 - const playthroughData: BorglePlayRecord = { 50 - game: evaluations 51 - .filter( 52 - (evaluation): evaluation is GuessEvaluation => evaluation !== null, 53 - ) 54 - .map((evaluation) => ({ 55 - guess: evaluation.guess, 56 - evaluations: evaluation.evaluations, 57 - })), 58 - }; 59 - 60 - // Submit once when game ends 61 - useEffect(() => { 62 - const submitPlaythrough = async () => { 63 - if (!qt) { 64 - console.error("QtContext is not available"); 65 - return; 66 - } 67 - if (record !== "" || gameState === "playing") return; 68 - if (playthroughData.game.length === 0) return; 69 - 70 - try { 71 - if (qt.currentAgent) { 72 - let response = await qt.client.rpc.call( 73 - "com.atproto.repo.putRecord", 74 - { 75 - data: { 76 - rkey: generateTid().toString(), 77 - repo: qt.currentAgent.sub, 78 - record: playthroughData, 79 - collection: "tools.atp.borgle.play", 80 - }, 81 - }, 82 - ); 83 - console.log("Playthrough submitted successfully"); 84 - setRecord(response.data.uri); 85 - } 86 - } catch (err: any) { 87 - console.error("Error submitting playthrough:", err); 88 - setError(err.toString()); 89 - } 90 - }; 91 - 92 - submitPlaythrough(); 93 - }, [qt, gameState, playthroughData]); 94 - 95 46 if (error) { 96 47 return ( 97 48 <div className="text-red-500 text-xs">Error: {error.slice(0, 50)}...</div> ··· 113 64 ); 114 65 } 115 66 116 - if (gameState !== "playing") { 67 + if (isSubmitting) { 117 68 return ( 118 69 <div className="flex items-center gap-1"> 119 70 <Loader2 className="animate-spin w-4 h-4" /> ··· 181 132 const [todaysSubmission, setTodaysSubmission] = 182 133 useState<BorglePlayRecord | null>(null); 183 134 const [checkingSubmission, setCheckingSubmission] = useState<boolean>(true); 135 + const [hasSubmittedToday, setHasSubmittedToday] = useState<boolean>(false); 136 + const [submissionRecord, setSubmissionRecord] = useState<string>(""); 137 + const [submissionError, setSubmissionError] = useState<string>(""); 184 138 185 139 // Initialize game 186 140 useEffect(() => { ··· 188 142 startNewGame(); 189 143 } 190 144 }, [checkingSubmission, todaysSubmission]); 145 + 146 + // Submit playthrough when game ends 147 + useEffect(() => { 148 + const submitPlaythrough = async () => { 149 + if (!qt || !qt.currentAgent) return; 150 + if (hasSubmittedToday || gameState === "playing") return; 151 + if (evaluations.filter((e) => e !== null).length === 0) return; 152 + 153 + try { 154 + setHasSubmittedToday(true); 155 + // Check if today's submission already exists 156 + const today = new Date().toISOString().split("T")[0]; 157 + const response = await qt.client.rpc.get( 158 + "com.atproto.repo.listRecords", 159 + { 160 + params: { 161 + repo: qt.currentAgent.sub, 162 + collection: "tools.atp.borgle.play", 163 + limit: 50, 164 + }, 165 + }, 166 + ); 167 + 168 + // Check if any submission from today exists 169 + const existingSubmission = response.data.records.find((record: any) => { 170 + if (!record.uri) return false; 171 + try { 172 + const rkey = record.uri.split("/").pop(); 173 + if (!rkey) return false; 174 + const recordDate = tidToTime(rkey); 175 + return recordDate.toISOString().split("T")[0] === today; 176 + } catch (error) { 177 + return false; 178 + } 179 + }); 180 + 181 + if (existingSubmission) { 182 + console.log("Today's submission already exists, skipping"); 183 + setSubmissionRecord(existingSubmission.uri); 184 + setHasSubmittedToday(true); 185 + return; 186 + } 187 + 188 + // Convert evaluations to the lexicon format for submission 189 + const playthroughData: BorglePlayRecord = { 190 + game: evaluations 191 + .filter( 192 + (evaluation): evaluation is GuessEvaluation => 193 + evaluation !== null, 194 + ) 195 + .map((evaluation) => ({ 196 + guess: evaluation.guess, 197 + evaluations: evaluation.evaluations, 198 + })), 199 + }; 200 + 201 + // Create new record if none exists for today 202 + let createResponse = await qt.client.rpc.call( 203 + "com.atproto.repo.putRecord", 204 + { 205 + data: { 206 + rkey: generateTid().toString(), 207 + repo: qt.currentAgent.sub, 208 + record: playthroughData, 209 + collection: "tools.atp.borgle.play", 210 + }, 211 + }, 212 + ); 213 + console.log("Playthrough submitted successfully"); 214 + setSubmissionRecord(createResponse.data.uri); 215 + setHasSubmittedToday(true); 216 + } catch (err: any) { 217 + console.error("Error submitting playthrough:", err); 218 + setSubmissionError(err.toString()); 219 + } 220 + }; 221 + 222 + submitPlaythrough(); 223 + }, [gameState]); 191 224 192 225 // // Optional: Add debug info to see today's word (remove in production) 193 226 // useEffect(() => { ··· 788 821 Copy your results 789 822 </button> 790 823 <AutoSubmitPlaythrough 791 - evaluations={evaluations} 792 - gameState={gameState} 824 + record={submissionRecord} 825 + error={submissionError} 826 + isSubmitting={!hasSubmittedToday} 793 827 /> 794 828 </div> 795 829 <div className="text-xs text-gray-500 mt-2">