diff --git a/bun.lock b/bun.lock index 2147206..83067a0 100644 --- a/bun.lock +++ b/bun.lock @@ -7,6 +7,7 @@ "dependencies": { "@xenova/transformers": "^2.17.2", "fast-xml-parser": "^5.3.3", + "marked": "^17.0.4", "xml2js": "^0.6.2", }, "devDependencies": { @@ -394,6 +395,8 @@ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + "marked": ["marked@17.0.4", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-NOmVMM+KAokHMvjWmC5N/ZOvgmSWuqJB8FoYI019j4ogb/PeRMKoKIjReZ2w3376kkA8dSJIP8uD993Kxc0iRQ=="], + "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], diff --git a/package.json b/package.json index a29aa16..4a469b3 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "dependencies": { "@xenova/transformers": "^2.17.2", "fast-xml-parser": "^5.3.3", + "marked": "^17.0.4", "xml2js": "^0.6.2" } } diff --git a/src/lib/components/Credits.svelte b/src/lib/components/Credits.svelte index c9aa56e..683b9ce 100644 --- a/src/lib/components/Credits.svelte +++ b/src/lib/components/Credits.svelte @@ -1,7 +1,6 @@
@@ -28,56 +27,8 @@
-
- (window as any).rybbit?.event("Bluesky clicked")} - > - Bluesky - - -
- - (window as any).rybbit?.event("Twitter clicked")} - > - Twitter - - -
- - (window as any).rybbit?.event("Email clicked")} - > - - - - +
+
+
diff --git a/src/lib/components/SocialLinks.svelte b/src/lib/components/SocialLinks.svelte new file mode 100644 index 0000000..5fa3497 --- /dev/null +++ b/src/lib/components/SocialLinks.svelte @@ -0,0 +1,57 @@ + + +
+ (window as any).rybbit?.event("Bluesky clicked")} + > + Bluesky + + +
+ + (window as any).rybbit?.event("Twitter clicked")} + > + Twitter + + +
+ + (window as any).rybbit?.event("Email clicked")} + > + + + + +
diff --git a/src/lib/components/ThemeToggle.svelte b/src/lib/components/ThemeToggle.svelte new file mode 100644 index 0000000..47f553f --- /dev/null +++ b/src/lib/components/ThemeToggle.svelte @@ -0,0 +1,62 @@ + + +{#if browser} + +{/if} diff --git a/src/lib/components/WinScreen.svelte b/src/lib/components/WinScreen.svelte index 2659a8a..ec4ae7e 100644 --- a/src/lib/components/WinScreen.svelte +++ b/src/lib/components/WinScreen.svelte @@ -39,6 +39,8 @@ verseText, streak = 0, streakPercentile = null, + isLoggedIn = false, + anonymousId = '', }: { statsData: StatsData | null; correctBookId: string; @@ -53,6 +55,8 @@ verseText: string; streak?: number; streakPercentile?: number | null; + isLoggedIn?: boolean; + anonymousId?: string; } = $props(); let bookName = $derived(getBookById(correctBookId)?.name ?? ""); @@ -319,6 +323,24 @@ {/if} + + {#if !isLoggedIn} +
+

Sign in to save your streak & see your stats

+
+ + +
+
+ {/if} diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index e5f72a6..3e58d5b 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,26 +1,35 @@ - - + + + -{@render children()} + +
+

+ +
+

+ {@render children()} +
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 2639ad9..b6a1152 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -8,7 +8,7 @@ import GuessesTable from "$lib/components/GuessesTable.svelte"; import WinScreen from "$lib/components/WinScreen.svelte"; import Credits from "$lib/components/Credits.svelte"; - import TitleAnimation from "$lib/components/TitleAnimation.svelte"; + import ThemeToggle from "$lib/components/ThemeToggle.svelte"; import DevButtons from "$lib/components/DevButtons.svelte"; import AuthModal from "$lib/components/AuthModal.svelte"; @@ -35,6 +35,15 @@ let user = $derived(data.user); let session = $derived(data.session); + const currentDate = $derived( + new Date().toLocaleDateString("en-US", { + weekday: "long", + year: "numeric", + month: "long", + day: "numeric", + }), + ); + let searchQuery = $state(""); let copied = $state(false); let isDev = $state(false); @@ -55,15 +64,6 @@ new SvelteSet(persistence.guesses.map((g) => g.book.id)), ); - const currentDate = $derived( - new Date().toLocaleDateString("en-US", { - weekday: "long", - year: "numeric", - month: "long", - day: "numeric", - }), - ); - let isWon = $derived( persistence.guesses.some((g) => g.book.id === correctBookId), ); @@ -283,20 +283,13 @@ A daily bible game{isDev ? " (dev)" : ""} -
+
-

