From 6d4d39c2d8abe63a3a8e7e0852caba58ddd260af Mon Sep 17 00:00:00 2001 From: ScreenTinker Date: Sat, 11 Apr 2026 22:04:26 -0500 Subject: [PATCH] Phase 2: buildPlaylistPayload reads from playlist_items via device.playlist_id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the assignments-table query with a playlist_items query keyed on device.playlist_id. Also eliminates the duplicate payload builder in scheduler.js — it now calls the shared buildPlaylistPayload. Co-Authored-By: Claude Opus 4.6 --- server/services/scheduler.js | 22 ++++------------------ server/ws/deviceSocket.js | 26 +++++++++++++++++--------- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/server/services/scheduler.js b/server/services/scheduler.js index 29ad8d9..a0472ed 100644 --- a/server/services/scheduler.js +++ b/server/services/scheduler.js @@ -81,24 +81,10 @@ function parseSimpleRRule(rrule) { } function pushPlaylistToDevice(deviceId, deviceNs) { - const assignments = db.prepare(` - SELECT a.*, COALESCE(c.filename, w.name) as filename, c.mime_type, c.filepath, c.file_size, c.duration_sec as content_duration, c.remote_url, - w.name as widget_name, w.widget_type, w.config as widget_config - FROM assignments a LEFT JOIN content c ON a.content_id = c.id LEFT JOIN widgets w ON a.widget_id = w.id - WHERE a.device_id = ? AND a.enabled = 1 - ORDER BY a.sort_order ASC - `).all(deviceId); - - const device = db.prepare('SELECT * FROM devices WHERE id = ?').get(deviceId); - let layout = null; - if (device.layout_id) { - layout = db.prepare('SELECT * FROM layouts WHERE id = ?').get(device.layout_id); - if (layout) { - layout.zones = db.prepare('SELECT * FROM layout_zones WHERE layout_id = ? ORDER BY sort_order').all(layout.id); - } - } - - deviceNs.to(deviceId).emit('device:playlist-update', { assignments, layout, orientation: device?.orientation || 'landscape' }); + // Use the single-source buildPlaylistPayload from deviceSocket + const { buildPlaylistPayload } = require('../ws/deviceSocket'); + const payload = buildPlaylistPayload(deviceId); + deviceNs.to(deviceId).emit('device:playlist-update', payload); } module.exports = { startScheduler, pushPlaylistToDevice }; diff --git a/server/ws/deviceSocket.js b/server/ws/deviceSocket.js index 47e55f1..905a0c0 100644 --- a/server/ws/deviceSocket.js +++ b/server/ws/deviceSocket.js @@ -25,17 +25,25 @@ function logDeviceStatus(deviceId, status) { // Build playlist payload with layout and zones +// Reads from the device's assigned playlist (Phase 2) instead of assignments table function buildPlaylistPayload(deviceId) { - const assignments = db.prepare(` - SELECT a.*, COALESCE(c.filename, w.name) as filename, c.mime_type, c.filepath, c.file_size, c.duration_sec as content_duration, c.remote_url, - w.name as widget_name, w.widget_type, w.config as widget_config - FROM assignments a LEFT JOIN content c ON a.content_id = c.id LEFT JOIN widgets w ON a.widget_id = w.id - WHERE a.device_id = ? AND a.enabled = 1 - ORDER BY a.sort_order ASC - `).all(deviceId); + const device = db.prepare('SELECT playlist_id, layout_id, orientation FROM devices WHERE id = ?').get(deviceId); + + let assignments = []; + if (device?.playlist_id) { + assignments = db.prepare(` + SELECT pi.id, pi.content_id, pi.widget_id, pi.sort_order, pi.duration_sec, + COALESCE(c.filename, w.name) as filename, c.mime_type, c.filepath, c.file_size, + c.duration_sec as content_duration, c.remote_url, + w.name as widget_name, w.widget_type, w.config as widget_config + FROM playlist_items pi + LEFT JOIN content c ON pi.content_id = c.id + LEFT JOIN widgets w ON pi.widget_id = w.id + WHERE pi.playlist_id = ? + ORDER BY pi.sort_order ASC + `).all(device.playlist_id); + } - // Get device's layout with zones - const device = db.prepare('SELECT layout_id, orientation FROM devices WHERE id = ?').get(deviceId); let layout = null; if (device?.layout_id) { layout = db.prepare('SELECT * FROM layouts WHERE id = ?').get(device.layout_id);