Initial commit: KiddOs v3 React kiosk

- React 18 + Vite 5 hot-reload OS (800x480 Nord theme)
- 7 apps: Journal, Calculator, Drawing, CodeLab, Clock, Files, Scratch
- Cage + Cog Wayland kiosk, offline localStorage
- Scripts: dev.sh, run-kiosk.sh, run-prod.sh
This commit is contained in:
Elias Journal
2026-08-24 21:53:02 -04:00
commit 30f9148adb
45 changed files with 3075 additions and 0 deletions
+116
View File
@@ -0,0 +1,116 @@
# KiddOs v3 — React Hot Reload OS (Done)
**Browser kiosk + React + Vite HMR, no backend, no LVGL, offline-first.**
This is the finished v3 you'd been building. Just React, hot refresh, works on 800×480 DSI.
## What works now
- **React shell** `src/App.jsx`: header with clock, greeting, companion banner, favorites & recent (localStorage), category filters, 150px cards grid, settings drawer
- **7 apps** (all React components, no fork/exec):
- `Journal` — autosave 1.5s, word count, past list, companion banner, offline localStorage
- `Calculator` — touch 56px buttons, history in localStorage
- `Drawing` — canvas pen/eraser, size, undo, save PNG, works touch+mouse
- `CodeLab` — JS playground, 3 samples, auto-saves, safe `new Function`
- `Clock` — analog time, timer (1/3/5/10m), stopwatch
- `Files` — browse localStorage journal entries, show companion info
- `Scratch` — iframe scratch.mit.edu (needs online) + offline alternatives info
- **Styling**: dark #2E3440 Nord theme, 800×480 optimized, touch 36px+ targets
- **Hot reload**: Vite dev server on :5173, Cog loads http://localhost:5173, edits push <1s to DSI
- **Build**: 184KB JS, 55KB gzip, no backend, file:// also works via `dist/`
## How to run (proven commands)
**1. Stop old kiosks:**
```bash
sudo systemctl stop kiddos.service kiddos-browser.service journal-kiosk.service
```
**2. Start React dev server (SSH session 1):**
```bash
cd ~/KiddOsV3/webapp
npm run dev -- --host 0.0.0.0 --port 5173
# or
~/KiddOsV3/scripts/dev.sh
```
Vite: `Local: http://localhost:5173/`
**3. Put on DSI (SSH session 2):**
```bash
~/KiddOsV3/scripts/run-kiosk.sh
# which runs:
sudo openvt -f -c 1 -s -- env XDG_RUNTIME_DIR=/run/user/1000 cage -s -- \
cog --platform=wl http://localhost:5173 --bg-color=#2E3440 --doc-viewer
```
You should see React launcher on DSI, touch works (ft5x06 event7 via libinput seat0). Edit `src/App.jsx`, save, DSI updates instantly.
**Fallbacks:**
```bash
# Chromium if Cog touch cursor stuck middle
sudo openvt -f -c 1 -s -- env XDG_RUNTIME_DIR=/run/user/1000 cage -s -- \
chromium --kiosk --no-sandbox --ozone-platform=wayland --disable-gpu http://localhost:5173
# Static prod build (no dev server)
cd ~/KiddOsV3/webapp && npm run build
cage -s -- cog --platform=wl file://$PWD/dist/index.html --bg-color=#2E3440
# Hello world test (no React)
cage -s -- cog --platform=wl file:///home/elias/KiddOsV2/browser/hello.html --bg-color=#2E3440
```
**If touch cursor stuck middle:**
- `libinput list-devices` should show `10-0038 generic ft5x06 (79)` at event7
- cage needs it. Try without `WLR_NO_HARDWARE_CURSORS`, clean `/run/user/1000/wayland-*`
- Or try labwc compositor instead of cage (heavier but more compatible)
## Folder
```
KiddOsV3/
├── plan.md
├── README.md (this)
├── public/icons/ (128x128 PNGs reused from v1)
├── webapp/
│ ├── package.json (react 18, vite 5, @vitejs/plugin-react)
│ ├── vite.config.js (0.0.0.0:5173, hmr clientPort 5173, base ./)
│ ├── index.html
│ └── src/
│ ├── main.jsx
│ ├── index.css (Nord theme, 800x480 tweaks)
│ ├── App.jsx (OS shell + settings drawer)
│ └── apps/
│ ├── Journal.jsx
│ ├── Calculator.jsx
│ ├── Drawing.jsx
│ ├── CodeLab.jsx
│ ├── Clock.jsx
│ ├── Files.jsx
│ └── Scratch.jsx
└── scripts/
├── dev.sh
├── run-kiosk.sh
└── run-prod.sh
```
## Companion integration
- `elias_companion` writes `~/launcher_config/companion_message.txt` and `dashboard.md` (counts only)
- v3 reads `localStorage.kiddos_companion_message` if set
- To show live companion on React:
```bash
cat ~/launcher_config/companion_message.txt
# then in browser console:
localStorage.setItem('kiddos_companion_message', 'You wrote today - 1 entries!')
```
Future: add tiny python server endpoint `/api/companion` in v2 `server/server.py` or copy companion_message.txt into `webapp/public/` and fetch.
## Next steps (after prove)
1. Confirm hot reload works on DSI (edit App.jsx, see instantly)
2. Add more apps: Blockly offline (copy from v2), music, math games
3. Optionally re-add `server/server.py` for central sync (v2's local-first + central)
4. Only then systemd service using same working command (openvt -f -c 1 -s ...)
## Why not LVGL anymore
v1 LVGL had DRM master handover per app → “any app I try to open freeze and restarts the OS” (your report). Browser OS: one process owns DRM forever, apps are React components, no fork, no black screen.