Added streak counter

This commit is contained in:
George Powell
2026-02-21 01:24:16 -05:00
parent 19646c72ca
commit c3307b3920
5 changed files with 129 additions and 68 deletions

View File

@@ -12,12 +12,13 @@
import DevButtons from "$lib/components/DevButtons.svelte";
import AuthModal from "$lib/components/AuthModal.svelte";
import { evaluateGuess, getGrade } from "$lib/utils/game";
import { evaluateGuess } from "$lib/utils/game";
import {
generateShareText,
shareResult,
copyToClipboard as clipboardCopy,
} from "$lib/utils/share";
import { fetchStreak } from "$lib/utils/streak";
import {
submitCompletion,
fetchExistingStats,
@@ -39,6 +40,7 @@
let authModalOpen = $state(false);
let showWinScreen = $state(false);
let statsData = $state<StatsData | null>(null);
let streak = $state(0);
const persistence = createGamePersistence(
() => dailyVerse.date,
@@ -63,13 +65,6 @@
let isWon = $derived(
persistence.guesses.some((g) => g.book.id === correctBookId),
);
let grade = $derived(
isWon
? persistence.guesses.length === 1 && persistence.chapterCorrect
? "S++"
: getGrade(persistence.guesses.length)
: "",
);
let blurChapter = $derived(
isWon &&
persistence.guesses.length === 1 &&
@@ -216,15 +211,23 @@
}
});
// Fetch streak when the player wins
$effect(() => {
if (!browser || !isWon || !persistence.anonymousId) return;
const localDate = new Date().toLocaleDateString("en-CA");
fetchStreak(persistence.anonymousId, localDate).then((result) => {
streak = result;
});
});
function getShareText(): string {
return generateShareText({
guesses: persistence.guesses,
correctBookId,
dailyVerseDate: dailyVerse.date,
grade,
chapterCorrect: persistence.chapterCorrect,
isLoggedIn: !!user,
userStreak: user ? (user as any).streak : undefined,
streak,
origin: window.location.origin,
});
}
@@ -294,7 +297,6 @@
{:else if showWinScreen}
<div class="animate-fade-in-up animate-delay-400">
<WinScreen
{grade}
{statsData}
{correctBookId}
{handleShare}
@@ -304,7 +306,8 @@
guessCount={persistence.guesses.length}
reference={dailyVerse.reference}
onChapterGuessCompleted={persistence.onChapterGuessCompleted}
shareText={getShareText()}
shareText={getShareText()}
{streak}
/>
</div>
{/if}
@@ -388,6 +391,7 @@
)}
</div>
<div>Daily Verse Date: {dailyVerse.date}</div>
<div>Streak: {streak}</div>
</div>
<DevButtons anonymousId={persistence.anonymousId} />
</div>

View File

@@ -0,0 +1,36 @@
import { json, error } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { db } from '$lib/server/db';
import { dailyCompletions } from '$lib/server/db/schema';
import { eq, desc } from 'drizzle-orm';
export const GET: RequestHandler = async ({ url }) => {
const anonymousId = url.searchParams.get('anonymousId');
const localDate = url.searchParams.get('localDate');
if (!anonymousId || !localDate) {
error(400, 'Missing anonymousId or localDate');
}
// Fetch all completion dates for this user, newest first
const rows = await db
.select({ date: dailyCompletions.date })
.from(dailyCompletions)
.where(eq(dailyCompletions.anonymousId, anonymousId))
.orderBy(desc(dailyCompletions.date));
const completedDates = new Set(rows.map((r) => r.date));
// Walk backwards from localDate, counting consecutive completed days
let streak = 0;
let cursor = new Date(`${localDate}T00:00:00`);
while (true) {
const dateStr = cursor.toLocaleDateString('en-CA'); // YYYY-MM-DD
if (!completedDates.has(dateStr)) break;
streak++;
cursor.setDate(cursor.getDate() - 1);
}
return json({ streak });
};