externalise deeplinks
This commit is contained in:
135
deeplinks.js
Normal file
135
deeplinks.js
Normal file
@@ -0,0 +1,135 @@
|
||||
// deeplinks.js - Deep Link Manager for Game Timer
|
||||
|
||||
// Available actions
|
||||
const VALID_ACTIONS = ['start', 'pause', 'toggle', 'nextplayer', 'reset'];
|
||||
|
||||
// Class to manage all deep link functionality
|
||||
class DeepLinkManager {
|
||||
constructor() {
|
||||
this.actionHandlers = {};
|
||||
|
||||
// Initialize listeners
|
||||
this.initServiceWorkerListener();
|
||||
this.initHashChangeListener();
|
||||
this.initPopStateListener();
|
||||
}
|
||||
|
||||
// Register action handlers
|
||||
registerHandler(action, handlerFn) {
|
||||
if (VALID_ACTIONS.includes(action)) {
|
||||
this.actionHandlers[action] = handlerFn;
|
||||
console.log(`Registered handler for action: ${action}`);
|
||||
} else {
|
||||
console.warn(`Attempted to register handler for invalid action: ${action}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract action from URL parameters (search or hash)
|
||||
getActionFromUrl() {
|
||||
// Check for action in both search params and hash
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
const hashParams = new URLSearchParams(window.location.hash.substring(1));
|
||||
|
||||
// First check search params (for direct curl or navigation)
|
||||
const searchAction = searchParams.get('action');
|
||||
if (searchAction && VALID_ACTIONS.includes(searchAction)) {
|
||||
console.log('Found action in search params:', searchAction);
|
||||
return searchAction;
|
||||
}
|
||||
|
||||
// Then check hash params (existing deep link mechanism)
|
||||
const hashAction = hashParams.get('action');
|
||||
if (hashAction && VALID_ACTIONS.includes(hashAction)) {
|
||||
console.log('Found action in hash params:', hashAction);
|
||||
return hashAction;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Process an action
|
||||
handleAction(action) {
|
||||
if (!action) return;
|
||||
|
||||
console.log('Processing action:', action);
|
||||
|
||||
if (this.actionHandlers[action]) {
|
||||
this.actionHandlers[action]();
|
||||
} else {
|
||||
console.log('No handler registered for action:', action);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle deep links from URL
|
||||
processDeepLink() {
|
||||
// Get action from URL parameters
|
||||
const action = this.getActionFromUrl();
|
||||
|
||||
// Process the action if found
|
||||
if (action) {
|
||||
this.handleAction(action);
|
||||
|
||||
// Clear the parameters to prevent duplicate actions if page is refreshed
|
||||
if (window.history && window.history.replaceState) {
|
||||
// Create new URL without the action parameter
|
||||
const newUrl = window.location.pathname;
|
||||
window.history.replaceState({}, document.title, newUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize service worker message listener
|
||||
initServiceWorkerListener() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.addEventListener('message', (event) => {
|
||||
if (event.data && event.data.type === 'ACTION') {
|
||||
console.log('Received action from service worker:', event.data.action);
|
||||
this.handleAction(event.data.action);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize hash change listener
|
||||
initHashChangeListener() {
|
||||
window.addEventListener('hashchange', () => {
|
||||
console.log('Hash changed, checking for actions');
|
||||
this.processDeepLink();
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize popstate listener for navigation events
|
||||
initPopStateListener() {
|
||||
window.addEventListener('popstate', () => {
|
||||
console.log('Navigation occurred, checking for actions');
|
||||
this.processDeepLink();
|
||||
});
|
||||
}
|
||||
|
||||
// Send an action to the service worker
|
||||
sendActionToServiceWorker(action) {
|
||||
if ('serviceWorker' in navigator && navigator.serviceWorker.controller) {
|
||||
navigator.serviceWorker.controller.postMessage({
|
||||
type: 'PROCESS_ACTION',
|
||||
action: action
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a deep link URL for a specific action
|
||||
generateDeepLink(action, useHash = false) {
|
||||
if (!VALID_ACTIONS.includes(action)) {
|
||||
console.warn(`Cannot generate deep link for invalid action: ${action}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const baseUrl = window.location.origin + window.location.pathname;
|
||||
return useHash ?
|
||||
`${baseUrl}#action=${action}` :
|
||||
`${baseUrl}?action=${action}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Export singleton instance
|
||||
const deepLinkManager = new DeepLinkManager();
|
||||
export default deepLinkManager;
|
||||
Reference in New Issue
Block a user