Skip to content

Commit e42275b

Browse files
authored
Datum compare, and other flair. (#12)
* init datum compare * intro shadcn * shadcn nav * metadata support * fix popover issue * better metadata formatting * optimize diff context scope
1 parent 9450451 commit e42275b

37 files changed

+2719
-581
lines changed

bun.lock

Lines changed: 411 additions & 2 deletions
Large diffs are not rendered by default.

components.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "new-york",
4+
"rsc": false,
5+
"tsx": true,
6+
"tailwind": {
7+
"config": "",
8+
"css": "src/index.css",
9+
"baseColor": "gray",
10+
"cssVariables": true,
11+
"prefix": ""
12+
},
13+
"aliases": {
14+
"components": "@/components",
15+
"utils": "@/lib/utils",
16+
"ui": "@/components/ui",
17+
"lib": "@/lib",
18+
"hooks": "@/hooks"
19+
},
20+
"iconLibrary": "lucide"
21+
}

package.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
},
1515
"dependencies": {
1616
"@dcspark/cardano-multiplatform-lib-browser": "^6.1.0",
17+
"@radix-ui/react-context-menu": "^2.2.15",
18+
"@radix-ui/react-dialog": "^1.1.14",
19+
"@radix-ui/react-popover": "^1.1.14",
20+
"@radix-ui/react-scroll-area": "^1.2.9",
21+
"@radix-ui/react-select": "^2.2.5",
22+
"@radix-ui/react-slot": "^1.2.3",
1723
"@tailwindcss/vite": "^4.0.14",
1824
"@tanstack/query-sync-storage-persister": "^5.69.0",
1925
"@tanstack/react-query": "^5.69.0",
@@ -24,21 +30,29 @@
2430
"@vitejs/plugin-react": "^4.4.1",
2531
"babel-plugin-react-compiler": "^19.1.0-rc.1",
2632
"cbor2": "^1.12.0",
33+
"class-variance-authority": "^0.7.1",
34+
"clsx": "^2.1.1",
35+
"cmdk": "^1.1.1",
2736
"convict": "^6.2.4",
2837
"dexie": "^4.0.11",
2938
"dexie-react-hooks": "^1.1.7",
39+
"diff": "^8.0.2",
3040
"fuse.js": "^7.1.0",
3141
"hast-util-to-jsx-runtime": "^2.3.6",
3242
"hono": "^4.7.6",
3343
"http-proxy": "^1.18.1",
3444
"json-bigint": "^1.0.0",
3545
"lru-cache": "^11.1.0",
46+
"lucide-react": "^0.511.0",
3647
"react": "^19.0.0",
3748
"react-dom": "^19.0.0",
3849
"react-router": "^7.4.0",
3950
"react-use": "^17.6.0",
4051
"refractor": "^5.0.0",
52+
"shadcn": "^2.5.0",
53+
"tailwind-merge": "^3.3.0",
4154
"tailwindcss": "^4.0.14",
55+
"vaul": "^1.1.2",
4256
"vite-plugin-babel": "^1.3.1",
4357
"yaml": "^2.7.1",
4458
"zod": "^3.24.2"
@@ -58,6 +72,7 @@
5872
"eslint-plugin-react-hooks": "^5.1.0",
5973
"eslint-plugin-react-refresh": "^0.4.19",
6074
"globals": "^15.15.0",
75+
"tw-animate-css": "^1.3.2",
6176
"typescript": "~5.7.2",
6277
"typescript-eslint": "^8.24.1",
6378
"vite": "^6.2.0",

src/App.tsx

Lines changed: 85 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,92 @@ function App() {
4444
client={queryClient}
4545
persistOptions={{ persister }}
4646
>
47-
<Providers>
48-
<Router>
49-
<Routes>
50-
<Route path="/tx" element={<TxViewPage />} />
51-
<Route path="/" element={<HomePage />} />
47+
<Router>
48+
<Routes>
49+
<Route
50+
path="/tx"
51+
element={
52+
<Providers>
53+
<TxViewPage />
54+
</Providers>
55+
}
56+
/>
57+
<Route
58+
path="/"
59+
element={
60+
<Providers>
61+
<HomePage />
62+
</Providers>
63+
}
64+
/>
5265

53-
<Route path="/tx/:txCbor?" element={<TxViewPage />} />
54-
<Route path="/registry" element={<RegistryPage />} />
55-
<Route path="/chain" element={<ChainPage />} />
56-
<Route path="/policy/:unit" element={<PolicyPage />} />
57-
<Route
58-
path="/submitted-tx/:txHash?"
59-
element={<SubmittedTxPage />}
60-
/>
61-
<Route path="/address/:address" element={<AddressPage />} />
62-
<Route path="/blueprint" element={<BlueprintPage />} />
63-
<Route path="/p/:id" element={<HandlePaste iface="sf" />} />
64-
</Routes>
65-
</Router>
66-
<ReactQueryDevtools initialIsOpen />
67-
</Providers>
66+
<Route
67+
path="/tx/:txCbor?"
68+
element={
69+
<Providers>
70+
<TxViewPage />
71+
</Providers>
72+
}
73+
/>
74+
<Route
75+
path="/registry"
76+
element={
77+
<Providers>
78+
<RegistryPage />
79+
</Providers>
80+
}
81+
/>
82+
<Route
83+
path="/chain"
84+
element={
85+
<Providers>
86+
<ChainPage />
87+
</Providers>
88+
}
89+
/>
90+
<Route
91+
path="/policy/:unit"
92+
element={
93+
<Providers>
94+
<PolicyPage />
95+
</Providers>
96+
}
97+
/>
98+
<Route
99+
path="/submitted-tx/:txHash?"
100+
element={
101+
<Providers>
102+
<SubmittedTxPage />
103+
</Providers>
104+
}
105+
/>
106+
<Route
107+
path="/address/:address"
108+
element={
109+
<Providers>
110+
<AddressPage />
111+
</Providers>
112+
}
113+
/>
114+
<Route
115+
path="/blueprint"
116+
element={
117+
<Providers>
118+
<BlueprintPage />
119+
</Providers>
120+
}
121+
/>
122+
<Route
123+
path="/p/:id"
124+
element={
125+
<Providers>
126+
<HandlePaste iface="sf" />
127+
</Providers>
128+
}
129+
/>
130+
</Routes>
131+
</Router>
132+
<ReactQueryDevtools initialIsOpen />
68133
</PersistQueryClientProvider>
69134
);
70135
}

