diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html
index d7a1adc..b1f84e4 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html
+++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html
@@ -724,7 +724,7 @@
- | Start | End | Bookmark | Label | |
+ | Start | End | Bookmark | Label | Interleave (min) | |
@@ -741,6 +741,9 @@
+
diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/scheduler.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/scheduler.js
index bea4949..cebe798 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/scheduler.js
+++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/scheduler.js
@@ -277,11 +277,13 @@
: [];
entries.forEach(function (entry, idx) {
const tr = document.createElement("tr");
+ const il = entry.interleave_min ? String(entry.interleave_min) + " min" : "—";
tr.innerHTML =
'' + minToHHMM(entry.start_min) + ' | ' +
'' + minToHHMM(entry.end_min) + ' | ' +
'' + bmName(entry.bookmark_id) + ' | ' +
'' + escHtml(entry.label || "") + ' | ' +
+ '' + il + ' | ' +
' | ';
tbody.appendChild(tr);
});
@@ -330,12 +332,15 @@
const endEl = document.getElementById("scheduler-ts-end");
const bmEl = document.getElementById("scheduler-ts-bookmark");
const labelEl = document.getElementById("scheduler-ts-label");
+ const ilEl = document.getElementById("scheduler-ts-entry-interleave");
if (!startEl || !endEl || !bmEl) return;
const startMin = hhmmToMin(startEl.value);
const endMin = hhmmToMin(endEl.value);
const bmId = bmEl.value;
const label = labelEl ? labelEl.value.trim() : "";
+ const ilVal = ilEl ? parseInt(ilEl.value, 10) : NaN;
+ const entryInterleave = !isNaN(ilVal) && ilVal > 0 ? ilVal : null;
if (!bmId) {
alert("Please select a bookmark.");
@@ -354,12 +359,14 @@
end_min: endMin,
bookmark_id: bmId,
label: label || null,
+ interleave_min: entryInterleave,
});
startEl.value = "";
endEl.value = "";
- bmEl.value = ""; // reset select to first option
+ bmEl.value = "";
if (labelEl) labelEl.value = "";
+ if (ilEl) ilEl.value = "";
renderTimespanEntries();
}
diff --git a/src/trx-client/trx-frontend/trx-frontend-http/src/scheduler.rs b/src/trx-client/trx-frontend/trx-frontend-http/src/scheduler.rs
index a64f6b9..d89790c 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/src/scheduler.rs
+++ b/src/trx-client/trx-frontend/trx-frontend-http/src/scheduler.rs
@@ -68,6 +68,11 @@ pub struct ScheduleEntry {
pub bookmark_id: String,
#[serde(default)]
pub label: Option,
+ /// Per-entry interleave duration in minutes. Overrides the config-level
+ /// `interleave_min` when set. Allows each entry to occupy a differently
+ /// sized slice of the interleave cycle.
+ #[serde(default)]
+ pub interleave_min: Option,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
@@ -284,7 +289,7 @@ fn entry_is_active(entry: &ScheduleEntry, now_min: f64) -> bool {
fn timespan_bookmark_id(
entries: &[ScheduleEntry],
now_min: f64,
- interleave_min: Option,
+ default_interleave: Option,
) -> Option {
let active: Vec<&ScheduleEntry> = entries
.iter()
@@ -295,11 +300,24 @@ fn timespan_bookmark_id(
return None;
}
- // With interleaving and more than one active entry, pick by time slot.
+ // With interleaving and more than one active entry, use a weighted cycle.
+ // Each entry's effective duration is its own interleave_min, falling back
+ // to the config-level default. The cycle length is the sum of all durations.
if active.len() > 1 {
- if let Some(step) = interleave_min.filter(|&s| s > 0) {
- let slot = (now_min as u64 / step as u64) as usize % active.len();
- return Some(active[slot].bookmark_id.clone());
+ let durations: Vec = active
+ .iter()
+ .map(|e| e.interleave_min.or(default_interleave).unwrap_or(0))
+ .collect();
+ let cycle: u32 = durations.iter().sum();
+ if cycle > 0 {
+ let pos = (now_min as u64) % (cycle as u64);
+ let mut cum = 0u64;
+ for (entry, &dur) in active.iter().zip(durations.iter()) {
+ cum += dur as u64;
+ if pos < cum {
+ return Some(entry.bookmark_id.clone());
+ }
+ }
}
}