-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 4fc03ee
Showing
23 changed files
with
1,073 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
name: Deploy content to Pages | ||
|
||
on: | ||
push: | ||
branches: ["master"] | ||
workflow_dispatch: | ||
|
||
permissions: | ||
contents: read | ||
pages: write | ||
id-token: write | ||
|
||
concurrency: | ||
group: "pages" | ||
cancel-in-progress: true | ||
|
||
jobs: | ||
deploy: | ||
environment: | ||
name: github-pages | ||
url: ${{ steps.deployment.outputs.page_url }} | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
- name: Install bun | ||
uses: oven-sh/setup-bun@v1 | ||
- name: Build all tools | ||
run: ./build.sh | ||
- name: Setup Pages | ||
uses: actions/configure-pages@v3 | ||
- name: Upload artifact | ||
uses: actions/upload-pages-artifact@v1 | ||
with: | ||
path: "dist/" | ||
- name: Deploy to GitHub Pages | ||
id: deployment | ||
uses: actions/deploy-pages@v1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
dist/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
pnpm-debug.log* | ||
lerna-debug.log* | ||
|
||
node_modules | ||
dist | ||
dist-ssr | ||
*.local | ||
|
||
# Editor directories and files | ||
.vscode/* | ||
!.vscode/extensions.json | ||
.idea | ||
.DS_Store | ||
*.suo | ||
*.ntvs* | ||
*.njsproj | ||
*.sln | ||
*.sw? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
## Usage | ||
|
||
```bash | ||
$ npm install # or pnpm install or yarn install | ||
``` | ||
|
||
### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs) | ||
|
||
## Available Scripts | ||
|
||
In the project directory, you can run: | ||
|
||
### `npm run dev` | ||
|
||
Runs the app in the development mode.<br> | ||
Open [http://localhost:5173](http://localhost:5173) to view it in the browser. | ||
|
||
### `npm run build` | ||
|
||
Builds the app for production to the `dist` folder.<br> | ||
It correctly bundles Solid in production mode and optimizes the build for the best performance. | ||
|
||
The build is minified and the filenames include the hashes.<br> | ||
Your app is ready to be deployed! | ||
|
||
## Deployment | ||
|
||
Learn more about deploying your application with the [documentations](https://vitejs.dev/guide/static-deploy.html) |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Beacon Plotter</title> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
<script type="module" src="/src/index.tsx"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"name": "beacon_plotter", | ||
"private": true, | ||
"version": "0.0.0", | ||
"type": "module", | ||
"scripts": { | ||
"dev": "vite", | ||
"build": "tsc && vite build", | ||
"preview": "vite preview" | ||
}, | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"@fortawesome/free-solid-svg-icons": "^6.4.2", | ||
"@solid-primitives/resize-observer": "^2.0.22", | ||
"@types/d3-axis": "^3.0.6", | ||
"@types/d3-scale": "^4.0.8", | ||
"@types/d3-selection": "^3.0.10", | ||
"@types/luxon": "^3.3.4", | ||
"autoprefixer": "^10.4.16", | ||
"d3-axis": "^3.0.0", | ||
"d3-selection": "^3.0.0", | ||
"eventemitter3": "^5.0.1", | ||
"luxon": "^3.4.4", | ||
"postcss": "^8.4.31", | ||
"solid-fa": "^0.2.0", | ||
"solid-js": "^1.7.8", | ||
"tailwindcss": "^3.3.5", | ||
"timechart": "beta", | ||
"typescript": "^5.0.2", | ||
"vite": "^4.4.5", | ||
"vite-plugin-solid": "^2.7.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export default { | ||
plugins: { | ||
tailwindcss: {}, | ||
autoprefixer: {}, | ||
}, | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
@tailwind base; | ||
@tailwind components; | ||
@tailwind utilities; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,243 @@ | ||
import { | ||
Accessor, | ||
Show, | ||
createEffect, | ||
createSignal, | ||
onCleanup, | ||
For, | ||
ValidComponent, | ||
createMemo, | ||
Switch, | ||
Match, | ||
} from "solid-js"; | ||
import { createStore } from "solid-js/store"; | ||
import { Fa } from "solid-fa"; | ||
import { faGear } from "@fortawesome/free-solid-svg-icons"; | ||
import "./App.css"; | ||
import { Dynamic } from "solid-js/web"; | ||
import { BeaconStreamDumper, Sample } from "./stream_dumper"; | ||
import { SampleChart } from "./sample_chart"; | ||
|
||
const precision_rounder = (d: number) => { | ||
return (v: number) => { | ||
return v.toFixed(d); | ||
}; | ||
}; | ||
const rp1 = precision_rounder(1); | ||
const rp2 = precision_rounder(2); | ||
const rp3 = precision_rounder(3); | ||
const rp4 = precision_rounder(4); | ||
|
||
interface DataFieldProps { | ||
last_sample: Accessor<Sample>; | ||
} | ||
|
||
const DataFields: [string, ValidComponent][] = [ | ||
["Dist", (props: DataFieldProps) => <>{rp4(props.last_sample().dist)}</>], | ||
["Freq", (props: DataFieldProps) => <>{rp3(props.last_sample().dist)}</>], | ||
[ | ||
"Pos", | ||
(props: DataFieldProps) => ( | ||
<Show | ||
when={props.last_sample().pos} | ||
fallback={<span class="text-yellow-800">-</span>} | ||
> | ||
{props.last_sample().pos!.map(rp2).join(",") || "-"} | ||
</Show> | ||
), | ||
], | ||
["Temp", (props: DataFieldProps) => <>{rp1(props.last_sample().temp)}</>], | ||
["Time", (props: DataFieldProps) => <>{rp3(props.last_sample().time)}</>], | ||
[ | ||
"Vel", | ||
(props: DataFieldProps) => { | ||
const vel = createMemo(() => { | ||
const vel = props.last_sample()?.vel; | ||
return vel ? rp2(vel) : undefined; | ||
}); | ||
return ( | ||
<Show | ||
when={vel() != undefined} | ||
fallback={<span class="text-yellow-800">-</span>} | ||
> | ||
{vel()!} | ||
</Show> | ||
); | ||
}, | ||
], | ||
]; | ||
|
||
function App() { | ||
const [last_sample, set_last_sample] = createSignal<Sample>(); | ||
|
||
const saved_settings = localStorage.getItem("settings"); | ||
let init_settings = { | ||
domain: "", | ||
port: 80, | ||
secure: false, | ||
}; | ||
if (saved_settings) { | ||
init_settings = { ...init_settings, ...JSON.parse(saved_settings) }; | ||
} | ||
const [settings, set_settings] = createStore(init_settings); | ||
|
||
createEffect(() => { | ||
localStorage.setItem("settings", JSON.stringify(settings)); | ||
}); | ||
|
||
const source_url = createMemo(() => { | ||
if (!settings.domain || !settings.port) return undefined; | ||
return `ws${settings.secure ? "s" : ""}://${settings.domain}:${ | ||
settings.port | ||
}/klippysocket`; | ||
}); | ||
|
||
const [raw_source, set_raw_source] = createSignal<BeaconStreamDumper>(); | ||
const connect = () => { | ||
const url = source_url(); | ||
if (url) { | ||
set_raw_source(new BeaconStreamDumper(url)); | ||
} | ||
}; | ||
|
||
const source = createMemo(() => { | ||
const src = raw_source(); | ||
if (!src || !src.state.receiving) return undefined; | ||
return src; | ||
}); | ||
|
||
createEffect(() => { | ||
const sd = source(); | ||
if (!sd) return; | ||
const cb = (samples: Sample[]) => { | ||
if (samples.length) { | ||
set_last_sample(samples[samples.length - 1]); | ||
} | ||
}; | ||
sd.addListener("samples", cb); | ||
onCleanup(() => sd.removeListener("samples", cb)); | ||
}); | ||
|
||
const [highlighted_point, set_highlighted_point] = createSignal< | ||
Sample | undefined | ||
>(); | ||
|
||
return ( | ||
<Switch> | ||
<Match when={!source()}> | ||
<div class="absolute inset-0 flex flex-col justify-center bg-slate-950 text-black"> | ||
<div class="mx-auto container max-w-screen-sm bg-gray-300 rounded-lg p-4"> | ||
<Show | ||
when={!raw_source()?.state.connected} | ||
fallback={ | ||
<h1 class="text-lg font-bold">Awaiting initial data</h1> | ||
} | ||
> | ||
<h1 class="text-xl font-bold mb-3">Connection details</h1> | ||
<div class="mb-3"> | ||
<label | ||
class="block mb-2 text-sm font-medium text-gray-900" | ||
for="ip" | ||
> | ||
Moonraker IP address or domain | ||
</label> | ||
<input | ||
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" | ||
type="ip" | ||
id="ip" | ||
value={settings.domain} | ||
onInput={(e) => set_settings("domain", e.currentTarget.value)} | ||
/> | ||
</div> | ||
<div class="mb-3"> | ||
<label | ||
class="block mb-2 text-sm font-medium text-gray-900" | ||
for="ip" | ||
> | ||
Moonraker port | ||
</label> | ||
<input | ||
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" | ||
type="ip" | ||
id="ip" | ||
value={settings.port} | ||
onInput={[set_settings, "port"]} | ||
/> | ||
</div> | ||
<div class="flex flex-row items-center gap-3"> | ||
<button | ||
type="button" | ||
classList={{ | ||
"text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center w-max": | ||
true, | ||
"bg-gray-700": !source_url(), | ||
}} | ||
onClick={connect} | ||
disabled={raw_source()?.state.connecting || !source_url()} | ||
> | ||
<Show when={raw_source()?.state.connecting}> | ||
<Fa | ||
icon={faGear} | ||
spin={true} | ||
classList={{ "inline-block": true, "mr-2": true }} | ||
/> | ||
</Show> | ||
Connect | ||
</button> | ||
<Show when={raw_source()?.state.last_error}> | ||
{(error) => ( | ||
<div class="text-red-600 font-bold"> | ||
Connection error: {error()} | ||
</div> | ||
)} | ||
</Show> | ||
</div> | ||
</Show> | ||
</div> | ||
</div> | ||
</Match> | ||
<Match when={source()}> | ||
{(source) => ( | ||
<div class="absolute inset-0 flex flex-col bg-slate-950 text-yellow-300"> | ||
<SampleChart | ||
class="grow" | ||
set_highlighted_point={set_highlighted_point} | ||
source={source} | ||
/> | ||
<Show when={highlighted_point() || last_sample()}> | ||
{(last_sample) => ( | ||
<div> | ||
<div | ||
class="text-xs font-extrabold bg-slate-950 w-max mx-2" | ||
style={{ "margin-bottom": "-8px" }} | ||
> | ||
<Show when={highlighted_point()} fallback={"Last sample"}> | ||
Sample under cursor | ||
</Show> | ||
</div> | ||
<div class="grid grid-cols-6 px-2 pt-3 border-t border-slate-600"> | ||
<For each={DataFields}> | ||
{([title, formatter]) => ( | ||
<div class="flex-col odd:bg-slate-900 px-2"> | ||
<div class="font-extrabold text-sm">{title}</div> | ||
<div> | ||
<Dynamic | ||
component={formatter} | ||
last_sample={last_sample} | ||
/> | ||
</div> | ||
</div> | ||
)} | ||
</For> | ||
</div> | ||
</div> | ||
)} | ||
</Show> | ||
</div> | ||
)} | ||
</Match> | ||
</Switch> | ||
); | ||
} | ||
|
||
export default App; |
Oops, something went wrong.