- -
-

{isDev ? "Dev Edition | " : ""}{currentDate}
-
@@ -304,7 +297,12 @@ {#if !isWon}
- +
{:else if showWinScreen}
@@ -322,6 +320,8 @@ verseText={dailyVerse.verseText} {streak} {streakPercentile} + isLoggedIn={!!user} + anonymousId={persistence.anonymousId} />
{/if} @@ -335,6 +335,11 @@
{/if} + + +
{#if isDev}
diff --git a/src/routes/about/+page.server.ts b/src/routes/about/+page.server.ts new file mode 100644 index 0000000..9b7aa34 --- /dev/null +++ b/src/routes/about/+page.server.ts @@ -0,0 +1,13 @@ +import { readFileSync } from 'fs'; +import { resolve } from 'path'; +import { marked } from 'marked'; + +export async function load() { + const about = readFileSync(resolve('static/about.md'), 'utf-8'); + const howToPlay = readFileSync(resolve('static/how-to-play.md'), 'utf-8'); + + return { + about: await marked(about), + howToPlay: await marked(howToPlay) + }; +} diff --git a/src/routes/about/+page.svelte b/src/routes/about/+page.svelte new file mode 100644 index 0000000..8b38c91 --- /dev/null +++ b/src/routes/about/+page.svelte @@ -0,0 +1,48 @@ + + About — Bibdle + + + + +
+
+ + + +
+ {#if aboutParts} + {@html aboutParts[0]} +
+ +
+ {@html aboutParts[1]} + {:else} + {@html data.about} + {/if} +
+ +
+ {@html data.howToPlay} +
+ +
+
diff --git a/src/routes/layout.css b/src/routes/layout.css index 99419b9..7b93d94 100644 --- a/src/routes/layout.css +++ b/src/routes/layout.css @@ -2,20 +2,31 @@ @import 'tailwindcss'; @plugin '@tailwindcss/typography'; +@custom-variant dark (&:where(.dark, .dark *)); + @theme { --font-triodion: "PT Serif", serif; } html, body { background: oklch(89.126% 0.06134 298.626); + transition: background 0.3s ease; } @media (prefers-color-scheme: dark) { - html, body { + html:not(.light), body:not(.light) { background: oklch(18% 0.03 298.626); } } +html.dark, html.dark body { + background: oklch(18% 0.03 298.626); +} + +html.light, html.light body { + background: oklch(89.126% 0.06134 298.626); +} + .big-text { font-size: 0.75rem; text-transform: uppercase; @@ -25,11 +36,19 @@ html, body { } @media (prefers-color-scheme: dark) { - .big-text { + html:not(.light) .big-text { color: rgb(156 163 175); } } +html.dark .big-text { + color: rgb(156 163 175); +} + +html.light .big-text { + color: rgb(107 114 128); +} + /* Page load animations */ @keyframes fadeInUp { from { @@ -60,4 +79,4 @@ html, body { .animate-delay-800 { animation-delay: 0.8s; -} \ No newline at end of file +} diff --git a/src/routes/sitemap.xml/+server.ts b/src/routes/sitemap.xml/+server.ts new file mode 100644 index 0000000..faee521 --- /dev/null +++ b/src/routes/sitemap.xml/+server.ts @@ -0,0 +1,23 @@ +import type { RequestHandler } from '@sveltejs/kit'; + +export const GET: RequestHandler = () => { + const sitemap = ` + + + https://bibdle.com/ + daily + 1.0 + + + https://bibdle.com/about + monthly + 0.5 + +`; + + return new Response(sitemap, { + headers: { + 'Content-Type': 'application/xml' + } + }); +}; diff --git a/static/about.md b/static/about.md new file mode 100644 index 0000000..6e01c35 --- /dev/null +++ b/static/about.md @@ -0,0 +1,15 @@ +# About Bibdle + +Bibdle is a daily Bible guessing game. Every day, a random verse is posted to the website. Try to figure out which book of the Bible it comes from, in as few guesses as possible. That's it! + +--- + +The game was built with the hope that it would be a small, delightful thing people can make part of their day. It's not a Bible study course. You don't need to know the Bible inside and out to enjoy it or to learn something from it. + +If you're someone who grew up in church and can name all 66 books in order, great. If you're someone who can barely tell the Old Testament from the New, that's great too. The game meets you where you are. + +It is completely free. If you'd like to support the developer (who works solely on small projects like this one) or express your thanks, you can become a Bibdle patron. + +If you use Bibdle, I would love to hear from you! I can be reached via email or through Bluesky. + + diff --git a/static/how-to-play.md b/static/how-to-play.md new file mode 100644 index 0000000..a3b88ca --- /dev/null +++ b/static/how-to-play.md @@ -0,0 +1,47 @@ +# How to Play + +Each day, Bibdle gives you a verse from the Bible. Your job is to guess which book it comes from. (Genesis, John, Corinthians, etc.) + +You have unlimited guesses. + +--- + +## The Basics + +1. **Read the verse.** It appears at the top of the page. +2. **Make a guess.** Type or select a book of the Bible from the list. +3. **Read the feedback.** After each guess, you'll get clues telling you how close you were. +4. **Keep guessing** until you get it right. + + +--- + +## Feedback Hints + +After each wrong guess, you'll see the following hints: + +| Hint | What it means | +|---|---| +| **Testament** | If your guess was in the correct Testament (Old or New) | +| **Section** | If your guess was in the correct section of the Bible (e.g. Gospels, Epistles, Major Prophets) | +| **First Letter** | If your guess has the same first letter as the correct guess | + +Use the hints to narrow down your search. + +--- + +## A Few Things to Know + +- **Everyone plays the same verse each day.** The daily verse resets at midnight. +- **Your progress is saved automatically.** You can close the tab and come back later. + +--- + +## Tips + +- Pay attention to writing style: the voice of Psalms is very different from Paul's letters. +- Historical narrative (battles, kings, genealogies) tends to be Old Testament. +- Short, poetic, or wisdom-focused verses could be Proverbs, Ecclesiastes, or Psalms. +- If a verse mentions Jesus by name, it's in the New Testament. + +Good luck! diff --git a/static/robots.txt b/static/robots.txt index b6dd667..44b881a 100644 --- a/static/robots.txt +++ b/static/robots.txt @@ -1,3 +1,5 @@ # allow crawling everything by default User-agent: * Disallow: + +Sitemap: https://bibdle.com/sitemap.xml diff --git a/todo.md b/todo.md index 638fe42..e8ef345 100644 --- a/todo.md +++ b/todo.md @@ -59,6 +59,12 @@ I created Bibdle from a combination of two things. The first is my lifelong desi # done +## march 12th + +- Added about page with social buttons and XML sitemap for SEO +- Fixed incorrect header background color on Desktop +- Added color theme toggle button (commented out for now) + ## feb 26th - Added dark mode