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
Note: The SQLite database requires Val Town environment variables to work. For full local testing, you'll need Val Town credentials. The app is designed to work seamlessly when deployed to Val Town.
-
Start the server (with required permissions):
deno run --allow-net --allow-import --allow-env --watch server.ts -
Access the app:
- Open
http://localhost:8000in your browser - The server will automatically reload on file changes
- Database operations will work when deployed to Val Town
- Open
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