diff --git a/app/__pycache__/server.cpython-312.pyc b/app/__pycache__/server.cpython-312.pyc index 4899fff..301628d 100644 Binary files a/app/__pycache__/server.cpython-312.pyc and b/app/__pycache__/server.cpython-312.pyc differ diff --git a/app/server.py b/app/server.py index 093709a..1cfb0d3 100644 --- a/app/server.py +++ b/app/server.py @@ -12,6 +12,7 @@ import waitress from flask import Flask, render_template, send_from_directory from flask_socketio import SocketIO, emit from ntcore import util +import os def signal_handler(_signal: int, _frame) -> None: @@ -23,7 +24,7 @@ signal.signal(signal.SIGINT, signal_handler) # initialize flask app and socketio -app = Flask(__name__, static_folder="dist") +app = Flask(__name__, static_folder="dist", static_url_path="/") socketio = SocketIO(app) inst = ntcore.NetworkTableInstance.getDefault() @@ -79,15 +80,18 @@ def choose(key: str, selection: str) -> str: # Route for serving dynamic content (all files within dist/) +@app.route("/static/") +def custom_static(filename): + return send_from_directory("static", filename) + + +@app.route("/", defaults={"path": ""}) @app.route("/") -def serve_file(path): - return send_from_directory("dist", path) - - -# Special route for the root to serve index.html -@app.route("/") -def serve_index(): - return send_from_directory("dist", "index.html") +def serve(path): + if path != "" and os.path.exists(app.static_folder + "/" + path): + return send_from_directory(app.static_folder, path) + else: + return send_from_directory(app.static_folder, "index.html") def start(**server_kwargs: dict) -> None: @@ -110,6 +114,12 @@ def connect() -> None: """Handle client connection.""" +@socketio.on("ping") +def ping() -> None: + emit("pong") + print("pinged!") + + @socketio.on("request_data") def request(obj: dict) -> None: """Handle client telemetry request. diff --git a/app/static/app-icons/camera.png b/app/static/app-icons/camera.png new file mode 100644 index 0000000..dc77cdf Binary files /dev/null and b/app/static/app-icons/camera.png differ diff --git a/app/static/app-icons/media-player.png b/app/static/app-icons/media-player.png new file mode 100644 index 0000000..76fc301 Binary files /dev/null and b/app/static/app-icons/media-player.png differ diff --git a/app/static/songs/danger-zone/audio.mp3 b/app/static/songs/danger-zone/audio.mp3 new file mode 100644 index 0000000..25e367e Binary files /dev/null and b/app/static/songs/danger-zone/audio.mp3 differ diff --git a/app/static/songs/danger-zone/cover.png b/app/static/songs/danger-zone/cover.png new file mode 100644 index 0000000..c4968ef Binary files /dev/null and b/app/static/songs/danger-zone/cover.png differ diff --git a/client/package-lock.json b/client/package-lock.json index 2dd59fe..9b723cb 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -7,6 +7,12 @@ "": { "name": "-client", "version": "0.0.0", + "dependencies": { + "@fontsource/roboto": "^5.0.8", + "material-icons": "^1.13.12", + "material-symbols": "^0.15.0", + "socket.io-client": "^4.7.4" + }, "devDependencies": { "@sveltejs/adapter-static": "^3.0.1", "@sveltejs/vite-plugin-svelte": "^3.0.2", @@ -414,6 +420,11 @@ "node": ">=12" } }, + "node_modules/@fontsource/roboto": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.0.8.tgz", + "integrity": "sha512-XxPltXs5R31D6UZeLIV1td3wTXU3jzd3f2DLsXI8tytMGBkIsGcc9sIyiupRtA8y73HAhuSCeweOoBqf6DbWCA==" + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -700,6 +711,11 @@ "win32" ] }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, "node_modules/@sveltejs/adapter-static": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.1.tgz", @@ -1161,7 +1177,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -1238,6 +1253,26 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/engine.io-client": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz", + "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", + "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/es6-promise": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", @@ -1665,6 +1700,16 @@ "node": ">=12" } }, + "node_modules/material-icons": { + "version": "1.13.12", + "resolved": "https://registry.npmjs.org/material-icons/-/material-icons-1.13.12.tgz", + "integrity": "sha512-/2YoaB79IjUK2B2JB+vIXXYGtBfHb/XG66LvoKVM5ykHW7yfrV5SP6d7KLX6iijY6/G9GqwgtPQ/sbhFnOURVA==" + }, + "node_modules/material-symbols": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/material-symbols/-/material-symbols-0.15.0.tgz", + "integrity": "sha512-216LRlmN8fZb0CoIOaQBmRZ55BptWcd7z//0v7dXQA6aogsvI9Qp1nMQ5jZ44dbgBXntUQzWdB5Q2D+6bJXioA==" + }, "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", @@ -1766,8 +1811,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mz": { "version": "2.7.0", @@ -2320,6 +2364,32 @@ "node": ">= 10" } }, + "node_modules/socket.io-client": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.4.tgz", + "integrity": "sha512-wh+OkeF0rAVCrABWQBaEjLfb7DVPotMbu0cgWgyR0v6eA4EoVnAwcIeIbcdTE3GT/H3kbdLl7OoH2+asoDRIIg==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/sorcery": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.0.tgz", @@ -2999,6 +3069,34 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/yaml": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", diff --git a/client/package.json b/client/package.json index 74ad392..3492f2b 100644 --- a/client/package.json +++ b/client/package.json @@ -21,5 +21,11 @@ "tslib": "^2.6.2", "typescript": "^5.2.2", "vite": "^5.1.4" + }, + "dependencies": { + "@fontsource/roboto": "^5.0.8", + "material-icons": "^1.13.12", + "material-symbols": "^0.15.0", + "socket.io-client": "^4.7.4" } } diff --git a/client/src/App.svelte b/client/src/App.svelte index 9aac21e..a419633 100644 --- a/client/src/App.svelte +++ b/client/src/App.svelte @@ -1,13 +1,47 @@ -
+
+ +
+ +
+ +
+ +
+ +
+
+ +
+
+
diff --git a/client/src/app.css b/client/src/app.css index 79af57d..809c4f0 100644 --- a/client/src/app.css +++ b/client/src/app.css @@ -14,6 +14,6 @@ } body { - @apply bg-black; + @apply bg-black text-white; } } diff --git a/client/src/globals.d.ts b/client/src/globals.d.ts new file mode 100644 index 0000000..93ce3e9 --- /dev/null +++ b/client/src/globals.d.ts @@ -0,0 +1,21 @@ +type Gear = 'p' | 'r' | 'n' | 'l' | 'a' | 'd' + +type Mode = 'chill' | 'ludicrous' | 'cruise' + +type App = 'camera' | 'media-player' + +interface SongData { + title: string + artist: string + src: string + coverImg: string + slug: string +} + +interface AppData { + [key: App]: { + name: string + component: SvelteComponent + icon: string + } +} diff --git a/client/src/lib/Apps/AppBar.svelte b/client/src/lib/Apps/AppBar.svelte new file mode 100644 index 0000000..e0d0b30 --- /dev/null +++ b/client/src/lib/Apps/AppBar.svelte @@ -0,0 +1,36 @@ + + + +
+ {#each Object.entries(appList) as [appName, appData]} + + {/each} +
+ + diff --git a/client/src/lib/Apps/Camera/Camera.svelte b/client/src/lib/Apps/Camera/Camera.svelte new file mode 100644 index 0000000..c445404 --- /dev/null +++ b/client/src/lib/Apps/Camera/Camera.svelte @@ -0,0 +1,34 @@ + + +
+
+ +
+
+ +
+
+ + diff --git a/client/src/lib/Apps/Camera/CameraContainer.svelte b/client/src/lib/Apps/Camera/CameraContainer.svelte new file mode 100644 index 0000000..875d356 --- /dev/null +++ b/client/src/lib/Apps/Camera/CameraContainer.svelte @@ -0,0 +1,13 @@ + + +
+ camera feed +
diff --git a/client/src/lib/Apps/Camera/icon.png b/client/src/lib/Apps/Camera/icon.png new file mode 100644 index 0000000..dc77cdf Binary files /dev/null and b/client/src/lib/Apps/Camera/icon.png differ diff --git a/client/src/lib/Apps/MusicPlayer/MusicBrowser.svelte b/client/src/lib/Apps/MusicPlayer/MusicBrowser.svelte new file mode 100644 index 0000000..b9da24c --- /dev/null +++ b/client/src/lib/Apps/MusicPlayer/MusicBrowser.svelte @@ -0,0 +1,22 @@ + + +
+ {#each songList as song} + + {/each} +
+ + diff --git a/client/src/lib/Apps/MusicPlayer/Song.svelte b/client/src/lib/Apps/MusicPlayer/Song.svelte new file mode 100644 index 0000000..7a1e357 --- /dev/null +++ b/client/src/lib/Apps/MusicPlayer/Song.svelte @@ -0,0 +1,33 @@ + + +
+ album cover +

{title}

+

{artist}

+
+
+ + + +
+
+
+ + diff --git a/client/src/lib/Apps/MusicPlayer/songList.ts b/client/src/lib/Apps/MusicPlayer/songList.ts new file mode 100644 index 0000000..8e231dd --- /dev/null +++ b/client/src/lib/Apps/MusicPlayer/songList.ts @@ -0,0 +1,30 @@ +export const songList = [ + { + title: 'Danger Zone', + artist: 'Kenny Loggins', + src: '/static/songs/danger-zone/audio.mp3', + coverImg: '/static/songs/danger-zone/cover.png', + slug: 'danger-zone', + }, + { + title: 'Danger Zone', + artist: 'Kenny Loggins', + src: '/static/songs/danger-zone/audio.mp3', + coverImg: '/static/songs/danger-zone/cover.png', + slug: 'danger-zone', + }, + { + title: 'Danger Zone', + artist: 'Kenny Loggins', + src: '/static/songs/danger-zone/audio.mp3', + coverImg: '/static/songs/danger-zone/cover.png', + slug: 'danger-zone', + }, + { + title: 'Danger Zone', + artist: 'Kenny Loggins', + src: '/static/songs/danger-zone/audio.mp3', + coverImg: '/static/songs/danger-zone/cover.png', + slug: 'danger-zone', + }, +] diff --git a/client/src/lib/Apps/appList.ts b/client/src/lib/Apps/appList.ts new file mode 100644 index 0000000..2de0990 --- /dev/null +++ b/client/src/lib/Apps/appList.ts @@ -0,0 +1,15 @@ +import Camera from './Camera/Camera.svelte' +import MusicBrowser from './MusicPlayer/MusicBrowser.svelte' + +export const appList = { + 'camera': { + name: 'Camera', + component: Camera, + icon: '/static/app-icons/camera.png', + }, + 'media-player': { + name: 'Media Player', + component: MusicBrowser, + icon: '/static/app-icons/media-player.png', + }, +} diff --git a/client/src/lib/Dashboard/Dashboard.svelte b/client/src/lib/Dashboard/Dashboard.svelte new file mode 100644 index 0000000..1c48c0f --- /dev/null +++ b/client/src/lib/Dashboard/Dashboard.svelte @@ -0,0 +1,21 @@ + + +
+
+ +
+
+ + +
+
+ +
+ +
+
diff --git a/client/src/lib/Dashboard/MediaDisplay/Controls.svelte b/client/src/lib/Dashboard/MediaDisplay/Controls.svelte new file mode 100644 index 0000000..1cebede --- /dev/null +++ b/client/src/lib/Dashboard/MediaDisplay/Controls.svelte @@ -0,0 +1,28 @@ + + +
+ + {#if playing} + + {:else} + + {/if} + +
+ + diff --git a/client/src/lib/Dashboard/MediaDisplay/MediaDisplay.svelte b/client/src/lib/Dashboard/MediaDisplay/MediaDisplay.svelte new file mode 100644 index 0000000..bee6783 --- /dev/null +++ b/client/src/lib/Dashboard/MediaDisplay/MediaDisplay.svelte @@ -0,0 +1,20 @@ + + +
+
+
+ album cover +
+
+

Danger Zone

+

Kenny Loggins

+
+
+ +
diff --git a/client/src/lib/Dashboard/SpeedLimit.svelte b/client/src/lib/Dashboard/SpeedLimit.svelte new file mode 100644 index 0000000..3e98609 --- /dev/null +++ b/client/src/lib/Dashboard/SpeedLimit.svelte @@ -0,0 +1,18 @@ + + +
+
+
+ SPEED
LIMIT +
+
{formatted}
+
+
diff --git a/client/src/lib/Dashboard/Speedometer.svelte b/client/src/lib/Dashboard/Speedometer.svelte new file mode 100644 index 0000000..38a1fd1 --- /dev/null +++ b/client/src/lib/Dashboard/Speedometer.svelte @@ -0,0 +1,11 @@ + + +
+
{formatted}
+
MPH
+
diff --git a/client/src/lib/Dashboard/TopBar/BatteryDisplay.svelte b/client/src/lib/Dashboard/TopBar/BatteryDisplay.svelte new file mode 100644 index 0000000..deeddd0 --- /dev/null +++ b/client/src/lib/Dashboard/TopBar/BatteryDisplay.svelte @@ -0,0 +1,18 @@ + + + +
+ {formatted} V +
+ battery_horiz_075 +
+ + diff --git a/client/src/lib/Dashboard/TopBar/GearSelector.svelte b/client/src/lib/Dashboard/TopBar/GearSelector.svelte new file mode 100644 index 0000000..8626b4f --- /dev/null +++ b/client/src/lib/Dashboard/TopBar/GearSelector.svelte @@ -0,0 +1,20 @@ + + +
+
+
P
+
R
+
N
+
L
+
A
+
D
+
+
+ + diff --git a/client/src/lib/Dashboard/TopBar/ModeSelector.svelte b/client/src/lib/Dashboard/TopBar/ModeSelector.svelte new file mode 100644 index 0000000..727507e --- /dev/null +++ b/client/src/lib/Dashboard/TopBar/ModeSelector.svelte @@ -0,0 +1,21 @@ + + +
+ {modeText} +
diff --git a/client/src/lib/Dashboard/TopBar/TopBar.svelte b/client/src/lib/Dashboard/TopBar/TopBar.svelte new file mode 100644 index 0000000..87ba9cf --- /dev/null +++ b/client/src/lib/Dashboard/TopBar/TopBar.svelte @@ -0,0 +1,17 @@ + + +
+
+ +
+
+ +
+
+ +
+
diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index c55f628..0000000 --- a/package-lock.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "jankboard-2", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@fontsource/roboto": "^5.0.8" - } - }, - "node_modules/@fontsource/roboto": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.0.8.tgz", - "integrity": "sha512-XxPltXs5R31D6UZeLIV1td3wTXU3jzd3f2DLsXI8tytMGBkIsGcc9sIyiupRtA8y73HAhuSCeweOoBqf6DbWCA==" - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index abe2e29..0000000 --- a/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "@fontsource/roboto": "^5.0.8" - } -}