src/cbor/raw_datum.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,64 @@ export const parseRawDatum = (rawDatum: unknown): RawDatum => {
7575

7676
return null;
7777
};
78+
79+
/// For metadata
80+
81+
/**
82+
* Metadata is encoded as JSON, but since map keys can be non-strings, it encodes it using `{ 'map': [{ 'k': <key>, 'v': <value> }] }'`
83+
*
84+
* The following function simplifies this structure when all keys are strings
85+
*/
86+
const simplifyObject = (
87+
obj: { k: unknown; v: unknown }[],
88+
): { [k: string]: unknown } | { k: unknown; v: unknown }[] => {
89+
const result: { [k: string]: unknown } = {};
90+
91+
console.log(obj);
92+
for (const { k, v } of obj) {
93+
if (
94+
typeof k === 'object' &&
95+
k !== null &&
96+
'string' in k &&
97+
typeof k.string === 'string'
98+
) {
99+
result[k.string] = simplifyMetadata(v);
100+
} else {
101+
// Not all keys are strings, return the original object!
102+
return obj;
103+
}
104+
}
105+
return result;
106+
};
107+
108+
/**
109+
* Simplifies metadata by doing the following:
110+
*
111+
* '{ "string": "value" }' -> "value"
112+
* '{ "int": 1 }' -> 1
113+
* '{ "map": <map> }' -> simplifyObject(<map>)
114+
*/
115+
export const simplifyMetadata = (metadata: unknown): unknown => {
116+
if (Array.isArray(metadata)) {
117+
return metadata.map(simplifyObject);
118+
} else if (
119+
typeof metadata === 'object' &&
120+
metadata !== null &&
121+
'map' in metadata
122+
) {
123+
return simplifyObject(metadata.map as { k: unknown; v: unknown }[]);
124+
} else if (
125+
typeof metadata === 'object' &&
126+
metadata !== null &&
127+
'string' in metadata
128+
) {
129+
return metadata.string;
130+
} else if (
131+
typeof metadata === 'object' &&
132+
metadata !== null &&
133+
'int' in metadata
134+
) {
135+
return metadata.int;
136+
}
137+
return metadata;
138+
};

src/components/Button.tsx

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)