@@ -24604,6 +24604,7 @@ async function togglePlayPauseEffective() {
2460424604 }
2460524605
2460624606 if (isPaused) {
24607+ normalizeFocusLoopBoundsForPlayback();
2460724608 const plan = buildTransportPlaybackPlan();
2460824609 if (plan && plan.invalid) {
2460924610 showToast(plan.invalidReason || "Cannot start Focus playback.", 3200);
@@ -24626,6 +24627,7 @@ async function togglePlayPauseEffective() {
2462624627 if (played) return;
2462724628 }
2462824629
24630+ if (focusModeEnabled) normalizeFocusLoopBoundsForPlayback();
2462924631 const plan = focusModeEnabled
2463024632 ? buildTransportPlaybackPlan()
2463124633 : (pendingPlaybackPlan || buildTransportPlaybackPlan());
@@ -24680,8 +24682,35 @@ async function transportTogglePlayPause() {
2468024682
2468124683async function transportPlay() {
2468224684 if (isPlaying) return;
24685+ if (focusModeEnabled) normalizeFocusLoopBoundsForPlayback();
2468324686 if (isPaused) {
24684- await startPlaybackFromRange();
24687+ const plan = buildTransportPlaybackPlan();
24688+ if (plan && plan.invalid) {
24689+ showToast(plan.invalidReason || "Cannot start Focus playback.", 3200);
24690+ return;
24691+ }
24692+ const resumeOffset = playbackRange ? Math.max(0, Number(playbackRange.startOffset) || 0) : 0;
24693+ await startPlaybackFromRange({
24694+ startOffset: resumeOffset,
24695+ endOffset: plan.rangeEnd,
24696+ origin: focusModeEnabled ? "focus" : "transport",
24697+ loop: plan.loopEnabled,
24698+ });
24699+ return;
24700+ }
24701+ if (focusModeEnabled) {
24702+ const plan = buildTransportPlaybackPlan();
24703+ if (plan && plan.invalid) {
24704+ showToast(plan.invalidReason || "Cannot start Focus playback.", 3200);
24705+ return;
24706+ }
24707+ applyPlaybackPlanSpeed(plan);
24708+ await startPlaybackFromRange({
24709+ startOffset: plan.rangeStart,
24710+ endOffset: plan.rangeEnd,
24711+ origin: "focus",
24712+ loop: plan.loopEnabled,
24713+ });
2468524714 return;
2468624715 }
2468724716 const startOffset = Math.max(0, Number(transportPlayheadOffset) || 0);
@@ -24694,6 +24723,7 @@ async function transportPause() {
2469424723 return;
2469524724 }
2469624725 if (isPaused) {
24726+ normalizeFocusLoopBoundsForPlayback();
2469724727 const plan = buildTransportPlaybackPlan();
2469824728 if (plan && plan.invalid) {
2469924729 showToast(plan.invalidReason || "Cannot start Focus playback.", 3200);
@@ -26311,16 +26341,33 @@ function updatePracticeUi() {
2631126341 }
2631226342}
2631326343
26314- function normalizeLoopBounds(fromMeasure, toMeasure, { changedField } = {} ) {
26344+ function normalizeLoopBounds(fromMeasure, toMeasure) {
2631526345 const from = clampInt(fromMeasure, 0, 100000, 0);
2631626346 const to = clampInt(toMeasure, 0, 100000, 0);
26317- if (from > 0 && to > 0 && from > to) {
26318- if (changedField === "to") return { from: to, to };
26319- return { from, to: from };
26320- }
2632126347 return { from, to };
2632226348}
2632326349
26350+ function normalizeFocusLoopBoundsForPlayback() {
26351+ if (!focusModeEnabled) return false;
26352+ const from = clampInt(playbackLoopFromMeasure, 0, 100000, 0);
26353+ const to = clampInt(playbackLoopToMeasure, 0, 100000, 0);
26354+ if (!(from > 0 && to > 0 && from > to)) return false;
26355+ playbackLoopFromMeasure = to;
26356+ playbackLoopToMeasure = from;
26357+ updatePracticeUi();
26358+ syncPendingPlaybackPlan();
26359+ const patch = {
26360+ playbackLoopFromMeasure: playbackLoopFromMeasure,
26361+ playbackLoopToMeasure: playbackLoopToMeasure,
26362+ };
26363+ if (activeTuneId) {
26364+ playbackLoopTuneId = String(activeTuneId);
26365+ patch.playbackLoopTuneId = playbackLoopTuneId;
26366+ }
26367+ persistLoopSettingsPatch(patch).catch(() => {});
26368+ return true;
26369+ }
26370+
2632426371function maybeResetFocusLoopForTune(tuneId, { updateUi = true } = {}) {
2632526372 if (!focusModeEnabled) return;
2632626373 const id = tuneId != null ? String(tuneId) : "";
@@ -29499,17 +29546,13 @@ if ($practiceLoopEnabled) {
2949929546if ($practiceLoopFrom) {
2950029547 $practiceLoopFrom.addEventListener("input", () => {
2950129548 const next = clampLoopField($practiceLoopFrom.value);
29502- const normalized = normalizeLoopBounds(next, playbackLoopToMeasure, { changedField: "from" });
29503- playbackLoopFromMeasure = normalized.from;
29504- playbackLoopToMeasure = normalized.to;
29549+ playbackLoopFromMeasure = next;
2950529550 syncPendingPlaybackPlan();
2950629551 updatePracticeUi();
2950729552 });
2950829553 $practiceLoopFrom.addEventListener("change", () => {
2950929554 const next = clampLoopField($practiceLoopFrom.value);
29510- const normalized = normalizeLoopBounds(next, playbackLoopToMeasure, { changedField: "from" });
29511- playbackLoopFromMeasure = normalized.from;
29512- playbackLoopToMeasure = normalized.to;
29555+ playbackLoopFromMeasure = next;
2951329556 syncPendingPlaybackPlan();
2951429557 updatePracticeUi();
2951529558 const patch = {
@@ -29527,17 +29570,13 @@ if ($practiceLoopFrom) {
2952729570if ($practiceLoopTo) {
2952829571 $practiceLoopTo.addEventListener("input", () => {
2952929572 const next = clampLoopField($practiceLoopTo.value);
29530- const normalized = normalizeLoopBounds(playbackLoopFromMeasure, next, { changedField: "to" });
29531- playbackLoopFromMeasure = normalized.from;
29532- playbackLoopToMeasure = normalized.to;
29573+ playbackLoopToMeasure = next;
2953329574 syncPendingPlaybackPlan();
2953429575 updatePracticeUi();
2953529576 });
2953629577 $practiceLoopTo.addEventListener("change", () => {
2953729578 const next = clampLoopField($practiceLoopTo.value);
29538- const normalized = normalizeLoopBounds(playbackLoopFromMeasure, next, { changedField: "to" });
29539- playbackLoopFromMeasure = normalized.from;
29540- playbackLoopToMeasure = normalized.to;
29579+ playbackLoopToMeasure = next;
2954129580 syncPendingPlaybackPlan();
2954229581 updatePracticeUi();
2954329582 const patch = {
0 commit comments