From b5fe3f6cc8e6825703926a1a469926c10ade2de4 Mon Sep 17 00:00:00 2001 From: kurihada Date: Tue, 24 Feb 2026 19:39:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8C=B9=E9=85=8D=E7=BB=93=E6=9E=9C?= =?UTF-8?q?=E9=A1=B5=E5=A2=9E=E5=8A=A0"=E5=88=86=E4=BA=AB=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=E5=88=B0=E7=BE=A4=E9=87=8C"=E6=8C=89=E9=92=AE?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=20Web=20Share=20=E5=92=8C=E5=89=AA?= =?UTF-8?q?=E8=B4=B4=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MatchResult.tsx | 68 +++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/src/components/MatchResult.tsx b/src/components/MatchResult.tsx index 243a0ee..0174638 100644 --- a/src/components/MatchResult.tsx +++ b/src/components/MatchResult.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState } from "react"; +import { useState, useCallback } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { useRouter } from "next/navigation"; import { @@ -17,6 +17,7 @@ import { ChevronDown, Swords, RefreshCw, + Share2, } from "lucide-react"; import { Restaurant, MatchType, RunnerUp } from "@/types"; @@ -171,6 +172,48 @@ export default function MatchResult({ }: MatchResultProps) { const router = useRouter(); const [showRunnerUps, setShowRunnerUps] = useState(false); + const [toast, setToast] = useState(""); + + const showToast = useCallback((msg: string) => { + setToast(msg); + setTimeout(() => setToast(""), 2200); + }, []); + + const handleShare = useCallback(async () => { + const lines = [ + `🎉 我们用 NoWhatever 选好了!`, + ``, + `📍 ${restaurant.name}`, + restaurant.rating ? `⭐ ${restaurant.rating}` : "", + restaurant.price && restaurant.price !== "未知" ? `💰 人均${restaurant.price}` : "", + restaurant.address ? `📮 ${restaurant.address}` : "", + ].filter(Boolean); + + const text = lines.join("\n"); + const navUrl = buildNavUrl(restaurant); + + const shareData = { + title: `我们选了${restaurant.name}!`, + text, + url: navUrl, + }; + + try { + if (navigator.share && navigator.canShare?.(shareData)) { + await navigator.share(shareData); + return; + } + } catch (e) { + if (e instanceof Error && e.name === "AbortError") return; + } + + try { + await navigator.clipboard.writeText(`${text}\n\n${navUrl}`); + showToast("已复制,快去发给朋友吧!"); + } catch { + showToast("复制失败,请手动复制"); + } + }, [restaurant, showToast]); if (matchType === "no_match") { return ; @@ -334,6 +377,15 @@ export default function MatchResult({ 打电话订位 )} + + + + 分享结果到群里 + {!isUnanimous && runnerUpRestaurants.length > 0 && ( @@ -428,6 +480,20 @@ export default function MatchResult({ )} + + + {toast && ( + + {toast} + + )} + ); }