mirror of
https://github.com/pupperpowell/bibdle.git
synced 2026-02-04 10:54:44 -05:00
added first-guess and correct-guess umami event tracking
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { fade } from "svelte/transition";
|
import { fade } from "svelte/transition";
|
||||||
import { getBookById, toOrdinal, getNextGradeMessage } from "$lib/utils/game";
|
import { getBookById, toOrdinal, getNextGradeMessage } from "$lib/utils/game";
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
interface StatsData {
|
interface StatsData {
|
||||||
solveRank: number;
|
solveRank: number;
|
||||||
@@ -33,10 +34,10 @@
|
|||||||
|
|
||||||
// List of congratulations messages with weights
|
// List of congratulations messages with weights
|
||||||
const congratulationsMessages: WeightedMessage[] = [
|
const congratulationsMessages: WeightedMessage[] = [
|
||||||
{ text: "🎉 Congratulations! 🎉", weight: 1000 },
|
{ text: "Congratulations!", weight: 10 },
|
||||||
{ text: "⭐ You got it! ⭐", weight: 10 },
|
{ text: "You got it!", weight: 1000 },
|
||||||
{ text: "🎉 Yup 🎉", weight: 5 },
|
{ text: "Yup,", weight: 100 },
|
||||||
{ text: "👍🏻 Very nice! 👍🏻", weight: 1 },
|
{ text: "Very nice!", weight: 1 },
|
||||||
];
|
];
|
||||||
|
|
||||||
// Function to select a random message based on weights
|
// Function to select a random message based on weights
|
||||||
@@ -45,9 +46,9 @@
|
|||||||
if (guessCount === 1) {
|
if (guessCount === 1) {
|
||||||
const n = Math.random();
|
const n = Math.random();
|
||||||
if (n < 0.99) {
|
if (n < 0.99) {
|
||||||
return "🤯 First try! 🤯";
|
return "🌟 First try! 🌟";
|
||||||
} else {
|
} else {
|
||||||
return "‼️ Axios ‼️";
|
return "🗣️ Axios! 🗣️";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,18 +71,25 @@
|
|||||||
|
|
||||||
// Generate the congratulations message
|
// Generate the congratulations message
|
||||||
let congratulationsMessage = $derived(getRandomCongratulationsMessage());
|
let congratulationsMessage = $derived(getRandomCongratulationsMessage());
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (typeof window !== "undefined" && (window as any).umami) {
|
||||||
|
(window as any).umami.track("guessed-correctly", {
|
||||||
|
totalGuesses: guessCount,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="p-8 sm:p-12 w-full bg-linear-to-r from-green-400 to-green-600 text-white rounded-2xl shadow-2xl text-center fade-in"
|
class="p-8 sm:p-12 w-full bg-linear-to-r from-green-400 to-green-600 text-white rounded-2xl shadow-2xl text-center fade-in"
|
||||||
>
|
>
|
||||||
<h2 class="text-2xl sm:text-4xl font-black mb-4 drop-shadow-lg">
|
<!-- <h2 class="text-2xl sm:text-4xl font-black mb-4 drop-shadow-lg">
|
||||||
{congratulationsMessage}
|
{congratulationsMessage}
|
||||||
</h2>
|
</h2> -->
|
||||||
<p class="text-lg sm:text-xl md:text-2xl">
|
<p class="text-xl sm:text-3xl md:text-4xl">
|
||||||
The verse is from <span class="font-black text-xl sm:text-2xl md:text-3xl"
|
{congratulationsMessage} The verse is from
|
||||||
>{bookName}</span
|
<span class="font-black text-xl sm:text-2xl md:text-3xl">{bookName}</span>.
|
||||||
>
|
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
class="text-2xl font-bold mt-6 p-2 mx-2 bg-black/20 rounded-lg inline-block"
|
class="text-2xl font-bold mt-6 p-2 mx-2 bg-black/20 rounded-lg inline-block"
|
||||||
|
|||||||
@@ -49,17 +49,14 @@
|
|||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "long",
|
month: "long",
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
let isWon = $derived(guesses.some((g) => g.book.id === correctBookId));
|
let isWon = $derived(guesses.some((g) => g.book.id === correctBookId));
|
||||||
let grade = $derived(
|
let grade = $derived(
|
||||||
isWon
|
isWon
|
||||||
? getGrade(
|
? getGrade(guesses.length, getBookById(correctBookId)?.popularity ?? 0)
|
||||||
guesses.length,
|
: ""
|
||||||
getBookById(correctBookId)?.popularity ?? 0,
|
|
||||||
)
|
|
||||||
: "",
|
|
||||||
);
|
);
|
||||||
|
|
||||||
function getBookById(id: string): BibleBook | undefined {
|
function getBookById(id: string): BibleBook | undefined {
|
||||||
@@ -86,9 +83,13 @@
|
|||||||
const adjacent = isAdjacent(book.id, correctBookId);
|
const adjacent = isAdjacent(book.id, correctBookId);
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`Guess: ${book.name} (order ${book.order}), Correct: ${correctBook.name} (order ${correctBook.order}), Adjacent: ${adjacent}`,
|
`Guess: ${book.name} (order ${book.order}), Correct: ${correctBook.name} (order ${correctBook.order}), Adjacent: ${adjacent}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (guesses.length === 0 && browser && (window as any).umami) {
|
||||||
|
(window as any).umami.track("first-guess");
|
||||||
|
}
|
||||||
|
|
||||||
guesses = [
|
guesses = [
|
||||||
{
|
{
|
||||||
book,
|
book,
|
||||||
@@ -110,8 +111,7 @@
|
|||||||
|
|
||||||
// Fallback UUID v4 generator for older browsers
|
// Fallback UUID v4 generator for older browsers
|
||||||
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
||||||
const r =
|
const r = window.crypto.getRandomValues(new Uint8Array(1))[0] % 16 | 0;
|
||||||
window.crypto.getRandomValues(new Uint8Array(1))[0] % 16 | 0;
|
|
||||||
const v = c === "x" ? r : (r & 0x3) | 0x8;
|
const v = c === "x" ? r : (r & 0x3) | 0x8;
|
||||||
return v.toString(16);
|
return v.toString(16);
|
||||||
});
|
});
|
||||||
@@ -170,7 +170,7 @@
|
|||||||
if (!browser) return;
|
if (!browser) return;
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
`bibdle-guesses-${dailyVerse.date}`,
|
`bibdle-guesses-${dailyVerse.date}`,
|
||||||
JSON.stringify(guesses.map((g) => g.book.id)),
|
JSON.stringify(guesses.map((g) => g.book.id))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@
|
|||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`/api/submit-completion?anonymousId=${anonymousId}&date=${dailyVerse.date}`,
|
`/api/submit-completion?anonymousId=${anonymousId}&date=${dailyVerse.date}`
|
||||||
);
|
);
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
console.log("Stats response:", result);
|
console.log("Stats response:", result);
|
||||||
@@ -205,7 +205,7 @@
|
|||||||
statsData = result.stats;
|
statsData = result.stats;
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
`bibdle-stats-submitted-${dailyVerse.date}`,
|
`bibdle-stats-submitted-${dailyVerse.date}`,
|
||||||
"true",
|
"true"
|
||||||
);
|
);
|
||||||
} else if (result.error) {
|
} else if (result.error) {
|
||||||
console.error("Server error:", result.error);
|
console.error("Server error:", result.error);
|
||||||
@@ -249,7 +249,7 @@
|
|||||||
statsSubmitted = true;
|
statsSubmitted = true;
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
`bibdle-stats-submitted-${dailyVerse.date}`,
|
`bibdle-stats-submitted-${dailyVerse.date}`,
|
||||||
"true",
|
"true"
|
||||||
);
|
);
|
||||||
} else if (result.error) {
|
} else if (result.error) {
|
||||||
console.error("Server error:", result.error);
|
console.error("Server error:", result.error);
|
||||||
@@ -283,7 +283,7 @@
|
|||||||
year: "numeric",
|
year: "numeric",
|
||||||
});
|
});
|
||||||
const formattedDate = dateFormatter.format(
|
const formattedDate = dateFormatter.format(
|
||||||
new Date(`${dailyVerse.date}T00:00:00`),
|
new Date(`${dailyVerse.date}T00:00:00`)
|
||||||
);
|
);
|
||||||
const siteUrl = window.location.origin;
|
const siteUrl = window.location.origin;
|
||||||
return [
|
return [
|
||||||
|
|||||||
21
todo.md
21
todo.md
@@ -1,17 +1,17 @@
|
|||||||
# in progress
|
# in progress
|
||||||
|
|
||||||
|
|
||||||
- root menu: classic / imposter mode / impossible mode (complete today's classic and imposter modes to unlock)
|
- root menu: classic / imposter mode / impossible mode (complete today's classic and imposter modes to unlock)
|
||||||
|
|
||||||
|
|
||||||
# todo
|
# todo
|
||||||
|
|
||||||
- impossible mode (1904 greek bible) three guesses only.
|
- impossible mode (1904 greek bible) three guesses only.
|
||||||
|
|
||||||
- share both classic and impossible mode with both buttons
|
- share both classic and impossible mode with both buttons
|
||||||
|
|
||||||
- add imposter mode
|
- add imposter mode
|
||||||
|
|
||||||
- instructions
|
- instructions
|
||||||
|
|
||||||
- classic mode: identify what book the verse is from (e.g. Genesis, John, Revelations...) in as few guesses as possible.
|
- classic mode: identify what book the verse is from (e.g. Genesis, John, Revelations...) in as few guesses as possible.
|
||||||
- imposter mode: out of four options, identify the verse that is not in the Bible
|
- imposter mode: out of four options, identify the verse that is not in the Bible
|
||||||
- impossible mode: identify which book of the bible the verse is from in less than three guesses.
|
- impossible mode: identify which book of the bible the verse is from in less than three guesses.
|
||||||
@@ -21,23 +21,18 @@
|
|||||||
- add deuterocanonical books
|
- add deuterocanonical books
|
||||||
|
|
||||||
<!-- Login features -->
|
<!-- Login features -->
|
||||||
|
|
||||||
- Practice mode: Unlimited verses
|
- Practice mode: Unlimited verses
|
||||||
- Create public or private leaderboards
|
- Create public or private leaderboards
|
||||||
- Passport book with badges:
|
- Passport book with awards:
|
||||||
|
|
||||||
- Guess each Gospel first try
|
- Guess each Gospel first try
|
||||||
- "Guessed all Gospels", "Perfect week", "Old Testament expert"
|
- "Guessed all Gospels", "Perfect week", "Old Testament expert"
|
||||||
- Theologian: Guess each book first try
|
- Theologian: Guess each book first try
|
||||||
|
- If chapter is 6 and verse 7, earn award "Six seven"
|
||||||
|
|
||||||
|
|
||||||
- difficult mode (guess old or new testament, first try _only_) (???)
|
- difficult mode (guess old or new testament, first try _only_) (???)
|
||||||
|
|
||||||
# places to send
|
|
||||||
|
|
||||||
- linkedin post
|
|
||||||
- ocf discord server ✅
|
|
||||||
- nick makiej ✅
|
|
||||||
|
|
||||||
# About this game
|
# About this game
|
||||||
|
|
||||||
As a young camper at the Metropolis of Boston Camp, I remember His Eminence Metropolitan Methodios would visit every Sunday. He was often surrounded by important people for his entire time there, so I never gathered the courage to introduce myself, but his homilies during Liturgy always stood out to me. In some ways, they differed year after year, but a majority of his message remained strikingly familiar. "Take ten minutes to read the Bible every day," he asked. "Just ten minutes. Go somewhere quiet, turn off the TV (then iPod, then cell phone), and read in peace and quiet."
|
As a young camper at the Metropolis of Boston Camp, I remember His Eminence Metropolitan Methodios would visit every Sunday. He was often surrounded by important people for his entire time there, so I never gathered the courage to introduce myself, but his homilies during Liturgy always stood out to me. In some ways, they differed year after year, but a majority of his message remained strikingly familiar. "Take ten minutes to read the Bible every day," he asked. "Just ten minutes. Go somewhere quiet, turn off the TV (then iPod, then cell phone), and read in peace and quiet."
|
||||||
@@ -52,6 +47,10 @@ I created Bibdle from a combination of two things. The first is my lifelong desi
|
|||||||
|
|
||||||
# done
|
# done
|
||||||
|
|
||||||
|
## december 27th
|
||||||
|
|
||||||
|
- add event log to submitting first-guess or correct-guess to umami (to make bounce rate more accurate)
|
||||||
|
|
||||||
## december 26th
|
## december 26th
|
||||||
|
|
||||||
- created embeddings for every bible verse (verse similarity finder)
|
- created embeddings for every bible verse (verse similarity finder)
|
||||||
|
|||||||
Reference in New Issue
Block a user