150 lines
3.2 KiB
TypeScript
150 lines
3.2 KiB
TypeScript
interface Match {
|
|
render: boolean;
|
|
title: string;
|
|
fallbackImg: string;
|
|
staticImg?: string;
|
|
networkMode: string;
|
|
}
|
|
|
|
const routes = {
|
|
block: {
|
|
render: true,
|
|
params: 1,
|
|
getTitle(path) {
|
|
return `Block: ${path[0]}`;
|
|
}
|
|
},
|
|
address: {
|
|
render: true,
|
|
params: 1,
|
|
getTitle(path) {
|
|
return `Address: ${path[0]}`;
|
|
}
|
|
},
|
|
tx: {
|
|
render: true,
|
|
params: 1,
|
|
getTitle(path) {
|
|
return `Transaction: ${path[0]}`;
|
|
}
|
|
},
|
|
lightning: {
|
|
title: "Lightning",
|
|
fallbackImg: '/resources/previews/lightning.png',
|
|
routes: {
|
|
node: {
|
|
render: true,
|
|
params: 1,
|
|
getTitle(path) {
|
|
return `Lightning Node: ${path[0]}`;
|
|
}
|
|
},
|
|
channel: {
|
|
render: true,
|
|
params: 1,
|
|
getTitle(path) {
|
|
return `Lightning Channel: ${path[0]}`;
|
|
}
|
|
},
|
|
nodes: {
|
|
routes: {
|
|
isp: {
|
|
render: true,
|
|
params: 1,
|
|
getTitle(path) {
|
|
return `Lightning ISP: ${path[0]}`;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
group: {
|
|
render: true,
|
|
params: 1,
|
|
getTitle(path) {
|
|
return `Lightning Node Group: ${path[0]}`;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
mining: {
|
|
title: "Mining",
|
|
fallbackImg: '/resources/previews/mining.png',
|
|
routes: {
|
|
pool: {
|
|
render: true,
|
|
params: 1,
|
|
getTitle(path) {
|
|
return `Mining Pool: ${path[0]}`;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
const networks = {
|
|
bitcoin: {
|
|
fallbackImg: '/resources/previews/dashboard.png',
|
|
routes: {
|
|
...routes // all routes supported
|
|
}
|
|
},
|
|
liquid: {
|
|
fallbackImg: '/resources/liquid/liquid-network-preview.png',
|
|
routes: { // only block, address & tx routes supported
|
|
block: routes.block,
|
|
address: routes.address,
|
|
tx: routes.tx
|
|
}
|
|
},
|
|
bisq: {
|
|
fallbackImg: '/resources/bisq/bisq-markets-preview.png',
|
|
routes: {} // no routes supported
|
|
}
|
|
};
|
|
|
|
export function matchRoute(network: string, path: string): Match {
|
|
const match: Match = {
|
|
render: false,
|
|
title: '',
|
|
fallbackImg: '',
|
|
networkMode: 'mainnet'
|
|
}
|
|
|
|
const parts = path.slice(1).split('/').filter(p => p.length);
|
|
|
|
if (parts[0] === 'preview') {
|
|
parts.shift();
|
|
}
|
|
if (['testnet', 'signet'].includes(parts[0])) {
|
|
match.networkMode = parts.shift() || 'mainnet';
|
|
}
|
|
|
|
let route = networks[network] || networks.bitcoin;
|
|
match.fallbackImg = route.fallbackImg;
|
|
|
|
// traverse the route tree until we run out of route or tree, or hit a renderable match
|
|
while (!route.render && route.routes && parts.length && route.routes[parts[0]]) {
|
|
route = route.routes[parts[0]];
|
|
parts.shift();
|
|
if (route.fallbackImg) {
|
|
match.fallbackImg = route.fallbackImg;
|
|
}
|
|
}
|
|
|
|
// enough route parts left for title & rendering
|
|
if (route.render && parts.length >= route.params) {
|
|
match.render = true;
|
|
}
|
|
// only use set a static image for exact matches
|
|
if (!parts.length && route.staticImg) {
|
|
match.staticImg = route.staticImg;
|
|
}
|
|
// apply the title function if present
|
|
if (route.getTitle && typeof route.getTitle === 'function') {
|
|
match.title = route.getTitle(parts);
|
|
} else {
|
|
match.title = route.title;
|
|
}
|
|
|
|
return match;
|
|
} |