An interactive presentation tool for Last Conference that allows presenters to embed real-time activities (polls, questions, etc.) throughout their talks. Audience members scan a QR code to participate, and responses are displayed in real-time to the presenter.
- Real-time Interaction: Participants join via QR code and respond to activities
- Session Persistence: Participant sessions are stored in localStorage for consistent experience
- Multiple Steps: Presentations can have multiple steps/activities
- Poll Widget: Built-in poll widget with real-time results visualization
- Presenter & Participant Modes: Separate views for presenter and audience
- Modern UI: Clean, responsive design with TailwindCSS
- Backend: Hono (Deno-compatible web framework)
- Database: SQLite (Val Town standard library)
- Frontend: React 18.2.0 with TypeScript
- Styling: TailwindCSS
- Platform: Val Town / Deno
βββ backend/
β βββ index.ts # Main Hono app entry point
β βββ database/
β β βββ migrations.ts # Database schema setup
β β βββ queries.ts # Database query functions
β βββ routes/
β βββ presentations.ts # Presentation CRUD
β βββ steps.ts # Step management
β βββ sessions.ts # Session handling
β βββ responses.ts # Response handling
β βββ admin.ts # Admin/presenter endpoints
βββ frontend/
β βββ index.html # Main HTML template
β βββ index.tsx # Frontend entry point
β βββ components/
β β βββ App.tsx # Main app component
β β βββ PresenterMode.tsx # Presenter view
β β βββ ParticipantMode.tsx # Participant view
β β βββ QRCode.tsx # QR code display
β β βββ widgets/
β β βββ PollWidget.tsx # Poll participant view
β β βββ PollPresenter.tsx # Poll presenter view
β βββ utils/
β βββ session.ts # Session management (localStorage)
β βββ api.ts # API client functions
βββ shared/
β βββ types.ts # TypeScript types/interfaces
βββ server.ts # Local development server
The app automatically detects the environment and uses:
- Local SQLite (
./live_talk.db) when running locally (using sql.js) - Val Town SQLite when deployed to Val Town (detected via
valtownenvironment variable)
Use the development script to manage the server:
# Start the server ./scripts/dev.sh start # or make dev # or npm run dev # Check server status ./scripts/dev.sh status # or make dev-status # or npm run dev:status # Stop the server ./scripts/dev.sh stop # or make dev-stop # or npm run dev:stop # Restart the server ./scripts/dev.sh restart # or make dev-restart # or npm run dev:restart
The script handles:
- Starting the server with all required Deno permissions
- Process management (PID tracking)
- Proper cleanup of all child processes when stopping
- Logging to
.dev-server.log
If you prefer to start manually:
deno run --allow-net --allow-read --allow-write --allow-import --allow-env --watch server.ts
- Open
http://localhost:8000in your browser - The server will automatically reload on file changes
- A local SQLite database file (
live_talk.db) will be created automatically - Database operations work fully locally without Val Town credentials
Note: The local SQLite uses sql.js (pure JavaScript SQLite) which loads WASM files. The first request might take a moment to initialize.
Use the API to create a presentation:
curl -X POST http://localhost:8000/api/presentations \ -H "Content-Type: application/json" \ -d '{ "name": "My Awesome Talk", "presenter": "John Doe", "talk_deck_link": "https://example.com/slides" }'
Create steps (activities) for your presentation:
curl -X POST http://localhost:8000/api/steps/presentation/1 \ -H "Content-Type: application/json" \ -d '{ "widget_type": "poll", "widget_config": { "question": "What is your favourite programming language?", "options": ["JavaScript", "Python", "Rust", "Go"] } }'
Navigate to /present/:presentationId to access the presenter view:
- See QR code for participants to join
- View real-time responses
- Activate/deactivate steps
- Navigate between steps
Example: http://localhost:8000/present/1
Participants navigate to /join/:presentationId:
- Automatically assigned a session ID (stored in localStorage)
- See the currently active step
- Submit responses
- Page auto-updates when presenter changes steps
Example: http://localhost:8000/join/1
GET /api/presentations- List all presentationsPOST /api/presentations- Create new presentationGET /api/presentations/:id- Get presentation detailsPUT /api/presentations/:id- Update presentation
GET /api/steps/presentation/:id- Get all steps for a presentationPOST /api/steps/presentation/:id- Create new stepGET /api/steps/:id- Get step detailsPUT /api/steps/:id- Update stepPUT /api/steps/:id/activate- Activate a stepGET /api/steps/presentation/:id/active- Get active step
POST /api/sessions- Create or get existing sessionGET /api/sessions/:id- Get session details
POST /api/responses- Submit a responseGET /api/responses/step/:id- Get all responses for a step
The system is designed to be extensible. Currently supports:
- Poll Widget: Multiple choice questions with real-time results
Future widgets can be added by:
- Creating participant component in
frontend/components/widgets/ - Creating presenter component in
frontend/components/widgets/ - Adding widget type handling in
ParticipantMode.tsxandPresenterMode.tsx
- presentations: Presentation metadata
- steps: Steps/activities within presentations
- sessions: Participant sessions
- responses: Participant responses to steps
See backend/database/migrations.ts for full schema details.
- Upload all files to a Val Town project
- The HTTP trigger file is
app.http.ts- this is the main entry point for Val Town - Val Town will automatically detect
app.http.tsas an HTTP trigger (because it hashttpin the filename) - Ensure all dependencies are available via esm.sh or Val Town standard libraries
- The app will automatically run migrations on startup
- Your app will be accessible at the URL provided by Val Town
Note: For local development, use server.ts which imports from backend/index.ts. For Val Town deployment, use app.http.ts directly.
Built for Last Conference