added copy verse text button

This commit is contained in:
George Powell
2026-02-22 22:50:28 -05:00
parent 3bcd7ea266
commit 1de436534c
2 changed files with 93 additions and 70 deletions

View File

@@ -1,73 +1,103 @@
<script lang="ts"> <script lang="ts">
import { browser } from "$app/environment"; import { browser } from "$app/environment";
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
import type { PageData } from "../../routes/$types.js"; // Approximate type; adjust if needed import type { PageData } from "../../routes/$types.js"; // Approximate type; adjust if needed
import Container from "./Container.svelte"; import Container from "./Container.svelte";
let { let {
data, data,
isWon, isWon,
blurChapter = false, blurChapter = false,
}: { data: PageData; isWon: boolean; blurChapter?: boolean } = $props(); }: { data: PageData; isWon: boolean; blurChapter?: boolean } = $props();
let dailyVerse = $derived(data.dailyVerse); let dailyVerse = $derived(data.dailyVerse);
let displayReference = $derived( let displayReference = $derived(
blurChapter blurChapter
? dailyVerse.reference ? dailyVerse.reference
.replace(/^Psalms /, "Psalm ") .replace(/^Psalms /, "Psalm ")
.replace(/\s(\d+):/, " ?:") .replace(/\s(\d+):/, " ?:")
: dailyVerse.reference.replace(/^Psalms /, "Psalm ") : dailyVerse.reference.replace(/^Psalms /, "Psalm "),
); );
let displayVerseText = $derived( let displayVerseText = $derived(
dailyVerse.verseText dailyVerse.verseText
.replace(/^([a-z])/, (c) => c.toUpperCase()) .replace(/^([a-z])/, (c) => c.toUpperCase())
.replace(/[,:;-—]$/, "...") .replace(/[,:;-—]$/, "..."),
); );
let showReference = $state(false); let showReference = $state(false);
let copied = $state(false);
// Delay showing reference until GuessesTable animation completes // Delay showing reference until GuessesTable animation completes
$effect(() => { $effect(() => {
if (!isWon) { if (!isWon) {
showReference = false; showReference = false;
return; return;
} }
// Check if user already won today (page reload case) // Check if user already won today (page reload case)
const winTrackedKey = `bibdle-win-tracked-${dailyVerse.date}`; const winTrackedKey = `bibdle-win-tracked-${dailyVerse.date}`;
const alreadyWonToday = browser && localStorage.getItem(winTrackedKey) === "true"; const alreadyWonToday =
browser && localStorage.getItem(winTrackedKey) === "true";
if (alreadyWonToday) { if (alreadyWonToday) {
// User already won and is refreshing - show immediately // User already won and is refreshing - show immediately
showReference = true; showReference = true;
} else { } else {
// User just won this session - delay for animation // User just won this session - delay for animation
const animationDelay = 1800; const animationDelay = 1800;
const timeoutId = setTimeout(() => { const timeoutId = setTimeout(() => {
showReference = true; showReference = true;
}, animationDelay); }, animationDelay);
return () => clearTimeout(timeoutId); return () => clearTimeout(timeoutId);
} }
}); });
function copyVerse() {
const fullReference = dailyVerse.reference.replace(
/^Psalms /,
"Psalm ",
);
const textToCopy = `"${displayVerseText}" — ${fullReference}`;
navigator.clipboard.writeText(textToCopy).then(() => {
copied = true;
(window as any).rybbit?.event("Copy Verse");
setTimeout(() => {
copied = false;
}, 2000);
});
}
</script> </script>
<Container class="w-full p-8 sm:p-12 bg-white/70 overflow-hidden"> <Container class="w-full p-8 sm:p-12 bg-white/70 overflow-hidden">
<blockquote <blockquote
class="text-xl sm:text-2xl font-triodion leading-relaxed text-gray-700 text-center" class="text-xl sm:text-2xl font-triodion leading-relaxed text-gray-700 text-center"
> >
{displayVerseText} {displayVerseText}
</blockquote> </blockquote>
<div <div
class="transition-all duration-500 ease-in-out overflow-hidden" class="transition-all duration-500 ease-in-out overflow-hidden"
style="max-height: {showReference ? '200px' : '0px'};" style="max-height: {showReference ? '200px' : '0px'};"
> >
{#if showReference} {#if showReference}
<p <p
transition:fade={{ duration: 400 }} transition:fade={{ duration: 400 }}
class="text-center text-lg! big-text text-green-600! font-bold mt-8 bg-white/70 rounded-xl px-4 py-2" class="text-center text-lg! big-text text-green-600! font-bold mt-8 bg-white/70 rounded-xl px-4 py-2"
> >
{displayReference} {displayReference}
</p> </p>
{/if} <div
</div> transition:fade={{ duration: 300 }}
class="flex justify-center mt-3"
>
<button
onclick={copyVerse}
data-umami-event="Copy Verse"
class="flex items-center gap-1.5 px-3 py-1.5 text-xs big-text text-gray-600 bg-white/50 hover:bg-white/70 border border-gray-300 rounded-lg transition-colors cursor-pointer"
>
{copied ? "✅" : "📋"}
{copied ? "Copied!" : "Copy verse to clipboard"}
</button>
</div>
{/if}
</div>
</Container> </Container>

View File

@@ -1,7 +1,6 @@
<script lang="ts"> <script lang="ts">
import { fade, fly } from "svelte/transition"; import { fade, fly } from "svelte/transition";
import { getBookById, toOrdinal } from "$lib/utils/game"; import { getBookById, toOrdinal } from "$lib/utils/game";
import { onMount } from "svelte";
import Container from "./Container.svelte"; import Container from "./Container.svelte";
import CountdownTimer from "./CountdownTimer.svelte"; import CountdownTimer from "./CountdownTimer.svelte";
import ChapterGuess from "./ChapterGuess.svelte"; import ChapterGuess from "./ChapterGuess.svelte";
@@ -475,12 +474,6 @@
padding-right: 32px; padding-right: 32px;
transform: rotate(-2deg); transform: rotate(-2deg);
transform-origin: right center; transform-origin: right center;
} margin-top: -6px;
.received-hint {
padding-right: 0;
padding-left: 32px;
transform: rotate(2deg);
transform-origin: left center;
} }
</style> </style>