90 lines
2.4 KiB
TypeScript
90 lines
2.4 KiB
TypeScript
// Enhanced router for reliable navigation with proper browser integration
|
|
let currentPath = window.location.pathname + window.location.search || '/';
|
|
const listeners: (() => void)[] = [];
|
|
|
|
export function navigateTo(path: string) {
|
|
try {
|
|
|
|
// Update current path
|
|
currentPath = path;
|
|
|
|
// Update browser URL and history
|
|
if (window.history && window.history.pushState) {
|
|
window.history.pushState({ path }, '', path);
|
|
} else {
|
|
// Fallback for older browsers
|
|
window.location.href = path;
|
|
return;
|
|
}
|
|
|
|
// Force a state change event
|
|
window.dispatchEvent(new PopStateEvent('popstate', { state: { path } }));
|
|
|
|
// Notify all listeners of the route change
|
|
listeners.forEach(listener => {
|
|
try {
|
|
listener();
|
|
} catch (error) {
|
|
console.error('Error in route listener:', error);
|
|
}
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('Navigation error:', error);
|
|
// Ultimate fallback
|
|
window.location.href = path;
|
|
}
|
|
}
|
|
|
|
export function getCurrentPath() {
|
|
try {
|
|
// Always get the current path from the browser URL
|
|
const path = window.location.pathname + window.location.search;
|
|
currentPath = path;
|
|
return path;
|
|
} catch (error) {
|
|
console.error('Error getting current path:', error);
|
|
return currentPath;
|
|
}
|
|
}
|
|
|
|
export function addRouteListener(listener: () => void) {
|
|
listeners.push(listener);
|
|
|
|
// Listen for browser back/forward button events
|
|
const handlePopState = (event: PopStateEvent) => {
|
|
try {
|
|
currentPath = window.location.pathname + window.location.search;
|
|
listener();
|
|
} catch (error) {
|
|
console.error('Error in popstate handler:', error);
|
|
}
|
|
};
|
|
|
|
// Listen for our custom navigation events
|
|
const handleNavigation = () => {
|
|
try {
|
|
listener();
|
|
} catch (error) {
|
|
console.error('Error in navigation handler:', error);
|
|
}
|
|
};
|
|
|
|
window.addEventListener('popstate', handlePopState);
|
|
window.addEventListener('navigation', handleNavigation);
|
|
|
|
return () => {
|
|
const index = listeners.indexOf(listener);
|
|
if (index > -1) {
|
|
listeners.splice(index, 1);
|
|
}
|
|
window.removeEventListener('popstate', handlePopState);
|
|
window.removeEventListener('navigation', handleNavigation);
|
|
};
|
|
}
|
|
|
|
// Helper function to trigger navigation events
|
|
export function triggerNavigationUpdate() {
|
|
window.dispatchEvent(new CustomEvent('navigation'));
|
|
}
|