# TFI Live G2 Even Realities G2 app for live Transport for Ireland departures. ## Features - Favourite stops - Nearby stops using phone geolocation - Typed stop/route search - G2 microphone voice search through a configured STT endpoint - Stop departure board for bus, Luas/tram, rail, DART, and other GTFS modes - G2 touch controls with a mirrored phone UI - Even SDK local storage with browser storage fallback ## Configuration Create `.env.local` when using live data: ```bash NTA_API_KEY=your_nta_key NTA_TRIP_UPDATES_TARGET=https://api.nationaltransport.ie/gtfsr/v2/TripUpdates?format=json VITE_TFI_API_BASE=https://your-worker.example VITE_TFI_STOPS_URL=https://your-host.example/stops.json VITE_STT_API_BASE=https://your-stt.example VITE_STT_API_KEY=optional_stt_key ``` For real sideloaded/packed use, deploy a small proxy for NTA requests and set `VITE_TFI_API_BASE` to it. The included Cloudflare Worker at `worker/nta-proxy.js` keeps the NTA key server-side, caches the GTFS-R feed briefly, and returns per-stop departures from `/departures?stopId=...&stopCode=...`. Configure Worker secrets/vars: ```bash NTA_API_KEY=your_nta_key NTA_TRIP_UPDATES_TARGET=https://api.nationaltransport.ie/gtfsr/v2/TripUpdates?format=json STOPS_URL=https://your-host.example/stops.json ``` `VITE_TFI_STOPS_URL` or `${VITE_TFI_API_BASE}/stops` should return either an array of stops or `{ "stops": [...] }`. Each stop can use camelCase or GTFS-style fields: ```json { "stop_id": "822GA00345", "stop_code": "345", "stop_name": "OConnell Street", "stop_lat": 53.3498, "stop_lon": -6.2603, "modes": ["bus"], "routes": ["1", "11", "13"] } ``` The NTA key is intentionally not prefixed with `VITE_`; Vite keeps it server-side and proxies `/api/nta/trip-updates` with the required subscription headers during local/tunnel development. The Vite proxy is dev-only, so production builds should use `VITE_TFI_API_BASE`. If live env vars are missing or calls fail, the app falls back to demo stops/departures so the G2 flow remains testable. ## Build a stop index If you have an extracted static GTFS folder containing `stops.txt`, `routes.txt`, `trips.txt`, and `stop_times.txt`, build the compact stop index: ```bash npm run build:stops -- /path/to/extracted-gtfs public/stops.json ``` Then serve `public/stops.json` or upload it and point `VITE_TFI_STOPS_URL` / Worker `STOPS_URL` at that JSON file. If you deploy the Worker on a custom domain instead of `*.workers.dev`, add that domain to `app.json` under `permissions[0].whitelist` before packing. ## Run ```bash npm install npm run dev ``` Generate a sideload QR: ```bash XDG_CONFIG_HOME=.evenhub-config npx evenhub qr --url "https://YOUR_TUNNEL_OR_HOST" ``` ## Glasses controls - Single press: select stop or refresh departures - Swipe up/down: move selection - Double press: back; from the main menu it opens the system exit dialog ## Package ```bash npm run build npm run pack ``` This creates `tfi-live-g2.ehpk`.