From e4675f2498626fae07cf8d2ac019e8e03aba5fc6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Nov 2026 10:37:18 +0000 Subject: [PATCH] Playlist generator: remove the Inserts step Generator inserts (jingles, adverts, talk and time announcements on their own schedule) doubled up with the advertisement scheduler's rules, which already fire while a generated playlist plays. The Inserts section is gone from the generator window and the web portal, generate() returns plain tracks, and "Preview and generate" is now step 4. Templates saved with inserts still load: the old "markers" field is ignored (new test), and is dropped the next time settings are saved. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016m2QHVXdQJrUq7pCLfKSXk --- README.md | 2 +- assets/portal/portal.js | 8 +- lang/template.json | 14 +- site/guides/playlist-generator/index.html | 16 +- src/app.rs | 10 +- src/config.rs | 49 ++--- src/generator.rs | 209 +++------------------- src/genui.rs | 102 +---------- src/playout.rs | 27 ++- 9 files changed, 59 insertions(+), 378 deletions(-) diff --git a/README.md b/README.md index ab3155b..aa23949 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ remote control HTTP API, station profiles, local operator accounts. **Rules** say what plays (an advert / jingle folder, chosen files, or the Adverts list), how often (after every N songs, every N minutes or hours, or at set times) and when the rule is in force (dates, days, hours). The **Adverts list** holds your adverts with the dates and days each may run. Rules can also be used in the playlist generator -(as a pattern step or inserted every N minutes) and run by the Event scheduler or the `RULE ` command. +(as a pattern step) and run by the Event scheduler or the `RULE ` command. ## Event scheduler (Tools → Event scheduler, F3) At a set time (on chosen days and dates): generate a new playlist from a template, append one, play a rule's diff --git a/assets/portal/portal.js b/assets/portal/portal.js index e06bf9d..217faa9 100644 --- a/assets/portal/portal.js +++ b/assets/portal/portal.js @@ -595,9 +595,9 @@ function stepRows(items, make, fields, addText) { function editTemplate(i) { const t = i >= 0 ? JSON.parse(JSON.stringify(cfg.templates[i])) - : { name: "New template", minutes: 120, pattern: [{ category: (cfg.categories[0] || {}).name || "Music", count: 1 }], markers: [], artist_gap: 5, hour_markers: false }; + : { name: "New template", minutes: 120, pattern: [{ category: (cfg.categories[0] || {}).name || "Music", count: 1 }], artist_gap: 5, hour_markers: false }; t.pattern = t.pattern || []; - t.markers = t.markers || []; + delete t.markers; // generator inserts were removed; the station's ad rules play jingles and adverts const first = (sources()[0] || ["Music"])[0]; const name = el("input", { value: t.name, required: true }); const minutes = num(t.minutes, 1, 1440 * 7); @@ -608,8 +608,6 @@ function editTemplate(i) { el("div", { class: "pair" }, field("Length (minutes)", minutes), field("Songs before an artist repeats", gap)), el("div", { class: "sub" }, el("strong", {}, "Steps"), el("p", { class: "muted small" }, "Played in order, then again from the top, until the length is reached."), stepRows(t.pattern, () => ({ category: first, count: 1 }), [["count", "×", 1, 50]], "+ Step")), - el("div", { class: "sub" }, el("strong", {}, "Markers"), el("p", { class: "muted small" }, "Put in every so many minutes, e.g. a station ID every 30 minutes."), - stepRows(t.markers, () => ({ category: first, every_mins: 30, count: 1 }), [["every_mins", "every (min)", 1, 1440], ["count", "×", 1, 20]], "+ Marker")), hourRow, ], () => { const n = name.value.trim(); @@ -653,7 +651,7 @@ function editCategory(i) { if (k >= 0) x.categories[k] = c; else x.categories.push(c); // the templates follow a renamed category if (old !== null && old !== n) { - (x.templates || []).forEach((t) => [...(t.pattern || []), ...(t.markers || [])].forEach((p) => { if (p.category === old) p.category = n; })); + (x.templates || []).forEach((t) => (t.pattern || []).forEach((p) => { if (p.category === old) p.category = n; })); } }); }); diff --git a/lang/template.json b/lang/template.json index de9d2ce..04a3c8a 100644 --- a/lang/template.json +++ b/lang/template.json @@ -94,7 +94,6 @@ "Assign audio file": "", "Assign audio file…": "", "At": "", - "At the top of every hour": "", "Attack": "", "Audio FX": "", "Audio devices": "", @@ -236,7 +235,6 @@ "Events": "", "Every": "", "Every 30 minutes on the clock = at :00 and :30. Off = 30 minutes after the last time.": "", - "Every 60 minutes on the clock = at the top of each hour. Off = counted from the start of the playlist.": "", "Every change is listed in cleanup-log.csv in the data folder.": "", "Every day": "", "Every file is there and can be read.": "", @@ -331,7 +329,6 @@ "Insert tracks from playlist…": "", "Insert voice track": "", "Insert voice track…": "", - "Inserts": "", "Install now": "", "Interface size": "", "Intro sound": "", @@ -341,7 +338,6 @@ "JINGLE": "", "Jingles": "", "Jingles & adverts (their rule's files)": "", - "Jingles, adverts, talk or a time announcement, like the advert / jingle rules: after a number of songs, every so often, or at set times. Timed ones go in after the song that's playing when the time comes.": "", "Keep": "", "Keep the music at full level": "", "Keep the playing track near the top as songs finish (the last one played stays in view)": "", @@ -395,7 +391,6 @@ "MIDI isn't available:": "", "MIDI only": "", "MP3 (built in)": "", - "Make a jingle rule in the Advertisement scheduler first, or add a Jingles category": "", "Make a tunnel in the Cloudflare dashboard (Zero Trust → Networks → Tunnels) for your own domain, and point it at http://localhost and the portal port. Without a token you get a random trycloudflare.com address.": "", "Make everything larger or smaller if the text is hard to read.": "", "Make this the primary output": "", @@ -747,7 +742,7 @@ "The song on air fades out and the break starts on time. A countdown lets the presenter play it now, snooze it or skip it.": "", "The song on air will fade out.": "", "The station goes quiet while the server restarts (a few seconds) — best done between shows. This app reconnects by itself.": "", - "The template's times of day and timed inserts follow the clock from where the new tracks start.": "", + "The template's times of day follow the clock from where the new tracks start.": "", "The track is only": "", "There's no RadioMaster Server download for the server's system: update it by hand": "", "These accounts sign in to the server (from the app and the web portal). The server checks every action against them.": "", @@ -807,7 +802,6 @@ "Username": "", "Users & access control": "", "Users…": "", - "Uses the files of a jingle rule (Advertisement scheduler) every 15 minutes": "", "Version": "", "Very slow computer": "", "View": "", @@ -865,7 +859,6 @@ "administrator": "", "advert": "", "adverts": "", - "after every": "", "after the playlist (instead of replacing it)": "", "after the track on air": "", "all day": "", @@ -885,7 +878,6 @@ "e.g. station id, news": "", "egui · rodio · symphonia · LAME": "", "encoder": "", - "every": "", "failed": "", "files": "", "files checked": "", @@ -979,7 +971,6 @@ "this band": "", "this category": "", "this event": "", - "this insert": "", "this rule": "", "this shortcut": "", "this template": "", @@ -1066,12 +1057,9 @@ "➕ Add encoder": "", "➕ Add event": "", "➕ Add files": "", - "➕ Add insert": "", - "➕ Add jingles": "", "➕ Add pattern step": "", "➕ Add streamer": "", "➕ Add time": "", - "➕ Add time announcement": "", "➕ Add time of day": "", "➕ Advert rule": "", "➕ Folder…": "", diff --git a/site/guides/playlist-generator/index.html b/site/guides/playlist-generator/index.html index d0d6a2a..84b1dde 100644 --- a/site/guides/playlist-generator/index.html +++ b/site/guides/playlist-generator/index.html @@ -14,7 +14,7 @@ - + @@ -23,7 +23,7 @@ - +