From d9bd48a66571529b451b6c20b9e47db5ec2bae91 Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Wed, 16 Apr 2025 20:45:59 -0600 Subject: [PATCH] detect region --- src/index.tsx | 4 +++ src/utils/detectRegion.tsx | 69 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/utils/detectRegion.tsx diff --git a/src/index.tsx b/src/index.tsx index 1ef9d409..4a531912 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -29,6 +29,7 @@ import { changeAppLanguage, useLanguageStore } from "@/stores/language"; import { ProgressSyncer } from "@/stores/progress/ProgressSyncer"; import { SettingsSyncer } from "@/stores/subtitles/SettingsSyncer"; import { ThemeProvider } from "@/stores/theme"; +import { detectRegion, useRegionStore } from "@/utils/detectRegion"; import { extensionInfo, @@ -136,6 +137,9 @@ function MigrationRunner() { const status = useAsync(async () => { changeAppLanguage(useLanguageStore.getState().language); await initializeOldStores(); + + const region = await detectRegion(); + useRegionStore.getState().setRegion(region); }, []); const { t } = useTranslation(); diff --git a/src/utils/detectRegion.tsx b/src/utils/detectRegion.tsx new file mode 100644 index 00000000..6e9c16c2 --- /dev/null +++ b/src/utils/detectRegion.tsx @@ -0,0 +1,69 @@ +import { create } from "zustand"; +import { persist } from "zustand/middleware"; + +export type Region = + | "us-east" + | "us-west" + | "south-america" + | "asia" + | "europe" + | "unknown"; + +interface RegionStore { + region: Region | null; + lastChecked: number | null; + setRegion: (region: Region) => void; +} + +const TEN_DAYS_MS = 10 * 24 * 60 * 60 * 1000; + +export const useRegionStore = create()( + persist( + (set) => ({ + region: null, + lastChecked: null, + setRegion: (region) => set({ region, lastChecked: Date.now() }), + }), + { + name: "__MW::region", + }, + ), +); + +function determineRegion(data: { + latitude: number; + longitude: number; + country_code: string; +}): Region { + const { latitude, longitude, country_code: country } = data; + + if (country === "US") return longitude < -100 ? "us-west" : "us-east"; + if (latitude < 0) return "south-america"; + if (longitude > 60) return "asia"; + if (longitude > -10) return "europe"; + return "us-east"; +} + +export async function detectRegion(): Promise { + const store = useRegionStore.getState(); + + if ( + store.region && + store.lastChecked && + Date.now() - store.lastChecked < TEN_DAYS_MS + ) { + return store.region; + } + + try { + const response = await fetch("https://ipapi.co/json/"); + const data = await response.json(); + + const detectedRegion = determineRegion(data); + store.setRegion(detectedRegion); // Persist the detected region + return detectedRegion; + } catch (error) { + console.warn("Failed to detect region:", error); + return store.region || "unknown"; + } +}