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.
├── 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:
./live_talk.db) when running locally (using sql.js)valtown environment 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:
.dev-server.logIf you prefer to start manually:
deno run --allow-net --allow-read --allow-write --allow-import --allow-env --watch server.ts
http://localhost:8000 in your browserlive_talk.db) will be created automaticallyNote: 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:
Example: http://localhost:8000/present/1
Participants navigate to /join/:presentationId:
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 presentationGET /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 stepPOST /api/sessions - Create or get existing sessionGET /api/sessions/:id - Get session detailsPOST /api/responses - Submit a responseGET /api/responses/step/:id - Get all responses for a stepThe system is designed to be extensible. Currently supports:
Future widgets can be added by:
frontend/components/widgets/frontend/components/widgets/ParticipantMode.tsx and PresenterMode.tsxSee backend/database/migrations.ts for full schema details.
app.http.ts - this is the main entry point for Val Townapp.http.ts as an HTTP trigger (because it has http in the filename)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