Files
Presentation-system/README.md
T
2026-09-13 20:23:05 +01:00

207 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MPS — Martinhal Presentation System
A self-hosted app that turns any presentation into a link and a QR code. Upload a
**video, PowerPoint, Word doc, Excel sheet, PDF, or image**; the app converts it to a
browser-friendly format and generates a QR code. Anyone who scans it watches along on
their own phone — **live and in sync with the presenter**, or browsing at their own pace.
Everything runs in a single Docker container. No cloud, no third-party services except
the mail account you choose to connect for email sharing.
**Version 1.7** · © 2026 Martinhal IT — Joao Vaz
---
## What's new in 1.7
- **Present Local Only** opens **two browser tabs**: the presenter console (to drive the
talk, exactly like **Present**) and a second, chrome-free tab showing the presentation
only — no header text, no control buttons. The second tab mirrors the console live, so
it's ideal for a projector or second screen. Both open as normal tabs (not pop-up
windows).
#### Since 1.4
- **Simpler login screen** — just the credentials, nothing else.
- **End session** button in the presenter bar (left of Exit): it **invalidates the QR
code** and disconnects everyone watching, so the link can't be reused afterwards.
- **Refresh regenerates codes** — pressing **Refresh** on the dashboard issues a fresh QR
code for every presentation, so links from a finished talk stop working.
- The presenter bar now shows a single **QR Code** button (opens the large, scannable
page); the old "Share / QR" pop-over was removed.
#### Since 1.3
- **First-run setup.** The very first time you open the app it asks you to **create the
administrator account** — no default password to remember or change.
- **Rebranded** as MPS — Martinhal Presentation System, with the MPS logo across the app.
- **QR Code button** on every ready presentation opens the code on its own page in
**large format** — ideal for putting on a projector. It has copy-link, fullscreen and
print actions.
- **Bigger presentation cards** on the host dashboard (twice as wide, 50% taller) so the
QR preview and controls are easier to use.
### From 1.2
Login page and user accounts, admin-only user management, mail settings and activity logs,
email sharing, PurelyMail SMTP+IMAP with a copy saved to **Sent**, and First/Last slide
controls.
---
## Quick start (Docker Compose)
```bash
# Point QR codes at an address phones can actually reach (LAN IP or public URL).
export PUBLIC_BASE_URL=http://192.168.1.50:3000
docker compose up --build -d
```
Open `http://<host>:3000`. On first launch you'll be asked to **create the admin
account**. After that, sign in, upload a file, and hit **Present**. Show the QR code
(**Share / QR**, or the **QR Code** button for a full-screen page) and the room scans to
join.
> **Unattended installs:** if you'd rather not use the setup screen, set `ADMIN_USERNAME`
> and `ADMIN_PASSWORD` before the first start and an admin will be pre-created from those
> values instead. They're ignored once an account exists.
### Plain Docker
```bash
docker build -t mps .
docker run -d --name mps \
-p 3000:3000 \
-e PUBLIC_BASE_URL=http://192.168.1.50:3000 \
-v qr_data:/data \
mps
```
### Without Docker (Node 18+)
Requires `libreoffice`, `ffmpeg`, and fonts on the host.
```bash
npm install
npm run fetch-vendor # vendors PDF.js for offline use
npm start
```
---
## Updating (no data loss)
All state — user accounts, mail settings, logs, uploaded decks — lives under the `/data`
volume, never inside the app code. To update:
1. Unzip the new version over your existing project folder (code files are replaced;
your `data/` and the Docker `qr_data` volume are left untouched).
2. Rebuild and restart:
```bash
docker compose up --build -d
```
Your admin account, users, presentations, and mail configuration carry straight over, and
the first-run setup screen does **not** reappear.
---
## Users & roles
| Role | Can do |
|---|---|
| **admin** | Everything: manage users, configure mail, view logs, see and manage **all** presentations. |
| **user** | Sign in, upload and present **their own** decks, share them (link, QR, email). |
The first admin is created during setup. Manage further accounts at **/users** (admins
only). The app prevents removing or demoting the last remaining admin, and you can't
delete your own account.
---
## Sharing a presentation
Each ready presentation offers several ways to get people in:
- **QR Code** — the presenter bar opens a dedicated full-screen page with a large,
scannable code (plus copy-link, fullscreen, and print). Great for a projector.
- **End session** — invalidates the QR code and disconnects viewers when you're done.
- **Copy link** — the plain audience URL.
- **Email** — sends the link and QR straight to recipients (requires mail set up).
---
## Email sharing (PurelyMail)
1. Sign in as an admin → **Manage users → Mail**.
2. Tick **Enable email sending**, enter the PurelyMail **account email** and **password**.
Servers are prefilled and match PurelyMail's settings:
| | Host | Port | Security |
|---|---|---|---|
| SMTP (send) | `smtp.purelymail.com` | `465` | SSL/TLS |
| IMAP (Sent copy) | `imap.purelymail.com` | `993` | SSL/TLS |
3. Save, then **Send test** to confirm it works.
Every message is delivered over SMTP and a copy is appended to the **Sent** folder over
IMAP, so it appears in your normal mail client. The stored mail password lives only in
`/data/config.json` on your server and is never sent back to the browser.
---
## Presenting
- **Slides:** `« First` · ` Prev` · `Next ` · `Last »`, or the keys `` `` `Home` `End`.
- **Present Local Only:** opens the presenter console plus a separate controls-free tab
that mirrors it for a projector/second screen. If the second tab doesn't open, allow
pop-ups for the site.
- **Synced ↔ Free browse:** in Synced mode the audience follows you; in Free browse they
move on their own. Audience members who wander off get a one-tap "Rejoin presenter".
- **Video:** play / pause / seek are broadcast to everyone. Viewers tap once to allow
sound (browsers block autoplay audio until then).
---
## Supported formats
| Input | Handled as | Tool |
|---|---|---|
| `.pdf` | paged deck | served directly |
| `.pptx .ppt .odp .pps .ppsx` | paged deck | LibreOffice → PDF |
| `.docx .doc .odt .rtf .txt .md` | paged deck | LibreOffice → PDF |
| `.xlsx .xls .ods .csv .tsv` | paged deck | LibreOffice → PDF |
| `.mp4 .webm .ogg` | synced video | served directly |
| `.mov .avi .mkv .wmv .flv .3gp .mpeg .ts` | synced video | ffmpeg → MP4 |
| `.png .jpg .jpeg .gif .webp .svg .bmp .avif` | image | served directly |
---
## Configuration
| Variable | Default | Purpose |
|---|---|---|
| `PUBLIC_BASE_URL` | derived from request | Absolute URL encoded in QR codes / links. **Set this.** |
| `ADMIN_USERNAME` | `admin` | Only for unattended pre-seed (see Quick start). |
| `ADMIN_PASSWORD` | *(unset)* | If set on first run, pre-creates an admin instead of showing setup. |
| `ADMIN_EMAIL` | *(empty)* | Email for a pre-seeded admin. |
| `MAX_UPLOAD_MB` | `500` | Maximum upload size. |
| `PORT` | `3000` | Listen port. |
| `DATA_DIR` | `/data` (Docker) | Where all state is stored. Mount as a volume. |
| `CONVERT_TIMEOUT_MS` | `240000` | Per-file conversion timeout. |
---
## Security notes
- Put a reverse proxy with **HTTPS** in front for anything beyond a trusted LAN, and set
`PUBLIC_BASE_URL` to the https address.
- Passwords are stored as salted scrypt hashes. Login sessions are HttpOnly cookies.
- The container runs as a non-root user; all state stays on the mounted volume.
## License
MIT.