Retry homepage city loading
This commit is contained in:
@@ -101,8 +101,13 @@ function getInitialProAccessState(): ProAccessState {
|
|||||||
|
|
||||||
const SELECTED_CITY_STORAGE_KEY = "polyWeather_selected_city_v1";
|
const SELECTED_CITY_STORAGE_KEY = "polyWeather_selected_city_v1";
|
||||||
const BACKGROUND_SUMMARY_REFRESH_MS = 30_000;
|
const BACKGROUND_SUMMARY_REFRESH_MS = 30_000;
|
||||||
|
const CITY_LOAD_RETRY_DELAYS_MS = [700, 1600];
|
||||||
type CityDetailDepth = "panel" | "market" | "nearby" | "full";
|
type CityDetailDepth = "panel" | "market" | "nearby" | "full";
|
||||||
|
|
||||||
|
function wait(ms: number) {
|
||||||
|
return new Promise((resolve) => window.setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
async function buildAuthMeHeaders(): Promise<HeadersInit> {
|
async function buildAuthMeHeaders(): Promise<HeadersInit> {
|
||||||
const headers: Record<string, string> = {
|
const headers: Record<string, string> = {
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
@@ -349,6 +354,7 @@ export function DashboardStoreProvider({
|
|||||||
const summaryInflightByCityRef = useRef<Record<string, Promise<CitySummary>>>(
|
const summaryInflightByCityRef = useRef<Record<string, Promise<CitySummary>>>(
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
|
const citiesRef = useRef<CityListItem[]>([]);
|
||||||
const citySummariesRef = useRef<Record<string, CitySummary>>({});
|
const citySummariesRef = useRef<Record<string, CitySummary>>({});
|
||||||
const selectedCityRef = useRef<string | null>(null);
|
const selectedCityRef = useRef<string | null>(null);
|
||||||
const selectedDetail = selectedCity ? cityDetailsByName[selectedCity] || null : null;
|
const selectedDetail = selectedCity ? cityDetailsByName[selectedCity] || null : null;
|
||||||
@@ -369,6 +375,10 @@ export function DashboardStoreProvider({
|
|||||||
proAccess.subscriptionActive,
|
proAccess.subscriptionActive,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
citiesRef.current = cities;
|
||||||
|
}, [cities]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
citySummariesRef.current = citySummariesByName;
|
citySummariesRef.current = citySummariesByName;
|
||||||
}, [citySummariesByName]);
|
}, [citySummariesByName]);
|
||||||
@@ -614,9 +624,24 @@ export function DashboardStoreProvider({
|
|||||||
|
|
||||||
const loadCities = async () => {
|
const loadCities = async () => {
|
||||||
setLoadingState((current) => ({ ...current, cities: true }));
|
setLoadingState((current) => ({ ...current, cities: true }));
|
||||||
|
let lastError: unknown = null;
|
||||||
try {
|
try {
|
||||||
const nextCities = await dashboardClient.getCities();
|
for (let attempt = 0; attempt <= CITY_LOAD_RETRY_DELAYS_MS.length; attempt += 1) {
|
||||||
setCities(nextCities);
|
try {
|
||||||
|
const nextCities = await dashboardClient.getCities();
|
||||||
|
if (!nextCities.length) {
|
||||||
|
throw new Error("City list was empty");
|
||||||
|
}
|
||||||
|
setCities(nextCities);
|
||||||
|
return;
|
||||||
|
} catch (error) {
|
||||||
|
lastError = error;
|
||||||
|
const delayMs = CITY_LOAD_RETRY_DELAYS_MS[attempt];
|
||||||
|
if (delayMs == null) break;
|
||||||
|
await wait(delayMs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.error("Failed to load monitored cities", lastError);
|
||||||
} finally {
|
} finally {
|
||||||
setLoadingState((current) => ({ ...current, cities: false }));
|
setLoadingState((current) => ({ ...current, cities: false }));
|
||||||
}
|
}
|
||||||
@@ -920,6 +945,9 @@ export function DashboardStoreProvider({
|
|||||||
dashboardClient.clearCityDetailCache();
|
dashboardClient.clearCityDetailCache();
|
||||||
setCityDetailsByName({});
|
setCityDetailsByName({});
|
||||||
setCityDetailMetaByName({});
|
setCityDetailMetaByName({});
|
||||||
|
if (!citiesRef.current.length) {
|
||||||
|
await loadCities();
|
||||||
|
}
|
||||||
if (selectedCity) {
|
if (selectedCity) {
|
||||||
const access = proAccessRef.current;
|
const access = proAccessRef.current;
|
||||||
setLoadingState((current) => ({ ...current, refresh: true }));
|
setLoadingState((current) => ({ ...current, refresh: true }));
|
||||||
|
|||||||
Reference in New Issue
Block a user