feat: preact-router and GraphInput node balance modifier

backup-1
Antonio De Lucreziis 2 years ago
parent 35759b6d1d
commit 160007eb0d

Binary file not shown.

@ -22,6 +22,7 @@
"@ruby/wasm-wasi": "^2.6.2", "@ruby/wasm-wasi": "^2.6.2",
"katex": "^0.16.11", "katex": "^0.16.11",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"preact-router": "^4.1.2",
"vite-plugin-wasm": "^3.3.0" "vite-plugin-wasm": "^3.3.0"
} }
} }

@ -20,18 +20,21 @@ export const View = ({}) => {
{ {
id: id1, id: id1,
label: '1', label: '1',
balance: 0,
x: 100 + Math.random() * 500, x: 100 + Math.random() * 500,
y: 100 + Math.random() * 300, y: 100 + Math.random() * 300,
}, },
{ {
id: id2, id: id2,
label: '2', label: '2',
balance: 0,
x: 100 + Math.random() * 500, x: 100 + Math.random() * 500,
y: 100 + Math.random() * 300, y: 100 + Math.random() * 300,
}, },
{ {
id: id3, id: id3,
label: '3', label: '3',
balance: 0,
x: 100 + Math.random() * 500, x: 100 + Math.random() * 500,
y: 100 + Math.random() * 300, y: 100 + Math.random() * 300,
}, },

@ -56,6 +56,7 @@ export const GraphInput = ({ graph, setGraph }) => {
{ {
id: crypto.randomUUID(9).split('-')[0], id: crypto.randomUUID(9).split('-')[0],
label: '?', label: '?',
balance: 0,
x, x,
y, y,
}, },
@ -193,7 +194,7 @@ export const GraphInput = ({ graph, setGraph }) => {
))} ))}
</div> </div>
<div class="nodes"> <div class="nodes">
{graph.nodes.map(({ id, label, x, y }, index) => ( {graph.nodes.map(({ id, label, balance, x, y }, index) => (
<div <div
class={[ class={[
'node', 'node',
@ -204,6 +205,49 @@ export const GraphInput = ({ graph, setGraph }) => {
.filter(Boolean) .filter(Boolean)
.join(' ')} .join(' ')}
style={{ '--x': x, '--y': y }} style={{ '--x': x, '--y': y }}
onKeyDown={e => {
if (
(e.key === 'Enter' || e.key === 'Escape') &&
interacting?.type === 'edit-node'
) {
setInteracting(false)
}
}}
>
<div class="popup">
<button
onClick={() => {
setGraph(g => {
const newNodes = [...g.nodes]
newNodes[index] = {
...g.nodes[index],
balance: g.nodes[index].balance + 1,
}
return { ...g, nodes: newNodes }
})
}}
>
+
</button>
<button
onClick={() => {
setGraph(g => {
const newNodes = [...g.nodes]
newNodes[index] = {
...g.nodes[index],
balance: g.nodes[index].balance - 1,
}
return { ...g, nodes: newNodes }
})
}}
>
-
</button>
</div>
<div
class="node-ball"
onMouseDown={e => { onMouseDown={e => {
if (interacting) return if (interacting) return
@ -242,14 +286,6 @@ export const GraphInput = ({ graph, setGraph }) => {
index, index,
}) })
}} }}
onKeyDown={e => {
if (
(e.key === 'Enter' || e.key === 'Escape') &&
interacting?.type === 'edit-node'
) {
setInteracting(false)
}
}}
> >
{interacting?.type === 'edit-node' && interacting.index === index ? ( {interacting?.type === 'edit-node' && interacting.index === index ? (
<input <input
@ -274,6 +310,16 @@ export const GraphInput = ({ graph, setGraph }) => {
label label
)} )}
</div> </div>
{balance !== 0 && (
<div class="balance">
{balance < 0 ? (
<>&minus;{Math.abs(balance)}</>
) : (
<>+{Math.abs(balance)}</>
)}
</div>
)}
</div>
))} ))}
</div> </div>
</div> </div>

@ -4,6 +4,7 @@ import '@fontsource/inter/latin.css'
import _ from 'lodash' import _ from 'lodash'
import { render } from 'preact' import { render } from 'preact'
import Router, { route } from 'preact-router'
import { useState } from 'preact/hooks' import { useState } from 'preact/hooks'
const ViewRegistry = Object.fromEntries( const ViewRegistry = Object.fromEntries(
@ -25,7 +26,7 @@ const NewAlgorithmBox = ({ title, description, onClick }) => (
</div> </div>
) )
const AlgorithmChooserView = ({ setCurrentView }) => { const AlgorithmChooserView = ({}) => {
const sections = _.groupBy(ViewRegistry, 'metadata.group') const sections = _.groupBy(ViewRegistry, 'metadata.group')
return ( return (
@ -41,7 +42,7 @@ const AlgorithmChooserView = ({ setCurrentView }) => {
<NewAlgorithmBox <NewAlgorithmBox
title={metadata.title} title={metadata.title}
description={metadata.description} description={metadata.description}
onClick={() => setCurrentView(id)} onClick={() => route(id)}
/> />
))} ))}
</div> </div>
@ -98,7 +99,12 @@ const App = ({}) => {
<h2>History</h2> <h2>History</h2>
</aside> </aside>
<main> <main>
<Main /> <Router>
<AlgorithmChooserView path="/" />
{Object.entries(ViewRegistry).map(([id, { View }]) => (
<View path={id} />
))}
</Router>
</main> </main>
</> </>
) )

@ -51,6 +51,22 @@ h6 {
/* Components */ /* Components */
button {
outline: none;
border: none;
background: #555;
color: #fff;
border-radius: 0.25rem;
cursor: pointer;
&:hover {
background: #777;
}
}
.boxes { .boxes {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -174,6 +190,19 @@ h6 {
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
pointer-events: all;
> .balance {
position: absolute;
top: 100%;
left: 50%;
font-size: 18px;
transform: translateX(-50%);
}
> .node-ball {
display: grid; display: grid;
place-content: center; place-content: center;
@ -184,14 +213,48 @@ h6 {
border: 2px solid #333; border: 2px solid #333;
border-radius: 1.25rem; border-radius: 1.25rem;
pointer-events: all;
cursor: move; cursor: move;
}
> .popup {
position: absolute;
z-index: -1;
inset: -0.25rem;
height: 4rem;
/* background: #e0e0e0dd;
border: 2px solid #333; */
/* border-radius: 0.5rem; */
display: flex;
flex-direction: column;
gap: 0.25rem;
right: -2.25rem;
top: 50%;
&.targeted { transform: translateY(-50%);
padding: 0.25rem;
padding-left: 3rem;
opacity: 0;
> * {
flex-grow: 1;
}
}
&.targeted > .node-ball {
color: #fff; color: #fff;
background: green; background: green;
} }
&:hover > .popup {
opacity: 1;
}
} }
} }
} }

Loading…
Cancel
Save