refactor(ModalTopBar, Discover): clean up breadcrumb handling and hash navigation logic

This commit is contained in:
alexsparkes
2026-02-02 10:59:01 +00:00
parent 99b139ffd6
commit cfb27ba392
2 changed files with 42 additions and 39 deletions

View File

@@ -102,38 +102,41 @@ function ModalTopBar({
// Use all iframe breadcrumbs except the first one (which is usually "Marketplace" or the category)
// Skip the first breadcrumb as it's redundant with our tab label
const relevantCrumbs = iframeBreadcrumbs.slice(1);
relevantCrumbs.forEach((crumb, index) => {
const isLast = index === relevantCrumbs.length - 1;
breadcrumbPath.push({
label: crumb.label,
// Make it clickable if it has an href and it's not the last item
onClick: crumb.clickable && !isLast && crumb.href ? () => {
// Convert website href to extension hash format
// e.g., /marketplace/packs/123 -> #discover/photo_packs/123
// e.g., /marketplace/collections -> #discover/collections
const href = crumb.href;
if (href.includes('/collections')) {
updateHash('#discover/collections');
} else if (href.includes('/collection/')) {
const collectionId = href.split('/collection/')[1]?.split('?')[0];
if (collectionId) {
updateHash(`#discover/collection/${collectionId}`);
}
} else if (href === '/marketplace' || href === '/marketplace/') {
updateHash('#discover/all');
}
// If it's a specific item, we'd need more context to determine the category
// In that case, using history.back() might be more reliable
else {
const stepsBack = relevantCrumbs.length - index - 1;
for (let i = 0; i < stepsBack; i++) {
window.history.back();
}
}
} : null,
onClick:
crumb.clickable && !isLast && crumb.href
? () => {
// Convert website href to extension hash format
// e.g., /marketplace/packs/123 -> #discover/photo_packs/123
// e.g., /marketplace/collections -> #discover/collections
const href = crumb.href;
if (href.includes('/collections')) {
updateHash('#discover/collections');
} else if (href.includes('/collection/')) {
const collectionId = href.split('/collection/')[1]?.split('?')[0];
if (collectionId) {
updateHash(`#discover/collection/${collectionId}`);
}
} else if (href === '/marketplace' || href === '/marketplace/') {
updateHash('#discover/all');
}
// If it's a specific item, we'd need more context to determine the category
// In that case, using history.back() might be more reliable
else {
const stepsBack = relevantCrumbs.length - index - 1;
for (let i = 0; i < stepsBack; i++) {
window.history.back();
}
}
}
: null,
});
});
} else if (productView) {

View File

@@ -146,21 +146,21 @@ function DiscoverContent({ category, onBreadcrumbsChange, deepLinkData }) {
useEffect(() => {
const handleHashChange = () => {
if (!iframeRef.current?.contentWindow) return;
const hash = window.location.hash;
if (!hash || !hash.startsWith('#discover')) return;
// Parse hash to determine target path
// e.g., #discover/photo_packs/123 -> /marketplace/packs/123
// e.g., #discover/preset_settings/456 -> /marketplace/presets/456
// e.g., #discover/collections -> /marketplace/collections
// e.g., #discover/collection/featured -> /marketplace/collection/featured
const parts = hash.slice(1).split('/');
if (parts.length < 2) return;
let targetPath = '/marketplace';
if (parts[1] === 'collections') {
targetPath = '/marketplace/collections';
} else if (parts[1] === 'collection' && parts[2]) {
@@ -178,18 +178,18 @@ function DiscoverContent({ category, onBreadcrumbsChange, deepLinkData }) {
// Category filter
targetPath = `/marketplace?type=${parts[1]}`;
}
// Send navigation command to iframe
const theme = getResolvedTheme();
iframeRef.current.contentWindow.postMessage(
{
type: 'marketplace:navigate',
payload: { path: targetPath }
payload: { path: targetPath },
},
MARKETPLACE_URL
MARKETPLACE_URL,
);
};
// Listen for hash changes from browser navigation
window.addEventListener('hashchange', handleHashChange);
return () => window.removeEventListener('hashchange', handleHashChange);
@@ -302,15 +302,15 @@ function DiscoverContent({ category, onBreadcrumbsChange, deepLinkData }) {
// e.g., /marketplace/presets/456 -> #discover/preset_settings/456
// e.g., /marketplace/collections -> #discover/collections
// e.g., /marketplace/collection/featured -> #discover/collection/featured
const path = payload.path;
if (path.includes('/packs/')) {
const itemId = path.split('/packs/')[1]?.split('?')[0];
if (itemId) {
// Determine type from installed items or default to photo_packs
const installed = JSON.parse(localStorage.getItem('installed')) || [];
const item = installed.find(i => i.id === itemId);
const item = installed.find((i) => i.id === itemId);
const category = item?.type || 'photo_packs';
updateHash(`#discover/${category}/${itemId}`);
}