Skip to content

Commit 699d75a

Browse files
committed
add support for session parsing, fixes #4
1 parent f96ba48 commit 699d75a

File tree

4 files changed

+117
-44
lines changed

4 files changed

+117
-44
lines changed

Diff for: biome.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
}
2323
},
2424
"linter": {
25-
"enabled": true,
25+
"enabled": false,
2626
"rules": {
2727
"recommended": true,
2828
"suspicious": {

Diff for: bun.lockb

32 Bytes
Binary file not shown.

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"dependencies": {
1313
"@tscircuit/pcb-viewer": "^1.10.17",
1414
"autoprefixer": "^10.4.20",
15-
"dsn-converter": "^0.0.10",
15+
"dsn-converter": "^0.0.26",
1616
"postcss": "^8.4.49",
1717
"react": "^18.3.1",
1818
"react-dom": "^18.3.1",

Diff for: src/App.tsx

+115-42
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,60 @@
11
import { useState, useCallback } from "react"
22
import { PCBViewer } from "@tscircuit/pcb-viewer"
3-
import { parseDsnToCircuitJson } from "dsn-converter"
3+
import {
4+
convertDsnSessionToCircuitJson,
5+
DsnPcb,
6+
DsnSession,
7+
parseDsnToCircuitJson,
8+
parseDsnToDsnJson,
9+
} from "dsn-converter"
410

511
function App() {
612
const [circuitJson, setCircuitJson] = useState<any>(null)
13+
const [inDsnSessionMode, setInDsnSessionMode] = useState(false)
14+
const [sessionFile, setSessionFile] = useState<string | null>(null)
15+
const [dsnPcbFile, setDsnPcbFile] = useState<string | null>(null)
16+
17+
const isSessionFileUploaded = Boolean(sessionFile)
18+
const isDsnPcbFileUploaded = Boolean(dsnPcbFile)
19+
20+
const processDsnUploadOrPaste = (content: string) => {
21+
if (!inDsnSessionMode) {
22+
try {
23+
const json = parseDsnToCircuitJson(content)
24+
setCircuitJson(json)
25+
} catch (err) {
26+
console.log(err)
27+
console.error("Failed to parse DSN content:", err)
28+
alert("Failed to parse DSN content. Please check the format.")
29+
}
30+
return
31+
}
32+
33+
let dsnPcbContent = dsnPcbFile
34+
let sessionContent = sessionFile
35+
36+
if (content.trim().startsWith("(pcb")) {
37+
dsnPcbContent = content
38+
setDsnPcbFile(content)
39+
}
40+
41+
if (content.trim().startsWith("(session")) {
42+
sessionContent = content
43+
setSessionFile(content)
44+
}
45+
46+
if (sessionContent && dsnPcbContent) {
47+
const dsnPcb = parseDsnToDsnJson(dsnPcbContent) as DsnPcb
48+
const dsnSession = parseDsnToDsnJson(sessionContent) as DsnSession
49+
try {
50+
setCircuitJson(convertDsnSessionToCircuitJson(dsnPcb, dsnSession))
51+
} catch (err) {
52+
console.log(err)
53+
console.error("Failed to convert DSN session to circuit JSON:", err)
54+
alert("Failed to convert DSN session to circuit JSON.")
55+
}
56+
}
57+
}
758

859
const handleDrop = useCallback((e: React.DragEvent) => {
960
e.preventDefault()
@@ -12,13 +63,7 @@ function App() {
1263
const reader = new FileReader()
1364
reader.onload = async (e) => {
1465
const dsnContent = e.target?.result as string
15-
try {
16-
const json = parseDsnToCircuitJson(dsnContent)
17-
setCircuitJson(json)
18-
} catch (err) {
19-
console.error("Failed to parse DSN file:", err)
20-
alert("Failed to parse DSN file. Please check the format.")
21-
}
66+
processDsnUploadOrPaste(dsnContent)
2267
}
2368
reader.readAsText(file)
2469
}
@@ -27,13 +72,7 @@ function App() {
2772
const handlePaste = useCallback((e: React.ClipboardEvent) => {
2873
const dsnContent = e.clipboardData.getData("text")
2974
if (dsnContent) {
30-
try {
31-
const json = parseDsnToCircuitJson(dsnContent)
32-
setCircuitJson(json)
33-
} catch (err) {
34-
console.error("Failed to parse DSN content:", err)
35-
alert("Failed to parse DSN content. Please check the format.")
36-
}
75+
processDsnUploadOrPaste(dsnContent)
3776
}
3877
}, [])
3978

@@ -54,33 +93,67 @@ function App() {
5493
<h1 className="text-3xl font-bold mb-4">
5594
Specctra DSN File Viewer
5695
</h1>
57-
<p className="text-gray-400 mb-2">Drag and drop a DSN file here</p>
58-
<p className="text-gray-400">
59-
or paste DSN content with Ctrl/CMD+V
60-
</p>
61-
{/* biome-ignore lint/a11y/useKeyWithClickEvents: <explanation> */}
62-
<div
63-
className="underline cursor-pointer"
64-
onClick={() => {
65-
fetch("/exampledsn.dsn")
66-
.then((response) => response.text())
67-
.then((dsnContent) => {
68-
try {
69-
const json = parseDsnToCircuitJson(dsnContent)
70-
setCircuitJson(json)
71-
} catch (err) {
72-
console.error("Failed to parse example DSN:", err)
73-
alert("Failed to parse example DSN file.")
74-
}
75-
})
76-
.catch((err) => {
77-
console.error("Failed to load example DSN:", err)
78-
alert("Failed to load example DSN file.")
79-
})
80-
}}
81-
>
82-
open example
83-
</div>
96+
{!inDsnSessionMode && (
97+
<>
98+
<p className="text-gray-400 mb-2">
99+
Drag and drop a DSN file here
100+
</p>
101+
<p className="text-gray-400">
102+
or paste DSN content with Ctrl/CMD+V
103+
</p>
104+
</>
105+
)}
106+
{inDsnSessionMode && (
107+
<>
108+
<p className="text-gray-400 mb-2">
109+
Drag and drop or paste a DSN session and original (DSN PCB)
110+
file here
111+
</p>
112+
<p className="text-gray-400">
113+
You must upload both files to see the results.
114+
</p>
115+
<p className="text-gray-400">
116+
{isSessionFileUploaded ? "✅" : "❌"} Session file uploaded
117+
</p>
118+
<p className="text-gray-400">
119+
{isDsnPcbFileUploaded ? "✅" : "❌"} DSN PCB file uploaded
120+
</p>
121+
</>
122+
)}
123+
{!inDsnSessionMode && (
124+
<div className="flex gap-4 justify-center">
125+
<div
126+
className="underline cursor-pointer"
127+
onClick={() => {
128+
fetch("/exampledsn.dsn")
129+
.then((response) => response.text())
130+
.then((dsnContent) => {
131+
try {
132+
const json = parseDsnToCircuitJson(dsnContent)
133+
setCircuitJson(json)
134+
} catch (err) {
135+
console.error("Failed to parse example DSN:", err)
136+
alert("Failed to parse example DSN file.")
137+
}
138+
})
139+
.catch((err) => {
140+
console.error("Failed to load example DSN:", err)
141+
alert("Failed to load example DSN file.")
142+
})
143+
}}
144+
>
145+
open example
146+
</div>
147+
<div
148+
className="underline cursor-pointer"
149+
onClick={() => {
150+
setInDsnSessionMode(true)
151+
}}
152+
>
153+
upload session
154+
</div>
155+
</div>
156+
)}
84157
</div>
85158
<div className="text-gray-400 text-sm mt-16">
86159
Unofficial Specctra DSN Parser/Viewer created by{" "}

0 commit comments

Comments
 (0)