| | |
| | | /** 修改目的地预览态和接驾态切路线期间隐藏车辆公里/分钟气泡。 */ |
| | | const shouldShowVehicleMetricCallout = |
| | | !deps.isModifyDestinationReviewVisible && !deps.isPickupRouteChangeVisible; |
| | | const shouldHideAndroidMarkerCallout = |
| | | deps.isAndroid && |
| | | ([ |
| | | TripStatus.PublishRoute, |
| | | TripStatus.VehicleArrivedPickup, |
| | | TripStatus.TripFinished, |
| | | TripStatus.PaymentSuccess, |
| | | TripStatus.CancelOnlyPickup |
| | | ].includes(deps.tripStatus) || |
| | | deps.isPickupRouteChangeVisible); // Android 指定状态下隐藏常规 marker 气泡 |
| | | const androidCarCalloutContent = useMemo( |
| | | () => ( |
| | | <AndroidCarCalloutContent |
| | |
| | | ); |
| | | |
| | | /** |
| | | * Android 上车点/下车点气泡(customCallout)偶现不绘制,需拖动/缩放/点击后才出现; |
| | | * 修改目的地预览态下下车点切换为目的地黑色浮窗(endpoint-summary)内容时同样会复现该问题。 |
| | | * Android 接驾态(VehicleApproaching)上车点气泡(customCallout)偶现不绘制,需拖动/缩放/点击后才出现。 |
| | | * 在 markers 更新后微调气泡外层(透明容器,无可见样式)的 borderRadius,触发原生地图对该 cover-view 的回流重绘。 |
| | | * 该重绘样式(calloutRepaintStyle)应用在 item.id === 1(上车点)和 item.id === 2(下车点)两处 marker 的 |
| | | * customCallout 根节点上,覆盖两者各自在不同状态下的内容渲染。 |
| | | * |
| | | * iOS 不再做任何 borderRadius 重绘:根因是 translateMarker 平移车标时会丢弃同屏 customCallout; |
| | | * 车辆 customCallout 不能靠周期重绘兜底——实测周期重绘会让气泡每 ~1.5s 闪一下(重绘 churn 本身致闪)。 |
| | | * 因此该重绘仅保留给 Android。 |
| | | * iOS 不再做任何 borderRadius 重绘:根因是 translateMarker 平移车标时会丢弃同屏 customCallout, |
| | | * 上车点已改为原生 callout(见 use-map-markers,不受影响);车辆 customCallout 不能靠周期重绘兜底—— |
| | | * 实测周期重绘会让气泡每 ~1.5s 闪一下(重绘 churn 本身致闪)。因此该重绘仅保留给 Android。 |
| | | */ |
| | | const [calloutRepaintStyle, setCalloutRepaintStyle] = useState<{ |
| | | borderRadius: string; |
| | |
| | | // 这两个状态切换时 customCallout 内容会切成目的地黑色浮窗(endpoint-summary), |
| | | // 但 marker 的 id/name(markersRepaintSignature)和 tripStatus 通常不变, |
| | | // 若不监听会导致本次内容切换错过重绘时机,出现"气泡背景已渲染但内部文字未绘制"。 |
| | | // 依赖里还加入 routeDistance / routeDuration:endpoint-summary 内容(全程XX公里XX分钟) |
| | | // 需要这两个值都非 null 才会渲染。页面首次进入 PublishRoute 态或从终点选点页 |
| | | // reLaunch 回来后,这两个值初始为 null,customCallout 首次绘制时内容判断为空; |
| | | // 待 routeRequestRouteAndFare 异步拿到真实值后才变为非 null,但若不监听这次变化, |
| | | // 就会错过重绘时机,导致气泡背景已渲染、内部文字和图标却始终停留在最初的空状态。 |
| | | |
| | | if (!deps.isAndroid) { |
| | | return undefined; |
| | | } |
| | |
| | | deps.isAndroid, |
| | | deps.isModifyDestinationReviewVisible, |
| | | deps.isPickupRouteChangeVisible, |
| | | deps.routeDistance, |
| | | deps.routeDuration, |
| | | toggleCalloutRepaint |
| | | ]); |
| | | |
| | |
| | | } |
| | | ` |
| | | } |
| | | style={(item.id === 1 || item.id === 2) ? calloutRepaintStyle : undefined} |
| | | style={item.id === 1 ? calloutRepaintStyle : undefined} |
| | | > |
| | | {item.isBeforeUserSite ? ( |
| | | <CoverView className="before-user-site-callout"> |
| | |
| | | const renderMarkerCallout = useCallback((item: any, index: number) => { |
| | | // 故将会变化的限停时长纳入 key,数值变化时强制整体重新挂载而非原地 patch。 |
| | | const calloutKey = `callout-${item.id}-${item.name || ''}-${deps.startSite?.time ?? ''}-${deps.isAndroid}`; |
| | | // 待支付/完成态的上/下车点浮窗为富内容(end-site 图片),需走 cover-view,不能被 Android 常规隐藏规则误伤 |
| | | const isSettledSiteMarker = |
| | | (item.id === 1 || item.id === 2) && |
| | | [TripStatus.TripFinished, TripStatus.PaymentSuccess].includes(deps.tripStatus); |
| | | // 到达上车点态的上车点倒计时浮窗(cover-view),同样需放开 |
| | | const isArrivedPickupMarker = |
| | | item.id === 1 && deps.tripStatus === TripStatus.VehicleArrivedPickup; |
| | | if (shouldHideAndroidMarkerCallout && !item.isBeforeUserSite && !isSettledSiteMarker && !isArrivedPickupMarker) return null; |
| | | const isWaiting = [TripStatus.Publishing, TripStatus.CallingCar].includes(deps.tripStatus) && index === 0; |
| | | if (isWaiting) return renderWaitingCallout(item, calloutKey); |
| | | // 车辆里程气泡:两端都不再用 marker customCallout 渲染。 |
| | |
| | | // 均规避被 translateMarker 丢弃(customCallout 在 iOS translate 下接驾/送驾都会偶发丢失)。 |
| | | if (item.name === '车辆位置' && [TripStatus.VehicleApproaching, TripStatus.InService].includes(deps.tripStatus)) return null; |
| | | return renderDefaultCallout(item, calloutKey); |
| | | }, [deps.isAndroid, deps.tripStatus, renderDefaultCallout, renderWaitingCallout, deps.startSite?.time]); |
| | | }, [deps.isAndroid, deps.tripStatus, renderDefaultCallout, renderWaitingCallout, shouldHideAndroidMarkerCallout, deps.startSite?.time]); |
| | | |
| | | /** |
| | | * 渲染地图覆盖层。 |