+43
-10
src/routes/rnfgrertt/borgle.lazy.tsx
+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
) : (