Update AppLayoutProvider.tsx

This commit is contained in:
Nate Kelley 2025-04-17 22:15:04 -06:00
parent 0b7f71ca14
commit af5f3e6675
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
1 changed files with 44 additions and 51 deletions

View File

@ -24,6 +24,8 @@ export const useAppLayout = () => {
// Check if the target URL is exactly the same as current URL (including search params) // Check if the target URL is exactly the same as current URL (including search params)
const targetUrl = new URL(targetPath, window.location.origin); const targetUrl = new URL(targetPath, window.location.origin);
const currentUrl = new URL(window.location.href); const currentUrl = new URL(window.location.href);
// Early return if URLs are identical
if (targetUrl.toString() === currentUrl.toString()) { if (targetUrl.toString() === currentUrl.toString()) {
return Promise.resolve(); return Promise.resolve();
} }
@ -31,74 +33,45 @@ export const useAppLayout = () => {
// Extract the pathname without query parameters // Extract the pathname without query parameters
const targetPathname = targetUrl.pathname; const targetPathname = targetUrl.pathname;
const currentPathname = currentUrl.pathname; const currentPathname = currentUrl.pathname;
const hasQueryParams = targetPath.indexOf('?') !== -1;
if (options?.shallow) { // Handle shallow routing (only updating query params)
const isSamePathname = targetPathname === currentPathname; if (options?.shallow && targetPathname === currentPathname) {
return new Promise((resolve) => {
if (isSamePathname) { const params = getQueryParamsFromPath(targetPath);
return new Promise((resolve) => { onChangeQueryParams(params, false);
const params = getQueryParamsFromPath(targetPath); resolve();
onChangeQueryParams(params, false); });
resolve();
});
}
} }
return new Promise((resolve) => { return new Promise((resolve) => {
// If we're already on the target pathname, but query params might differ // Same pathname cases
if (currentPathname === targetPathname && targetPath.indexOf('?') === -1) { if (targetPathname === currentPathname) {
// Clear query params by using the pathname only // Case 1: Remove all query parameters
window.history.pushState({}, '', targetPathname); if (!hasQueryParams) {
resolve(); window.history.pushState({}, '', targetPathname);
return; resolve();
} return;
}
// If target and current pathnames are the same but target includes query params // Case 2: Update query parameters
if (currentPathname === targetPathname && targetPath.indexOf('?') !== -1) {
// Compare current and target query parameters
const currentUrl = new URL(window.location.href);
const targetUrl = new URL(targetPath, window.location.origin);
const currentParams = Object.fromEntries(currentUrl.searchParams.entries()); const currentParams = Object.fromEntries(currentUrl.searchParams.entries());
const targetParams = Object.fromEntries(targetUrl.searchParams.entries()); const targetParams = Object.fromEntries(targetUrl.searchParams.entries());
// Check if the params are actually different // Skip if params are identical
const paramsAreDifferent = JSON.stringify(currentParams) !== JSON.stringify(targetParams); if (JSON.stringify(currentParams) === JSON.stringify(targetParams)) {
if (!paramsAreDifferent) {
resolve(); resolve();
return; return;
} }
push(targetPath); push(targetPath);
// Set up an effect to watch for pathname changes waitForUrlChange(() => window.location.href.includes(targetPath), resolve);
const checkPathChange = (waitTime: number = 25, iteration: number = 0) => {
if (window.location.href.includes(targetPath)) {
resolve();
} else if (iteration >= 10) {
resolve();
} else {
const newWaitTime = waitTime * 1.25;
setTimeout(() => checkPathChange(newWaitTime, iteration + 1), newWaitTime);
}
};
checkPathChange();
return; return;
} }
// Default case - different pathnames // Case 3: Different pathname - navigate to new route
const checkPathChange = (waitTime: number = 25, iteration: number = 0) => {
if (window.location.pathname !== currentPathname) {
resolve();
} else if (iteration >= 10) {
resolve();
} else {
const newWaitTime = waitTime * 1.25;
setTimeout(() => checkPathChange(newWaitTime, iteration + 1), newWaitTime);
}
};
push(targetPath); push(targetPath);
checkPathChange(); waitForUrlChange(() => window.location.pathname !== currentPathname, resolve);
}); });
} }
); );
@ -155,6 +128,26 @@ const getQueryParamsFromPath = (path: string): Record<string, string> => {
return params; return params;
}; };
// Helper function to wait for URL changes
const waitForUrlChange = (
condition: () => boolean,
callback: () => void,
waitTime: number = 25,
iteration: number = 0
) => {
if (condition()) {
callback();
} else if (iteration >= 10) {
callback(); // Resolve anyway after max attempts
} else {
const newWaitTime = waitTime * 1.25;
setTimeout(
() => waitForUrlChange(condition, callback, newWaitTime, iteration + 1),
newWaitTime
);
}
};
const AppLayoutContext = createContext<ReturnType<typeof useAppLayout>>( const AppLayoutContext = createContext<ReturnType<typeof useAppLayout>>(
{} as ReturnType<typeof useAppLayout> {} as ReturnType<typeof useAppLayout>
); );