refactor: Toast 升级为全局 Context,消除 onToast prop 透传

将 useToast 从独立 state hook 改为 Context-based,在 layout 中
挂载 ToastProvider 全局渲染 Toast。QrInviteModal、RoomManageModal、
ShareCardModal 不再需要 onToast prop,直接 useToast() 调用即可。
父组件 TopNav、MatchResult、profile、blindbox 移除了本地 Toast
渲染和 onToast 传递逻辑。
This commit is contained in:
2026-02-26 17:57:34 +08:00
parent b98920858c
commit d4c6da57a1
10 changed files with 68 additions and 55 deletions
+8 -8
View File
@@ -6,6 +6,7 @@ import { X, Download, Share2, Loader2, Star, MapPin, Zap } from "lucide-react";
import { QRCodeSVG } from "qrcode.react";
import { toPng } from "html-to-image";
import type { Restaurant, MatchType, SceneType } from "@/types";
import { useToast } from "@/hooks/useToast";
type ShareCardData =
| {
@@ -28,7 +29,6 @@ interface ShareCardModalProps {
open: boolean;
onClose: () => void;
data: ShareCardData;
onToast?: (msg: string) => void;
}
async function loadImageAsDataUrl(src: string): Promise<string | null> {
@@ -775,8 +775,8 @@ export default function ShareCardModal({
open,
onClose,
data,
onToast,
}: ShareCardModalProps) {
const toast = useToast();
const cardRef = useRef<HTMLDivElement>(null);
const backdropRef = useRef<HTMLDivElement>(null);
const [generating, setGenerating] = useState(false);
@@ -821,7 +821,7 @@ export default function ShareCardModal({
const handleSave = useCallback(async () => {
const png = await handleGenerate();
if (!png) {
onToast?.("生成图片失败,请重试");
toast.show("生成图片失败,请重试");
return;
}
const name =
@@ -829,13 +829,13 @@ export default function ShareCardModal({
? `NoWhatever_${data.restaurant.name}.png`
: `NoWhatever_周末契约.png`;
downloadDataUrl(png, name);
onToast?.("图片已保存");
}, [handleGenerate, onToast, data]);
toast.show("图片已保存");
}, [handleGenerate, toast, data]);
const handleShare = useCallback(async () => {
const png = await handleGenerate();
if (!png) {
onToast?.("生成图片失败,请重试");
toast.show("生成图片失败,请重试");
return;
}
@@ -852,8 +852,8 @@ export default function ShareCardModal({
}
downloadDataUrl(png, "NoWhatever.png");
onToast?.("图片已保存,快去分享吧!");
}, [handleGenerate, onToast]);
toast.show("图片已保存,快去分享吧!");
}, [handleGenerate, toast]);
const handleBackdropClick = (e: React.MouseEvent) => {
if (e.target === backdropRef.current) onClose();