Commit graph

166 commits

Author SHA1 Message Date
ScreenTinker 31e5a5a8f3 Add playlists route to frontend app.js router
Import, nav highlight for #/playlists and #/playlists/:id, route
handler delegating to playlists view module.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 21:16:08 -05:00
ScreenTinker 865a89836b Add Playlists nav entry to sidebar between Content and Layouts
Uses list icon (lines with dots). Positioned content-adjacent since
playlists are collections of content items.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 21:15:25 -05:00
ScreenTinker 94f48e76b0 Register playlist routes in server.js
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 21:10:24 -05:00
ScreenTinker e262216c58 Add playlist API routes with full CRUD and item management
Routes: GET/POST /playlists, GET/PUT/DELETE /playlists/:id,
GET/POST /playlists/:id/items, PUT/DELETE /playlists/:id/items/:itemId,
POST /playlists/:id/items/reorder.

Follows device-groups.js patterns: ownership middleware, parameterized
queries, content/widget ownership validation, input validation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 21:09:58 -05:00
ScreenTinker 1fbeccff7c Add playlists and playlist_items tables to schema
Phase 1 of playlist refactor: standalone playlist entities with ordered
items. No changes to existing tables or display behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 21:09:12 -05:00
ScreenTinker f57fc5ad81 Security hardening: auth checks, XSS escaping, input validation
- Add requireGroupOwnership middleware to all group endpoints
- Whitelist allowed command types (screen_on/off, launch, update, reboot, shutdown)
- Validate color format as #RRGGBB
- Escape all user-controlled strings (device/group names, emails) in dashboard HTML
- Restrict trust proxy to first hop only (prevents IP spoofing + rate limit bypass)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 22:09:40 -05:00
ScreenTinker faa437881f Add device groups UI, group commands, proxy IP fix, and web player detection
- Dashboard now organizes devices by group with colored section headers
- Group command endpoint (POST /groups/:id/command) sends to all members
- Manage modal with multi-group confirmation prompt
- Destructive commands (reboot/shutdown) require confirmation
- Ungrouped devices shown separately at bottom
- trust proxy + X-Forwarded-For for real client IPs behind Nginx
- Hide Android-only telemetry (battery/storage/RAM/CPU/WiFi) for web players

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 22:03:44 -05:00
ScreenTinker e7081a579c Fix widget assignments, designer scaling, and cache strategy
- Make assignments.content_id nullable so widgets can be assigned to playlists
- Fix designer publish to use vw units matching preview (was hardcoded px)
- Add px-to-vw conversion in text widget renderer for backward compat
- Fix webpage widget zoom scaling
- Add widget rendering support in fullscreen player mode
- Set no-cache headers on JS/CSS/HTML for instant updates (ETag/304)
- Set 30-day cache on media files and uploaded content for Cloudflare

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 16:25:05 -05:00
ScreenTinker e2879fff58 Instant playlist push, fix YouTube looping, auto-fetch video titles
- Push playlist updates to devices instantly via WebSocket on all
  assignment mutations (add, update, delete, reorder, copy)
- Fix YouTube videos skipping early: remove duration_sec timeout (was
  defaulting to 10s), use generation counter to ignore stale player
  callbacks, disable YouTube loop param for multi-item playlists
- Auto-fetch YouTube video title via oEmbed API when no name provided
- Show actual video duration in M:SS format in playlist instead of
  misleading assignment duration_sec
- Pre-fill server URL from origin on web player setup
- Bump playlist poll interval to 5min (fallback only, push is primary)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 15:42:41 -05:00
ScreenTinker b7d0c94313 Move player downloads into Add Display modal for discoverability
Player download links now appear directly in the Add Display modal below
the pairing form, so new users can find and install a player app without
hunting through Settings. Removed the duplicate downloads section from
the Settings page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 15:04:33 -05:00
ScreenTinker 8a84923d72 Fix YouTube playback: use IFrame API, fix playlist change detection, network-first caching
- Replace raw iframe YouTube embeds with official YT IFrame Player API for proper
  error handling (150/153/100/101) and unmute support
- Fix playlist not updating when single item changes by comparing full content
  fingerprint (id + url + filepath + filename) instead of just content_id
- Add click-to-unmute overlay for YouTube since iframe swallows click events
- Remove hardcoded origin param from server-side YouTube URLs (caused Error 153
  when player domain differs from server)
- Switch service worker to network-first for player assets so deploys take effect
  without hard refresh; keep cache-first for uploaded content

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 14:56:49 -05:00
ScreenTinker af371b9d89 Fix YouTube embed error 153 - add mute, origin, and enablejsapi params
- Add mute=1, enablejsapi=1, and origin params to YouTube embed URLs
- Fix applies at creation time (content route) and playback time (player)
- Existing YouTube content gets fixed params via fixYoutubeUrl() helper
- Also fixes content library preview iframe

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 14:25:44 -05:00
ScreenTinker 4ae7533b85 Hide unclaimed devices from dashboard, add unassigned API, add upgrade docs
- Filter out devices with no user_id from the main device listing
- Add GET /api/devices/unassigned endpoint (admin only) for unclaimed devices
- Add "Updating" section to README with upgrade instructions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 13:13:46 -05:00
ScreenTinker d18045a386 Fix web player single-video loop and service worker cache errors
- Loop single-video playlists natively instead of destroying/recreating the element
- Skip caching HTTP 206 partial responses in service worker (video range requests)
- Bump service worker cache version to invalidate old cache

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 12:58:43 -05:00
ScreenTinker d67dd41056 Add YouTube and Export/Import to README features list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 12:21:05 -05:00
ScreenTinker 1594a9d4a4 Initial open source release
ScreenTinker - open source digital signage management software.
MIT License, all features included, no license gates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 12:14:53 -05:00