mirror of
https://github.com/pupperpowell/bibdle.git
synced 2026-04-05 17:33:31 -04:00
added toggle verse display and fixed timer spacing
This commit is contained in:
@@ -73,7 +73,7 @@
|
|||||||
Next Verse In
|
Next Verse In
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
class="text-4xl font-triodion font-black text-gray-800 tabular-nums"
|
class="text-4xl font-triodion font-black text-gray-800 tabular-nums whitespace-nowrap"
|
||||||
>
|
>
|
||||||
{timeUntilNext}
|
{timeUntilNext}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
<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 {
|
||||||
|
getVerseSnippet,
|
||||||
|
shareResult,
|
||||||
|
copyToClipboard as clipboardCopy,
|
||||||
|
} from "$lib/utils/share";
|
||||||
import Container from "./Container.svelte";
|
import Container from "./Container.svelte";
|
||||||
import CountdownTimer from "./CountdownTimer.svelte";
|
import CountdownTimer from "./CountdownTimer.svelte";
|
||||||
import StreakCounter from "./StreakCounter.svelte";
|
import StreakCounter from "./StreakCounter.svelte";
|
||||||
@@ -31,6 +36,7 @@
|
|||||||
reference,
|
reference,
|
||||||
onChapterGuessCompleted,
|
onChapterGuessCompleted,
|
||||||
shareText,
|
shareText,
|
||||||
|
verseText,
|
||||||
streak = 0,
|
streak = 0,
|
||||||
streakPercentile = null,
|
streakPercentile = null,
|
||||||
}: {
|
}: {
|
||||||
@@ -44,6 +50,7 @@
|
|||||||
reference: string;
|
reference: string;
|
||||||
onChapterGuessCompleted: () => void;
|
onChapterGuessCompleted: () => void;
|
||||||
shareText: string;
|
shareText: string;
|
||||||
|
verseText: string;
|
||||||
streak?: number;
|
streak?: number;
|
||||||
streakPercentile?: number | null;
|
streakPercentile?: number | null;
|
||||||
} = $props();
|
} = $props();
|
||||||
@@ -55,6 +62,22 @@
|
|||||||
let copySuccess = $state(false);
|
let copySuccess = $state(false);
|
||||||
let bubbleCopied = $state(false);
|
let bubbleCopied = $state(false);
|
||||||
let copyTracked = $state(false);
|
let copyTracked = $state(false);
|
||||||
|
let showSnippetOption = $state(false);
|
||||||
|
let includeSnippet = $state(false);
|
||||||
|
|
||||||
|
let effectiveShareText = $derived(
|
||||||
|
includeSnippet
|
||||||
|
? (() => {
|
||||||
|
const snippet = getVerseSnippet(verseText);
|
||||||
|
const lines = shareText.split("\n");
|
||||||
|
return [
|
||||||
|
...lines.slice(0, -1),
|
||||||
|
snippet,
|
||||||
|
lines[lines.length - 1],
|
||||||
|
].join("\n");
|
||||||
|
})()
|
||||||
|
: shareText,
|
||||||
|
);
|
||||||
|
|
||||||
// List of congratulations messages with weights
|
// List of congratulations messages with weights
|
||||||
const congratulationsMessages: WeightedMessage[] = [
|
const congratulationsMessages: WeightedMessage[] = [
|
||||||
@@ -132,11 +155,11 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="flex flex-row gap-3 items-stretch w-full">
|
<div class="flex flex-row gap-3 items-stretch w-full">
|
||||||
<div class="flex-[2] min-w-0 flex flex-col">
|
<div class="flex-2 min-w-0 flex flex-col">
|
||||||
<CountdownTimer />
|
<CountdownTimer />
|
||||||
</div>
|
</div>
|
||||||
{#if streak > 0}
|
{#if streak > 0}
|
||||||
<div class="flex-[1] min-w-0 flex flex-col">
|
<div class="flex-1 min-w-0 flex flex-col">
|
||||||
<StreakCounter {streak} {streakPercentile} />
|
<StreakCounter {streak} {streakPercentile} />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -224,7 +247,7 @@
|
|||||||
onclick={() => {
|
onclick={() => {
|
||||||
if (hasWebShare) {
|
if (hasWebShare) {
|
||||||
(window as any).rybbit?.event("Share");
|
(window as any).rybbit?.event("Share");
|
||||||
handleShare();
|
shareResult(effectiveShareText);
|
||||||
} else {
|
} else {
|
||||||
if (!copyTracked) {
|
if (!copyTracked) {
|
||||||
(window as any).rybbit?.event(
|
(window as any).rybbit?.event(
|
||||||
@@ -232,7 +255,7 @@
|
|||||||
);
|
);
|
||||||
copyTracked = true;
|
copyTracked = true;
|
||||||
}
|
}
|
||||||
copyToClipboard();
|
clipboardCopy(effectiveShareText);
|
||||||
copySuccess = true;
|
copySuccess = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
copySuccess = false;
|
copySuccess = false;
|
||||||
@@ -261,12 +284,13 @@
|
|||||||
(window as any).rybbit?.event("Copy to Clipboard");
|
(window as any).rybbit?.event("Copy to Clipboard");
|
||||||
copyTracked = true;
|
copyTracked = true;
|
||||||
}
|
}
|
||||||
copyToClipboard();
|
clipboardCopy(effectiveShareText);
|
||||||
|
showSnippetOption = true;
|
||||||
bubbleCopied = true;
|
bubbleCopied = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
bubbleCopied = false;
|
bubbleCopied = false;
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}}>{shareText}</button
|
}}>{effectiveShareText}</button
|
||||||
>
|
>
|
||||||
{#if hasWebShare}
|
{#if hasWebShare}
|
||||||
<span class="copy-hint"
|
<span class="copy-hint"
|
||||||
@@ -280,6 +304,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{#if showSnippetOption}
|
||||||
|
<div class="snippet-toggle-row mr-4" in:fly={{ y: -8, duration: 220 }}>
|
||||||
|
<span class="snippet-label">Show verse snippet in share?</span>
|
||||||
|
<button
|
||||||
|
class="snippet-toggle"
|
||||||
|
class:on={includeSnippet}
|
||||||
|
onclick={() => (includeSnippet = !includeSnippet)}
|
||||||
|
aria-pressed={includeSnippet}
|
||||||
|
aria-label="Show snippet in share"
|
||||||
|
>
|
||||||
|
<span class="toggle-thumb"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@@ -485,4 +524,53 @@
|
|||||||
transform-origin: right center;
|
transform-origin: right center;
|
||||||
margin-top: -6px;
|
margin-top: -6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Snippet toggle row ── */
|
||||||
|
.snippet-toggle-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.snippet-label {
|
||||||
|
font-size: 0.72rem;
|
||||||
|
color: #666;
|
||||||
|
letter-spacing: 0.01em;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.snippet-toggle {
|
||||||
|
position: relative;
|
||||||
|
width: 36px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #ccc;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 200ms ease;
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.snippet-toggle.on {
|
||||||
|
background: #34c759;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-thumb {
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
left: 2px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: white;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
||||||
|
transition: transform 200ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.snippet-toggle.on .toggle-thumb {
|
||||||
|
transform: translateX(16px);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import type { SHA512_256 } from '@oslojs/crypto/sha2';
|
|
||||||
import type { Guess } from './game';
|
import type { Guess } from './game';
|
||||||
|
|
||||||
export function getVerseSnippet(verseText: string): string {
|
export function getVerseSnippet(verseText: string): string {
|
||||||
@@ -16,8 +15,8 @@ export function getVerseSnippet(verseText: string): string {
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
const start = posAfterWord(10);
|
const start = posAfterWord(9);
|
||||||
const end = posAfterWord(18);
|
const end = posAfterWord(25);
|
||||||
|
|
||||||
// Find first punctuation mark between words 10 and 25
|
// Find first punctuation mark between words 10 and 25
|
||||||
const range = text.substring(start, end);
|
const range = text.substring(start, end);
|
||||||
|
|||||||
@@ -319,6 +319,7 @@
|
|||||||
reference={dailyVerse.reference}
|
reference={dailyVerse.reference}
|
||||||
onChapterGuessCompleted={persistence.onChapterGuessCompleted}
|
onChapterGuessCompleted={persistence.onChapterGuessCompleted}
|
||||||
shareText={getShareText()}
|
shareText={getShareText()}
|
||||||
|
verseText={dailyVerse.verseText}
|
||||||
{streak}
|
{streak}
|
||||||
{streakPercentile}
|
{streakPercentile}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user