bigblocks
Version:
Complete Bitcoin UI component library - authentication, social, wallet, market, inscriptions, and blockchain interactions for React
15 lines • 6.75 kB
JSON
{
"name": "metalens-hooks-usemetalenscontext",
"type": "registry:hook",
"dependencies": [],
"devDependencies": [],
"registryDependencies": [],
"files": [
{
"path": "components/metalens/hooks/useMetaLensContext.ts",
"type": "registry:hook",
"content": "\"use client\";\n\nimport { useCallback } from \"react\";\nimport type { MetaLensContextType } from \"../types/index.js\";\n\n/**\n * Hook for detecting and parsing MetaLens contexts\n *\n * Based on patterns from:\n * - MetaLens browser extension context detection\n * - Various context type implementations\n *\n * @example\n * ```tsx\n * const { detectContext, parseContext } = useMetaLensContext();\n *\n * // Detect context from current page\n * const context = detectContext();\n *\n * // Parse a specific identifier\n * const parsed = parseContext('https://example.com/article');\n * // Returns: { type: 'url', value: 'https://example.com/article' }\n * ```\n */\nexport function useMetaLensContext() {\n\tconst detectContext = useCallback((): {\n\t\ttype: MetaLensContextType;\n\t\tvalue: string;\n\t} | null => {\n\t\tif (typeof window === \"undefined\" || !document) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Check meta tags for bitcoin transaction\n\t\tconst txMeta = document.querySelector(\n\t\t\t'meta[name=\"bitcoin-tx\"], meta[property=\"bitcoin:tx\"]',\n\t\t);\n\t\tif (txMeta?.getAttribute(\"content\")) {\n\t\t\treturn { type: \"tx\", value: txMeta.getAttribute(\"content\") || \"\" };\n\t\t}\n\n\t\t// Check for UPC in meta tags or structured data\n\t\tconst upcMeta = document.querySelector(\n\t\t\t'meta[property=\"product:upc\"], meta[name=\"upc\"]',\n\t\t);\n\t\tif (upcMeta?.getAttribute(\"content\")) {\n\t\t\treturn { type: \"upc\", value: upcMeta.getAttribute(\"content\") || \"\" };\n\t\t}\n\n\t\t// Check for ISBN in structured data\n\t\tconst isbnElement = document.querySelector(\n\t\t\t'[itemprop=\"isbn\"], meta[property=\"book:isbn\"]',\n\t\t);\n\t\tif (isbnElement) {\n\t\t\tconst isbn =\n\t\t\t\tisbnElement.getAttribute(\"content\") || isbnElement.textContent || \"\";\n\t\t\tif (isbn) {\n\t\t\t\treturn { type: \"isbn\", value: isbn.trim() };\n\t\t\t}\n\t\t}\n\n\t\t// Check URL patterns for specific contexts\n\t\tconst url = window.location.href;\n\n\t\t// Transaction explorers\n\t\tconst txExplorerPattern =\n\t\t\t/(?:whatsonchain\\.com|blockchair\\.com|blockstream\\.info)\\/.*\\/tx\\/([a-fA-F0-9]{64})/;\n\t\tconst txMatch = url.match(txExplorerPattern);\n\t\tif (txMatch?.[1]) {\n\t\t\treturn { type: \"tx\", value: txMatch[1] };\n\t\t}\n\n\t\t// IPFS gateways\n\t\tconst ipfsPattern =\n\t\t\t/(?:ipfs\\.io|gateway\\.ipfs\\.io|cloudflare-ipfs\\.com)\\/ipfs\\/(Qm[a-zA-Z0-9]+)/;\n\t\tconst ipfsMatch = url.match(ipfsPattern);\n\t\tif (ipfsMatch?.[1]) {\n\t\t\treturn { type: \"ipfs\", value: ipfsMatch[1] };\n\t\t}\n\n\t\t// Default to current URL\n\t\treturn { type: \"url\", value: window.location.href };\n\t}, []);\n\n\tconst parseContext = useCallback(\n\t\t(identifier: string): { type: MetaLensContextType; value: string } => {\n\t\t\tif (!identifier || typeof identifier !== \"string\") {\n\t\t\t\treturn { type: \"custom\", value: identifier || \"\" };\n\t\t\t}\n\n\t\t\t// Trim whitespace\n\t\t\tconst trimmedIdentifier = identifier.trim();\n\n\t\t\t// Check if it's a transaction ID (64 hex chars)\n\t\t\tif (/^[a-fA-F0-9]{64}$/.test(trimmedIdentifier)) {\n\t\t\t\treturn { type: \"tx\", value: trimmedIdentifier };\n\t\t\t}\n\n\t\t\t// Check if it's a UPC (12-14 digits)\n\t\t\tif (/^\\d{12,14}$/.test(trimmedIdentifier)) {\n\t\t\t\treturn { type: \"upc\", value: trimmedIdentifier };\n\t\t\t}\n\n\t\t\t// Check if it's an ISBN (10 or 13 digits, possibly with dashes)\n\t\t\tconst cleanIsbn = trimmedIdentifier.replace(/[-\\s]/g, \"\");\n\t\t\tif (/^(?:\\d{9}[\\dX]|\\d{13})$/.test(cleanIsbn)) {\n\t\t\t\treturn { type: \"isbn\", value: trimmedIdentifier };\n\t\t\t}\n\n\t\t\t// Check if it's a geohash (alphanumeric, typically 4-12 chars)\n\t\t\t// Basic validation - real geohash validation is more complex\n\t\t\tif (/^[0-9a-z]{4,12}$/.test(trimmedIdentifier)) {\n\t\t\t\t// Additional check: geohashes use base32 (no 'a', 'i', 'l', 'o')\n\t\t\t\tif (!/[ailo]/i.test(trimmedIdentifier)) {\n\t\t\t\t\treturn { type: \"geohash\", value: trimmedIdentifier };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check if it's an IPFS hash\n\t\t\tif (\n\t\t\t\ttrimmedIdentifier.startsWith(\"Qm\") &&\n\t\t\t\ttrimmedIdentifier.length === 46\n\t\t\t) {\n\t\t\t\treturn { type: \"ipfs\", value: trimmedIdentifier };\n\t\t\t}\n\t\t\tif (trimmedIdentifier.startsWith(\"ipfs://\")) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"ipfs\",\n\t\t\t\t\tvalue: trimmedIdentifier.replace(\"ipfs://\", \"\"),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Check if it's a DOI\n\t\t\tif (/^10\\.\\d{4,}\\/[-._;()\\/:a-zA-Z0-9]+$/.test(trimmedIdentifier)) {\n\t\t\t\treturn { type: \"doi\", value: trimmedIdentifier };\n\t\t\t}\n\n\t\t\t// Check if it's a URL\n\t\t\ttry {\n\t\t\t\tconst _url = new URL(trimmedIdentifier);\n\t\t\t\t// Valid URL\n\t\t\t\treturn { type: \"url\", value: trimmedIdentifier };\n\t\t\t} catch {\n\t\t\t\t// Not a valid URL, check if it looks like a URL without protocol\n\t\t\t\tif (\n\t\t\t\t\ttrimmedIdentifier.includes(\".\") &&\n\t\t\t\t\t!trimmedIdentifier.includes(\" \")\n\t\t\t\t) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tnew URL(`https://${trimmedIdentifier}`);\n\t\t\t\t\t\treturn { type: \"url\", value: `https://${trimmedIdentifier}` };\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Still not valid\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Default to custom\n\t\t\treturn { type: \"custom\", value: trimmedIdentifier };\n\t\t},\n\t\t[],\n\t);\n\n\tconst formatContextDisplay = useCallback(\n\t\t(type: MetaLensContextType, value: string): string => {\n\t\t\tswitch (type) {\n\t\t\t\tcase \"url\":\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst url = new URL(value);\n\t\t\t\t\t\treturn url.hostname + (url.pathname !== \"/\" ? url.pathname : \"\");\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\tcase \"tx\":\n\t\t\t\t\treturn `${value.substring(0, 8)}...${value.substring(56)}`;\n\t\t\t\tcase \"upc\":\n\t\t\t\t\treturn `Product ${value}`;\n\t\t\t\tcase \"geohash\":\n\t\t\t\t\treturn `Location ${value.substring(0, 6)}`;\n\t\t\t\tcase \"isbn\":\n\t\t\t\t\treturn `Book ISBN ${value}`;\n\t\t\t\tcase \"doi\":\n\t\t\t\t\treturn `Paper ${value}`;\n\t\t\t\tcase \"ipfs\":\n\t\t\t\t\treturn `IPFS ${value.substring(0, 12)}...`;\n\t\t\t\tdefault:\n\t\t\t\t\treturn value.length > 20 ? `${value.substring(0, 20)}...` : value;\n\t\t\t}\n\t\t},\n\t\t[],\n\t);\n\n\treturn {\n\t\tdetectContext,\n\t\tparseContext,\n\t\tformatContextDisplay,\n\t};\n}\n",
"target": "<%- config.aliases.hooks %>/usemetalenscontext.ts"
}
]
}