"use client"; import { useEffect, type ReactNode } from "react"; import type { Data } from "@/server/services/model"; import { initializeTracker, navigation, pageClick, pageView, externalAd, tracker, track, type TrackerBoot, } from "./tracker"; function loadScript(src: string): Promise { return new Promise((resolve) => { const existing = document.querySelector( `script[src="${src}"]`, ); if (existing) { resolve(); return; } const script = document.createElement("script"); script.src = src; script.async = true; script.onload = () => resolve(); script.onerror = () => resolve(); document.head.append(script); }); } export function TrackerProvider({ data, children, boot: explicitBoot, }: { data?: Data; boot?: TrackerBoot; children?: ReactNode; }) { useEffect(() => { let disposed = false; const boot: TrackerBoot = explicitBoot || { appId: String(data?.trackerAppId || ""), encryptedConfig: data?.reportSdkConfig ?? data?.appConfig?.reportSdkConfig ?? data?.appConfig?.ReportSDKConfig ?? data?.appConfig?.reportSDKConfig, appVersion: "1.0.0", pageKey: data?.pageKey, pageName: data?.pageName, userType: data?.isVip ? "vip" : "normal", uid: String(data?.userID || data?.userId || ""), channel: data?.channel, }; void loadScript("/static/common/web-sdk-v1.2.0.js?v=huakui-20261013-system") .then(() => initializeTracker(boot)) .then(() => { if (!disposed) pageView(); }); const google = "G-J58C18CTS0"; const yandex = data?.isNavPage || data?.requestPath === "/navigation/" ? 112952789 : 112951899; window.dataLayer ||= []; window.gtag ||= (...args) => { window.dataLayer!.push(args); }; window.gtag("js", new Date()); window.gtag("config", google); void loadScript(`https://www.googletagmanager.com/gtag/js?id=${google}`); window.ym ||= Object.assign( (...args: unknown[]) => { window.ym!.a!.push(args); }, { a: [] as unknown[][], l: Date.now() }, ); window.ym(yandex, "init", { ssr: true, webvisor: true, clickmap: true, ecommerce: "dataLayer", referrer: document.referrer, url: location.href, accurateTrackBounce: true, trackLinks: true, }); void loadScript(`https://mc.yandex.ru/metrika/tag.js?id=${yandex}`); const click = (event: MouseEvent) => { if (!(event.target instanceof Element)) return; const target = event.target; if ( !target.closest( "[data-ad-close],[data-dialog-ad-close],[data-download-close],[data-login-close],[data-register-close],[data-recharge-close],[data-play-coin-close],[data-setting-password-close],[data-drawer-close]", ) ) pageClick(event); const anchor = target.closest( "a[data-navigation-key],a[data-nav-key]", ); if (anchor) navigation(anchor); const ad = target.closest( '[data-track-ad="external"][data-ad-id]', ); if (ad) externalAd(ad, "click"); }; document.addEventListener("click", click, true); const observer = typeof IntersectionObserver === "undefined" ? null : new IntersectionObserver( (entries) => { for (const entry of entries) if (entry.isIntersecting) { externalAd(entry.target as HTMLElement, "show"); observer?.unobserve(entry.target); } }, { threshold: 0.1 }, ); const observed = new WeakSet(); const observe = () => document .querySelectorAll( '[data-track-ad="external"][data-ad-id]:not([data-ad-clone])', ) .forEach((node) => { if (!observed.has(node)) { observed.add(node); if (observer) observer.observe(node); else externalAd(node as HTMLElement, "show"); } }); observe(); const mutations = new MutationObserver(observe); mutations.observe(document.body, { childList: true, subtree: true }); const external = (event: Event) => { const detail = ( event as CustomEvent<{ element: HTMLElement; eventType: string }> ).detail; if (detail?.element) externalAd(detail.element, detail.eventType); }; const advertising = (event: Event) => { const detail = ( event as CustomEvent<{ element: HTMLElement; eventType: string }> ).detail; const node = detail?.element; if (node) void track("advertising", { event_type: detail.eventType, advertising_key: node.dataset.advertisingKey || "dialog_ad", advertising_name: node.dataset.advertisingName || "弹窗广告", advertising_id: node.dataset.advertisingId || node.dataset.dialogAdId || "", }); }; document.addEventListener("external-ad:track", external); document.addEventListener("dialog-ad:track", advertising); const flush = () => { void tracker.flush(); }; window.addEventListener("pagehide", flush); return () => { disposed = true; observer?.disconnect(); mutations.disconnect(); document.removeEventListener("click", click, true); document.removeEventListener("external-ad:track", external); document.removeEventListener("dialog-ad:track", advertising); window.removeEventListener("pagehide", flush); }; }, [data, explicitBoot]); return children; } export function useTracker() { return tracker; } export default TrackerProvider;