diff --git a/js/app/src/polyfills.tsx b/js/app/src/polyfills.tsx index e69de29b..e213a2d7 100644 --- a/js/app/src/polyfills.tsx +++ b/js/app/src/polyfills.tsx @@ -0,0 +1,6 @@ +import { initializeTimeSync } from "@streamplace/components"; + +// Install the Date monkeypatch before React mounts so that all subsequent +// `new Date()` / `Date.now()` calls account for server clock offset. +// No-op on non-web platforms. +initializeTimeSync(); diff --git a/js/components/src/index.tsx b/js/components/src/index.tsx index 3ff10fed..0f119813 100644 --- a/js/components/src/index.tsx +++ b/js/components/src/index.tsx @@ -65,6 +65,10 @@ export * from "./components/share/sharesheet"; export * from "./components/keep-awake"; +// Time sync — installs a Date monkeypatch that corrects for server clock +// offset. Must be called once on web before any time-sensitive code runs. +export { initializeTimeSync } from "./time-sync"; + // Dashboard components export * as Dashboard from "./components/dashboard"; diff --git a/js/components/src/time-sync/time-sync.ts b/js/components/src/time-sync/time-sync.ts index bffb239c..fcf29cbe 100644 --- a/js/components/src/time-sync/time-sync.ts +++ b/js/components/src/time-sync/time-sync.ts @@ -3,8 +3,9 @@ import { Platform } from "react-native"; let timeOffset = 0; let hasWarned = false; let OriginalDate: DateConstructor = Date; +let isInitialized = false; -const CLOCK_DRIFT_THRESHOLD_MS = 5000; // 5 seconds +const CLOCK_DRIFT_THRESHOLD_MS = 60 * 60 * 1000; // 1 hour export function getTimeOffset(): number { return timeOffset; @@ -19,8 +20,8 @@ export function checkClockDrift(serverTime: string): { driftMs: number; driftSeconds: number; } { - const serverDate = new Date(serverTime); - const clientDate = new Date(); + const serverDate = new OriginalDate(serverTime); + const clientDate = new OriginalDate(); const drift = Math.abs(serverDate.getTime() - clientDate.getTime()); if (drift > CLOCK_DRIFT_THRESHOLD_MS) { @@ -55,11 +56,10 @@ export function syncTimeWithServer( } export function getSyncedDate(): Date { - const now = new Date(); if (timeOffset !== 0) { - return new Date(now.getTime() + timeOffset); + return new Date(OriginalDate.now() + timeOffset); } - return now; + return new OriginalDate(); } export function getSystemDate(): Date { @@ -71,6 +71,11 @@ export function getSystemTime(): number { } export function initializeTimeSync(): void { + if (isInitialized) { + return; + } + isInitialized = true; + if (Platform.OS !== "web") { return; } diff --git a/js/components/src/time-sync/useTimeSync.tsx b/js/components/src/time-sync/useTimeSync.tsx index dc0c3c23..929650dc 100644 --- a/js/components/src/time-sync/useTimeSync.tsx +++ b/js/components/src/time-sync/useTimeSync.tsx @@ -35,7 +35,7 @@ export function useTimeSync() { hasShownWarning.current = true; t.show( "Clock drift detected!", - `Your device clock is ${driftInfo.driftSeconds}s off from server time. Please sync your system clock to avoid issues.`, + `Your device clock is ${driftInfo.driftSeconds}s off from server time. Times have been auto-corrected, but please sync your system clock.`, { variant: "info", iconLeft: TriangleAlert,