| | |
| | | import { useEffect, useRef, useState } from 'react'; |
| | | import wsManager from '../../../../utils/websocket'; |
| | | |
| | | type CouponMessagePayload = { |
| | | content?: any; |
| | | }; |
| | | import { getFirstToastEnter } from '../../../../robotaxi/api/coupon'; |
| | | |
| | | /** |
| | | * 首页优惠券消息 WebSocket 监听。 |
| | | * 首页优惠券消息提示。 |
| | | */ |
| | | export default function useCouponMessageWs() { |
| | | const [couponMessageContent, setCouponMessageContent] = useState(''); // 当前展示的消息文案 |
| | | const [showCouponMessage, setShowCouponMessage] = useState(false); // 是否展示消息提示 |
| | | const couponMessageTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null); // 自动关闭定时器 |
| | | const couponMessageBoundRef = useRef(false); // 当前页面是否已绑定消息监听 |
| | | |
| | | const clearCouponMessageTimer = () => { |
| | | if (couponMessageTimerRef.current) { |
| | |
| | | } |
| | | }; |
| | | |
| | | const resolveCouponMessageText = (payload?: CouponMessagePayload) => { |
| | | const rawContent = payload?.content; |
| | | if (typeof rawContent === 'string') { |
| | | useEffect(() => { |
| | | const fetchFirstToast = async () => { |
| | | try { |
| | | const parsedContent = JSON.parse(rawContent); |
| | | if (parsedContent && typeof parsedContent?.content === 'string') { |
| | | return parsedContent.content; |
| | | const res = await getFirstToastEnter(); |
| | | if (res && typeof res === 'string' && res.trim()) { |
| | | setCouponMessageContent(res.trim()); |
| | | setShowCouponMessage(true); |
| | | clearCouponMessageTimer(); |
| | | // 新消息到达时重置倒计时,保证每条消息都完整展示 3 秒 |
| | | couponMessageTimerRef.current = setTimeout(() => { |
| | | setShowCouponMessage(false); |
| | | couponMessageTimerRef.current = null; |
| | | }, 3000); |
| | | } |
| | | } catch (error) { |
| | | console.error('获取首页toast提示失败', error); |
| | | } |
| | | return rawContent; |
| | | } |
| | | if (rawContent && typeof rawContent?.content === 'string') { |
| | | return rawContent.content; |
| | | } |
| | | return ''; |
| | | }; |
| | | |
| | | useEffect(() => { |
| | | const couponMessageHandler = (payload?: CouponMessagePayload) => { |
| | | const nextContent = resolveCouponMessageText(payload).trim(); |
| | | if (!nextContent) { |
| | | return; |
| | | } |
| | | setCouponMessageContent(nextContent); |
| | | setShowCouponMessage(true); |
| | | clearCouponMessageTimer(); |
| | | // 新消息到达时重置倒计时,保证每条消息都完整展示 3 秒 |
| | | couponMessageTimerRef.current = setTimeout(() => { |
| | | setShowCouponMessage(false); |
| | | couponMessageTimerRef.current = null; |
| | | }, 3000); |
| | | }; |
| | | if (!couponMessageBoundRef.current) { |
| | | wsManager.on('COUPON_MESSAGE', couponMessageHandler); |
| | | couponMessageBoundRef.current = true; |
| | | } |
| | | |
| | | fetchFirstToast(); |
| | | |
| | | return () => { |
| | | clearCouponMessageTimer(); |
| | | if (couponMessageBoundRef.current) { |
| | | wsManager.off('COUPON_MESSAGE', couponMessageHandler); |
| | | couponMessageBoundRef.current = false; |
| | | } |
| | | }; |
| | | }, []); |
| | | |