1import { useEffect, useState } from "preact/hooks";23import { buildDailyPath, buildShareDailyStackText } from "@/lib/site/paths.ts";4import { getAchievedStackIndex } from "@/lib/storage/local_progress.ts";56interface ShareDailyStackButtonProps {7 date: string;8 class?: string;9}1011export default function ShareDailyStackButton(12 { date, class: className = "btn btn--ghost" }: ShareDailyStackButtonProps,13) {14 const [stackIndex, setStackIndex] = useState(0);15 const [origin, setOrigin] = useState("");16 const [copied, setCopied] = useState(false);1718 useEffect(() => {19 setOrigin(globalThis.location.origin);20 setStackIndex(getAchievedStackIndex(globalThis.localStorage, date));21 }, [date]);2223 const shareUrl = origin ? `${origin}${buildDailyPath(date, stackIndex)}` : "";24 const shareText = origin25 ? buildShareDailyStackText(origin, date, stackIndex)26 : "Daily stack";2728 async function handleShare() {29 if (!shareUrl) return;3031 try {32 if (navigator.share) {33 await navigator.share({34 title: "rect.run",35 text: shareText,36 url: shareUrl,37 });38 return;39 }4041 await navigator.clipboard.writeText(shareUrl);42 setCopied(true);43 setTimeout(() => setCopied(false), 1500);44 } catch {45 // ignore user-cancelled share errors and clipboard failures46 }47 }4849 return (50 <button class={className} type="button" onClick={handleShare}>51 {copied ? "COPIED" : "SHARE"}52 </button>53 );54}