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

force utc everywhere

Changed files
+43 -10
src
routes
rnfgrertt
+43 -10
src/routes/rnfgrertt/borgle.lazy.tsx
··· 3 import { QtContext } from "@/providers/qtprovider"; 4 import { Check, Loader2, Clipboard } from "lucide-react"; 5 import { generateTid, tidToTime } from "@/lib/tid"; 6 7 import { WORD_LIST, ACCEPTED_WORDS } from "@/lib/borgle-lists"; 8 import { StateUpdater } from "preact/hooks"; ··· 87 88 // Get word and puzzle number based on the current date 89 function getTodaysWordData(): WordData { 90 - const today = new Date(); 91 - const startDate = new Date("2025-06-10"); // Reference start date 92 const daysSinceStart = Math.floor( 93 (today.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24), 94 ); ··· 100 return { 101 word: WORD_LIST[index], 102 puzzleNumber: daysSinceStart + 1, // Start from puzzle #1 103 - date: today.toLocaleDateString(), 104 }; 105 } 106 ··· 135 const [hasSubmittedToday, setHasSubmittedToday] = useState<boolean>(false); 136 const [submissionRecord, setSubmissionRecord] = useState<string>(""); 137 const [submissionError, setSubmissionError] = useState<string>(""); 138 139 // Initialize game 140 useEffect(() => { ··· 143 } 144 }, [checkingSubmission, todaysSubmission]); 145 146 // Submit playthrough when game ends 147 useEffect(() => { 148 const submitPlaythrough = async () => { ··· 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 { ··· 255 try { 256 console.log("Checking submission"); 257 const wordData = getTodaysWordData(); 258 - const today = new Date().toISOString().split("T")[0]; // YYYY-MM-DD format 259 260 const response = await qt.client.rpc.get("com.atproto.repo.listRecords", { 261 params: { ··· 617 }; 618 619 const generateCurrentGameState = (): string => { 620 - let state = `Borgle Puzzle #${puzzleNumber} (${todaysDate})\n`; 621 622 for (let res in evaluations) { 623 const evalRow = evaluations[res]; ··· 718 <h1 className="text-4xl font-bold tracking-wide">BORGLE</h1> 719 {puzzleNumber > 0 && ( 720 <div className="text-sm text-muted-foreground mt-1"> 721 - Puzzle #{puzzleNumber} • {todaysDate} 722 </div> 723 )} 724 </div> ··· 739 740 <div className="text-center"> 741 <div className="text-sm text-gray-500 mb-4"> 742 - Come back tomorrow for the next puzzle! 743 </div> 744 <button 745 onClick={() => { ··· 827 /> 828 </div> 829 <div className="text-xs text-gray-500 mt-2"> 830 - Daily word changes at midnight 831 </div> 832 </div> 833 ) : (
··· 3 import { QtContext } from "@/providers/qtprovider"; 4 import { Check, Loader2, Clipboard } from "lucide-react"; 5 import { generateTid, tidToTime } from "@/lib/tid"; 6 + import { timeAgo } from "@/lib/utils"; 7 8 import { WORD_LIST, ACCEPTED_WORDS } from "@/lib/borgle-lists"; 9 import { StateUpdater } from "preact/hooks"; ··· 88 89 // Get word and puzzle number based on the current date 90 function getTodaysWordData(): WordData { 91 + const now = new Date(); 92 + const today = new Date( 93 + Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()), 94 + ); 95 + const startDate = new Date("2025-06-10T00:00:00Z"); // Reference start date in UTC 96 const daysSinceStart = Math.floor( 97 (today.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24), 98 ); ··· 104 return { 105 word: WORD_LIST[index], 106 puzzleNumber: daysSinceStart + 1, // Start from puzzle #1 107 + date: today.toISOString().split("T")[0], // Use UTC date 108 }; 109 } 110 ··· 139 const [hasSubmittedToday, setHasSubmittedToday] = useState<boolean>(false); 140 const [submissionRecord, setSubmissionRecord] = useState<string>(""); 141 const [submissionError, setSubmissionError] = useState<string>(""); 142 + const [nextPuzzleTime, setNextPuzzleTime] = useState<string>(""); 143 144 // Initialize game 145 useEffect(() => { ··· 148 } 149 }, [checkingSubmission, todaysSubmission]); 150 151 + // Update countdown timer 152 + useEffect(() => { 153 + const updateCountdown = () => { 154 + const now = new Date(); 155 + const nextMidnightUTC = new Date(); 156 + nextMidnightUTC.setUTCDate(nextMidnightUTC.getUTCDate() + 1); 157 + nextMidnightUTC.setUTCHours(0, 0, 0, 0); // Set to UTC midnight 158 + 159 + setNextPuzzleTime( 160 + timeAgo(nextMidnightUTC, { future: true, useShortLabels: true }), 161 + ); 162 + }; 163 + 164 + updateCountdown(); // Initial update 165 + const interval = setInterval(updateCountdown, 60000); // Update every minute 166 + 167 + return () => clearInterval(interval); 168 + }, []); 169 + 170 // Submit playthrough when game ends 171 useEffect(() => { 172 const submitPlaythrough = async () => { ··· 176 177 try { 178 setHasSubmittedToday(true); 179 + // Check if today's submission already exists (using UTC date) 180 + const now = new Date(); 181 + const todayUTC = new Date( 182 + Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()), 183 + ); 184 + const today = todayUTC.toISOString().split("T")[0]; 185 const response = await qt.client.rpc.get( 186 "com.atproto.repo.listRecords", 187 { ··· 283 try { 284 console.log("Checking submission"); 285 const wordData = getTodaysWordData(); 286 + const now = new Date(); 287 + const todayUTC = new Date( 288 + Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()), 289 + ); 290 + const today = todayUTC.toISOString().split("T")[0]; // YYYY-MM-DD format in UTC 291 292 const response = await qt.client.rpc.get("com.atproto.repo.listRecords", { 293 params: { ··· 649 }; 650 651 const generateCurrentGameState = (): string => { 652 + let state = `Borgle Puzzle #${puzzleNumber}\n`; 653 654 for (let res in evaluations) { 655 const evalRow = evaluations[res]; ··· 750 <h1 className="text-4xl font-bold tracking-wide">BORGLE</h1> 751 {puzzleNumber > 0 && ( 752 <div className="text-sm text-muted-foreground mt-1"> 753 + Puzzle #{puzzleNumber} • {todaysDate} Zulu time 754 </div> 755 )} 756 </div> ··· 771 772 <div className="text-center"> 773 <div className="text-sm text-gray-500 mb-4"> 774 + Come back after midnight UTC ({nextPuzzleTime}) for the next 775 + puzzle! 776 </div> 777 <button 778 onClick={() => { ··· 860 /> 861 </div> 862 <div className="text-xs text-gray-500 mt-2"> 863 + Daily puzzle changes at midnight UTC ({nextPuzzleTime}) 864 </div> 865 </div> 866 ) : (