import { parseShineRouteParts } from './services/shine-routes.js'; let previousTrackedPath = ''; let currentTrackedPath = String(window.location.pathname || '').trim() || '/'; const PRETTY_PATHS = new Map([ ['start-view', 'start'], ['entry-settings-view', 'entry-settings'], ['register-view', 'register'], ['registration-faq-view', 'register/faq'], ['registration-payment-view', 'register/payment'], ['registration-draft-keys-view', 'register/draft-keys'], ['registration-keys-view', 'register/keys'], ['topup-view', 'topup'], ['devnet-topup-view', 'devnet-topup'], ['login-view', 'login'], ['login-camera-view', 'login/camera'], ['login-other-device-view', 'login/device'], ['login-password-view', 'login/password'], ['key-storage-view', 'key-storage'], ['profile-view', 'profile'], ['profile-edit-view', 'profile/edit'], ['profiles-view', 'profiles'], ['messages-list', 'messages'], ['contact-search-view', 'contacts'], ['chat-view', 'chat'], ['channels-list', 'channels'], ['add-channel-view', 'channels/new'], ['add-personal-public-chat-view', 'channels/new-public-chat'], ['channel-view', 'channel'], ['channel-about-view', 'channel/about'], ['channel-thread-view', 'thread'], ['network-view', 'network'], ['notifications-view', 'notifications'], ['settings-view', 'settings'], ['access-servers-view', 'settings/access-servers'], ['server-settings-view', 'settings/servers'], ['arweave-uploads-view', 'settings/arweave-uploads'], ['developer-settings-view', 'settings/developer'], ['trusted-device-login-settings-view', 'settings/device-login'], ['language-view', 'settings/language'], ['app-log-view', 'settings/app-log'], ['pwa-diagnostics-view', 'settings/pwa-diagnostics'], ['solana-users-init-view', 'settings/solana-users-init'], ['solana-rpc-check-view', 'settings/solana-rpc-check'], ['wallet-view', 'wallet'], ['queue', 'quene'], ['device-view', 'devices'], ['device-session-view', 'devices'], ['connect-device-view', 'devices/connect'], ['device-pairing-view', 'devices/pairing'], ['device-qr-view', 'devices/qr'], ['device-camera-view', 'devices/camera'], ['show-keys-view', 'devices/keys'], ['remote-addblock-session-view', 'remote-addblock-session'], ]); function looksLikeBlockchainName(value) { return /^.+-\d+$/.test(String(value || '').trim()); } export const PRE_AUTH_PAGES = [ 'start-view', 'entry-settings-view', 'register-view', 'registration-faq-view', 'registration-payment-view', 'registration-draft-keys-view', 'registration-keys-view', 'topup-view', 'devnet-topup-view', 'login-view', 'login-camera-view', 'login-other-device-view', 'login-password-view', 'key-storage-view', ]; export function parseRouteFromPath(pathname = '') { const currentPath = String(pathname || '').trim(); const raw = currentPath .replace(/^\/+/, '') .replace(/^index\.html$/i, '') .replace(/^index\.html\//i, '') .replace(/\/+$/, ''); if (!raw) return { pageId: '', params: {} }; const segments = raw.split('/').filter(Boolean); const pageId = segments[0] || ''; const dynamicId = segments[1] || ''; const decodePart = (value) => { try { return decodeURIComponent(value || ''); } catch { return value || ''; } }; const isLikelyBlockNumber = (value) => /^[0-9]+$/.test(String(value || '').trim()); const shineRoute = parseShineRouteParts(segments); if (shineRoute?.entity) { const shineLogin = shineRoute.entity; const baseOffset = Number(shineRoute.offset || 0); const section = decodePart(segments[baseOffset] || '').toLowerCase(); if (!section) { return { pageId: 'user', params: { login: shineLogin, fromPage: 'messages-list', section: 'profile' } }; } if (section === 'links') { return { pageId: 'network-view', params: { mode: 'keep-history', login: shineLogin } }; } if (section === 'manage') { return { pageId: 'user-relation-manage-view', params: { login: shineLogin } }; } if (section === 'list') { return { pageId: 'user-profile-list-view', params: { login: shineLogin, kind: decodePart(segments[baseOffset + 1] || '') } }; } if (section === 'channels') { const sub = decodePart(segments[baseOffset + 1] || '').toLowerCase(); if (sub === 'owned') { return { pageId: 'channels-list', params: { mode: 'my', login: shineLogin, scope: 'owned' }, }; } if (sub === 'following') { return { pageId: 'channels-list', params: { mode: 'feed', login: shineLogin, scope: 'following' }, }; } return { pageId: 'channels-list', params: { mode: 'feed', login: shineLogin, scope: 'all' }, }; } if (segments.length === baseOffset + 1 && isLikelyBlockNumber(segments[baseOffset])) { return { pageId: 'channel-thread-view', params: { messageBlockchainName: shineLogin, messageBlockNumber: segments[baseOffset] || '', messageBlockHash: '', channelOwnerBlockchainName: '', channelRootBlockNumber: '', channelRootBlockHash: '', }, }; } if (segments.length >= baseOffset + 1) { const ownerBlockchainName = shineLogin; const channelName = decodePart(segments[baseOffset] || ''); const messageBlockNumber = segments[baseOffset + 1] || ''; if (ownerBlockchainName && channelName && messageBlockNumber) { return { pageId: 'channel-thread-view', params: { ownerBlockchainName, channelName, messageBlockNumber, messageBlockHash: '', messageBlockchainName: '', channelOwnerBlockchainName: ownerBlockchainName, channelRootBlockNumber: '', channelRootBlockHash: '', }, }; } if (ownerBlockchainName && channelName) { return { pageId: 'channel-view', params: { ownerBlockchainName, channelName, channelId: '' }, }; } } } if (segments.length >= 2 && looksLikeBlockchainName(segments[0])) { const ownerBlockchainName = decodePart(segments[0]); const channelName = decodePart(segments[1] || ''); const sub = decodePart(segments[2] || '').toLowerCase(); if (ownerBlockchainName && channelName) { if (sub === 'about') { return { pageId: 'channel-about-view', params: { ownerBlockchainName, channelRootBlockNumber: '', channelRootBlockHash: '', channelId: '', channelName, }, }; } return { pageId: 'channel-view', params: { ownerBlockchainName, channelName, channelId: '', }, }; } } if (pageId === 'chat' || pageId === 'chat-view') { return { pageId: 'chat-view', params: { chatId: dynamicId ? decodeURIComponent(dynamicId) : '' } }; } if (pageId === 'start') { return { pageId: 'start-view', params: {} }; } if (pageId === 'entry-settings') { return { pageId: 'entry-settings-view', params: {} }; } if (pageId === 'register') { const sub = decodePart(segments[1] || '').toLowerCase(); if (sub === 'faq') return { pageId: 'registration-faq-view', params: {} }; if (sub === 'payment') return { pageId: 'registration-payment-view', params: {} }; if (sub === 'draft-keys') return { pageId: 'registration-draft-keys-view', params: {} }; if (sub === 'keys') return { pageId: 'registration-keys-view', params: {} }; return { pageId: 'register-view', params: {} }; } if (pageId === 'topup') { return { pageId: 'topup-view', params: {} }; } if (pageId === 'devnet-topup') { return { pageId: 'devnet-topup-view', params: {} }; } if (pageId === 'login') { const sub = decodePart(segments[1] || '').toLowerCase(); if (sub === 'camera') return { pageId: 'login-camera-view', params: {} }; if (sub === 'device') return { pageId: 'login-other-device-view', params: {} }; if (sub === 'password') return { pageId: 'login-password-view', params: {} }; return { pageId: 'login-view', params: {} }; } if (pageId === 'key-storage') { return { pageId: 'key-storage-view', params: {} }; } if (pageId === 'profile') { const sub = decodePart(segments[1] || '').toLowerCase(); if (sub === 'edit') return { pageId: 'profile-edit-view', params: {} }; return { pageId: 'profile-view', params: {} }; } if (pageId === 'profiles') { return { pageId: 'profiles-view', params: {} }; } if (pageId === 'messages') { return { pageId: 'messages-list', params: {} }; } if (pageId === 'contacts') { return { pageId: 'contact-search-view', params: {} }; } if (pageId === 'channels') { const sub = decodePart(segments[1] || '').toLowerCase(); if (sub === 'new') return { pageId: 'add-channel-view', params: {} }; if (sub === 'new-public-chat') return { pageId: 'add-personal-public-chat-view', params: {} }; return { pageId: 'channels-list', params: { mode: segments[1] ? decodePart(segments[1]) : '' } }; } if (pageId === 'channel') { if (segments.length >= 5 && decodePart(segments[4] || '').toLowerCase() === 'about') { return { pageId: 'channel-about-view', params: { ownerBlockchainName: decodePart(segments[1]), channelRootBlockNumber: segments[2] || '', channelRootBlockHash: segments[3] || '', channelId: '', }, }; } if (segments.length >= 4) { return { pageId: 'channel-view', params: { ownerBlockchainName: decodePart(segments[1]), channelRootBlockNumber: segments[2] || '', channelRootBlockHash: segments[3] || '', channelId: '', }, }; } return { pageId: 'channel-view', params: { channelId: dynamicId || '' } }; } if (pageId === 'thread') { return { pageId: 'channel-thread-view', params: { messageBlockchainName: decodePart(segments[1]), messageBlockNumber: segments[2] || '', messageBlockHash: '', channelOwnerBlockchainName: decodePart(segments[3]), channelRootBlockNumber: segments[4] || '', channelRootBlockHash: segments[5] || '', }, }; } if (pageId === 'network') { return { pageId: 'network-view', params: { mode: segments[1] ? decodePart(segments[1]) : '' } }; } if (pageId === 'notifications') { return { pageId: 'notifications-view', params: {} }; } if (pageId === 'settings') { const sub = decodePart(segments[1] || '').toLowerCase(); if (sub === 'access-servers') return { pageId: 'access-servers-view', params: {} }; if (sub === 'servers') return { pageId: 'server-settings-view', params: {} }; if (sub === 'arweave-uploads') return { pageId: 'arweave-uploads-view', params: {} }; if (sub === 'developer') return { pageId: 'developer-settings-view', params: {} }; if (sub === 'device-login') return { pageId: 'trusted-device-login-settings-view', params: {} }; if (sub === 'language') return { pageId: 'language-view', params: {} }; if (sub === 'app-log') return { pageId: 'app-log-view', params: {} }; if (sub === 'pwa-diagnostics') return { pageId: 'pwa-diagnostics-view', params: {} }; if (sub === 'solana-users-init') return { pageId: 'solana-users-init-view', params: {} }; if (sub === 'solana-rpc-check') return { pageId: 'solana-rpc-check-view', params: {} }; return { pageId: 'settings-view', params: {} }; } if (pageId === 'wallet') { return { pageId: 'wallet-view', params: {} }; } if (pageId === 'quene' || pageId === 'queue') { return { pageId: 'queue', params: {} }; } if (pageId === 'devices') { const sub = decodePart(segments[1] || '').toLowerCase(); if (sub === 'connect') return { pageId: 'connect-device-view', params: {} }; if (sub === 'pairing') return { pageId: 'device-pairing-view', params: {} }; if (sub === 'qr') return { pageId: 'device-qr-view', params: {} }; if (sub === 'camera') return { pageId: 'device-camera-view', params: {} }; if (sub === 'keys') return { pageId: 'show-keys-view', params: {} }; if (dynamicId) { return { pageId: 'device-session-view', params: { sessionId: decodeURIComponent(dynamicId) } }; } return { pageId: 'device-view', params: {} }; } if (pageId === 'remote-addblock-session') { return { pageId: 'remote-addblock-session-view', params: {} }; } if (pageId === 'channel-view') { if (segments.length >= 4) { return { pageId, params: { ownerBlockchainName: decodePart(segments[1]), channelRootBlockNumber: segments[2] || '', channelRootBlockHash: segments[3] || '', channelId: '', }, }; } return { pageId, params: { channelId: dynamicId || '' } }; } if (pageId === 'channel-thread-view') { return { pageId, params: { messageBlockchainName: decodePart(segments[1]), messageBlockNumber: segments[2] || '', messageBlockHash: '', channelOwnerBlockchainName: decodePart(segments[3]), channelRootBlockNumber: segments[4] || '', channelRootBlockHash: segments[5] || '', }, }; } if (pageId === 'device-session-view') { return { pageId, params: { sessionId: dynamicId ? decodeURIComponent(dynamicId) : '' } }; } if (pageId === 'network-view') { return { pageId, params: { mode: segments[1] ? decodePart(segments[1]) : '' } }; } if (pageId === 'channels-list') { return { pageId, params: { mode: segments[1] ? decodePart(segments[1]) : '' } }; } return { pageId, params: {} }; } export function getRoute() { return parseRouteFromPath(window.location.pathname || ''); } export function navigate(path) { const cleanPath = toPrettyPath(path); const nextPath = cleanPath ? `/${cleanPath}` : '/'; if (window.location.pathname !== nextPath) { previousTrackedPath = currentTrackedPath; currentTrackedPath = nextPath; } if (window.location.pathname !== nextPath) { window.history.pushState({}, '', nextPath); } window.dispatchEvent(new PopStateEvent('popstate')); } export function toPrettyPath(path) { const raw = String(path || '').replace(/^\/+/, '').replace(/\/+$/, ''); if (!raw) return ''; const segments = raw.split('/').filter(Boolean); if (!segments.length) return ''; const [head, ...tail] = segments; const prettyHead = PRETTY_PATHS.get(head) || head; return [prettyHead, ...tail].join('/'); } export function navigateBack() { if (window.history.length <= 1) return; window.history.back(); } export function resolveToolbarActive(pageId) { if ( pageId === 'messages-list' || pageId === 'channels-list' || pageId === 'network-view' || pageId === 'notifications-view' || pageId === 'profile-view' ) return pageId; if ( pageId === 'profile-edit-view' || pageId === 'profiles-view' || pageId === 'wallet-view' || pageId === 'settings-view' || pageId === 'access-servers-view' || pageId === 'developer-settings-view' || pageId === 'server-settings-view' || pageId === 'arweave-uploads-view' || pageId === 'remote-addblock-session-view' || pageId === 'device-view' || pageId === 'connect-device-view' || pageId === 'device-pairing-view' || pageId === 'trusted-device-login-settings-view' || pageId === 'device-qr-view' || pageId === 'device-camera-view' || pageId === 'show-keys-view' || pageId === 'device-session-view' || pageId === 'language-view' || pageId === 'app-log-view' || pageId === 'pwa-diagnostics-view' || pageId === 'solana-users-init-view' ) return 'profile-view'; if (pageId === 'chat-view' || pageId === 'contact-search-view') return 'messages-list'; if (pageId === 'channel-view' || pageId === 'channel-about-view' || pageId === 'channel-thread-view' || pageId === 'add-channel-view' || pageId === 'add-personal-public-chat-view') return 'channels-list'; if (pageId === 'user') return 'messages-list'; return 'profile-view'; } export function syncTrackedRouteHistory(pathname = '') { const nextPath = String(pathname || '').trim() || '/'; if (nextPath === currentTrackedPath) return; previousTrackedPath = currentTrackedPath; currentTrackedPath = nextPath; } export function getPreviousTrackedPath() { return previousTrackedPath; }