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:
@@ -0,0 +1,124 @@
|
||||
# KiddOs v3 — Plan: Browser Kiosk + React Hot Reload, No Backend
|
||||
|
||||
## Goal
|
||||
From-scratch v3, **just webapp React with hot refresh**, no server, no LVGL, no backend. Use the proven kiosk command that shows web on DSI:
|
||||
|
||||
```bash
|
||||
cage -s -- \
|
||||
cog --platform=wl file:///home/elias/KiddOsV2/browser/hello.html --bg-color=#2E3440
|
||||
```
|
||||
|
||||
That command is Method 2a that you confirmed works: `cage` (tiny Wayland kiosk compositor, 82KB) owns DRM/KMS on `/dev/dri/card1` (DSI 800x480 connector id 49), creates Wayland socket in `$XDG_RUNTIME_DIR`, `cog --platform=wl` (WPE WebKit, ~10MB) connects as Wayland client and renders HTML. No X11, no black flicker from fork/exec.
|
||||
|
||||
For v3 we keep that exact command, but point it to a **React dev server** for hot refresh instead of static file://
|
||||
|
||||
## Why No Backend?
|
||||
- v2 had `server/server.py` local-first + central sync. Good architecture but adds complexity.
|
||||
- v3 requirement: **just webapp react with hot refresh on code changes so we can quickly iterate**.
|
||||
- So: Vite dev server on Pi itself `http://localhost:5173` serves React, Cog loads that URL, and Vite HMR pushes changes instantly to DSI — you edit `src/App.jsx` on laptop via SSH, DSI updates in <1s.
|
||||
|
||||
## Stack
|
||||
- **Compositor**: `cage -s` (kiosk Wayland, handles DRM, libinput touch via seat0)
|
||||
- **Browser**: `cog --platform=wl` (WPE WebKit, lighter than Chromium 150MB and Electron 265MB). Fallback: `chromium --ozone-platform=wayland` if WPE touch fails.
|
||||
- **Webapp**: React 18 UMD or Vite + React (we use Vite for HMR). No backend, uses `localStorage` for journal/todos. All offline, file:// or http://localhost works.
|
||||
- **Icons**: Reuse PNG 128x128 from v1/v2 `browser/icons/`.
|
||||
|
||||
## Folder v3
|
||||
```
|
||||
KiddOsV3/
|
||||
├── plan.md (this file)
|
||||
├── README.md
|
||||
├── public/ (static icons, will be served by Vite)
|
||||
├── webapp/
|
||||
│ ├── package.json (vite + react)
|
||||
│ ├── vite.config.js (host 0.0.0.0, port 5173, HMR overlay)
|
||||
│ ├── index.html (Vite entry)
|
||||
│ └── src/
|
||||
│ ├── main.jsx (ReactDOM.createRoot)
|
||||
│ ├── App.jsx (OS shell: header, favorites, categories, grid, settings drawer)
|
||||
│ └── apps/
|
||||
│ ├── Journal.jsx (localStorage journal)
|
||||
│ ├── Calculator.jsx
|
||||
│ ├── Drawing.jsx (canvas)
|
||||
│ └── CodeLab.jsx
|
||||
└── scripts/
|
||||
├── dev.sh (run vite dev server)
|
||||
└── run-kiosk.sh (the proven cage command)
|
||||
```
|
||||
|
||||
## How to run (prove without services)
|
||||
|
||||
**On Pi, no services needed — manual, like you asked:**
|
||||
|
||||
```bash
|
||||
# 1. Stop any old kiosks, leave terminal on DSI
|
||||
sudo systemctl stop kiddos.service kiddos-browser.service journal-kiosk.service
|
||||
sudo systemctl start getty@tty1.service
|
||||
|
||||
# 2. Start React dev server in one SSH session:
|
||||
cd ~/KiddOsV3/webapp
|
||||
npm install
|
||||
npm run dev -- --host 0.0.0.0 --port 5173
|
||||
# Vite says: Local: http://localhost:5173/
|
||||
|
||||
# 3. In another SSH session, put it on DSI (exact command you proved):
|
||||
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, and editing src/App.jsx updates instantly.
|
||||
```
|
||||
|
||||
**If touch cursor stuck middle (your last report):**
|
||||
- Cage needs input devices. Check `libinput list-devices` shows `10-0038 generic ft5x06 (79)` at event7.
|
||||
- Try without WLR_NO_HARDWARE_CURSORS, and ensure /run/user/1000/wayland-* cleaned.
|
||||
- Fallback: `cage -s -- chromium --ozone-platform=wayland` instead of cog — you saw webpage with that too.
|
||||
- Last resort heavier: `labwc --startup "cog ..."` or Xorg+openbox, but we avoid until proven.
|
||||
|
||||
## React Hot Refresh Details
|
||||
- Vite HMR uses WebSocket on same host:port. Cog supports WebSocket, so HMR works file://? No, needs http:// — hence dev server at localhost:5173.
|
||||
- In `vite.config.js`:
|
||||
```js
|
||||
export default {
|
||||
server: { host: '0.0.0.0', port: 5173, hmr: { clientPort: 5173 } },
|
||||
clearScreen: false
|
||||
}
|
||||
```
|
||||
- Edit `src/App.jsx`, save, DSI refreshes.
|
||||
|
||||
## Next Steps After Prove
|
||||
Once hello world React works reliably on DSI with touch:
|
||||
1. Add more React apps (Scratch via iframe?).
|
||||
2. Optionally re-add local server later for central sync (v2's server.py) — but keep v3 frontend-only for fast iteration.
|
||||
3. Only then create systemd service using same working command (openvt -f -c 1 -s ...).
|
||||
|
||||
## Commands Reference (the one you asked to keep)
|
||||
|
||||
Base proven command (no backend, just file:// hello world):
|
||||
```bash
|
||||
cage -s -- \
|
||||
cog --platform=wl file:///home/elias/KiddOsV2/browser/hello.html --bg-color=#2E3440
|
||||
```
|
||||
|
||||
For v3 React with HMR:
|
||||
```bash
|
||||
cage -s -- \
|
||||
cog --platform=wl http://localhost:5173 --bg-color=#2E3440
|
||||
```
|
||||
|
||||
If Cog touch fails, try Chromium:
|
||||
```bash
|
||||
cage -s -- \
|
||||
chromium --kiosk --no-sandbox --ozone-platform=wayland --disable-gpu \
|
||||
http://localhost:5173
|
||||
```
|
||||
|
||||
Electron alternative (heavier, same as Chromium + Node, you asked about):
|
||||
```bash
|
||||
cage -s -- \
|
||||
./node_modules/.bin/electron --no-sandbox --ozone-platform=wayland --disable-gpu .
|
||||
```
|
||||
|
||||
## Why not LVGL anymore?
|
||||
- v1 LVGL had to fork/exec + DRM master handover for each app → “any app I try to open freeze and restarts the OS” (your report). Non-DRM apps (gnome-calculator) crashed.
|
||||
- Browser OS: one process owns DRM forever, apps are just React components / pages, no fork, no black screen.
|
||||
|
||||
Reference in New Issue
Block a user