Skip to content

Fix block page showing cycle rollover time during manual lockdown#712

Open
absurd wants to merge 1 commit into
proginosko:masterfrom
absurd:fix-lockdown-unblock-time
Open

Fix block page showing cycle rollover time during manual lockdown#712
absurd wants to merge 1 commit into
proginosko:masterfrom
absurd:fix-lockdown-unblock-time

Conversation

@absurd
Copy link
Copy Markdown

@absurd absurd commented Apr 10, 2026

Bug

When a manual lockdown is active on a block set that also has a time-limit cycle (e.g. "20 minutes in every 4 hours"), and the lockdown ends before the next cycle rollover, the block page shows the rollover time instead of the lockdown end time.

Reproduction:

  1. Configure a block set with limitMins=20, limitPeriod=14400 (4 h), no time periods.
  2. Do not consume the 20-minute time limit.
  3. From lockdown.html, select the set and activate a short lockdown (e.g. 10 minutes) that ends before the next cycle rollover.
  4. Navigate to a URL matched by the set.

Expected: block page shows the lockdown end time.
Actual: block page shows the next cycle rollover time (e.g. "4:00:00 PM" when the 4-hour cycle rolls over at 4 PM, even though the lockdown ends at ~3:10 PM).

Before (pre-fix): block page shows 4:00:00 PM — the cycle rollover, despite the lockdown ending 24 minutes earlier.

pre-fix block page showing cycle rollover time

After (with this fix): same state, block page shows 3:36:49 PM — the actual lockdown end time.

post-fix block page showing lockdown end time

Root cause

In getUnblockTime(), Case 2 (!timePeriods && timeLimit, lines 1283–1287) and the Case 4 fallback (lines 1333–1336) unconditionally set:

unblockTime = new Date(timedata[2] * 1000 + limitPeriod * 1000);

…even when the time limit had not actually been exceeded. The lockdown check below (lines 1340–1346) only raises unblockTime if lockdownEnd > unblockTime, so an earlier lockdown end was masked by the later cycle rollover. The min-block-time check (lines 1348–1354) has the same shape.

Change

Gate the Case 2 and Case 4 cycle-rollover assignments on an afterTimeLimit check — the same computation already present inside Case 4. When the time limit is not actually exceeded, leave unblockTime null so the existing lockdown / minimum-block-time checks install the correct end time.

The existing endTime > unblockTime comparisons in the lockdown and min-block checks already tolerate a null unblockTime (Date coerces to its epoch-ms value, null coerces to 0), so no changes there are required.

Case 3 (conjMode) is deliberately left alone — fixing the analogous edge case there would require broader changes and is out of scope for a minimal bug fix.

Diff: background.js +9/-2, VERSIONS.md +3.

Verification

I tested by directly calling getUnblockTime() against a synthesized timedata[] state for each of: lockdown-only (the bug repro), limit exhausted + no lockdown, lockdown-after-rollover, min-block only, limit exhausted + lockdown-before-rollover, and a "nothing active" degenerate case. All produce the expected unblock time. Also confirmed end-to-end by navigating to a blocked URL in Firefox with the bug-repro state applied — blocked.html now shows the lockdown end time instead of the cycle rollover (screenshots above).

Note on behavior change

In the "no block reason is actually active" edge case (time limit not exceeded, no lockdown, no min-block, no time period — a state that shouldn't normally arise when the block page is shown), getUnblockTime() now returns null instead of falling back to the cycle rollover. blocked.html renders this as "the end of time", matching its default placeholder. I believe this is correct — there is no principled unblock time to show in that case — but happy to revisit if you'd rather preserve the old behavior.

When a manual lockdown is in effect and the current time-limit cycle has
not been exceeded, getUnblockTime() in background.js was unconditionally
using the cycle rollover time, then only raising unblockTime to the
lockdown end if the latter was later. The effect: a manual lockdown
ending before the next cycle rollover was obscured on the block page,
which showed the cycle rollover time instead of the actual lockdown end.

Fix: gate the Case 2 and Case 4 cycle-rollover assignments on an
afterTimeLimit check, matching the existing one already computed inside
Case 4. When the time limit is not actually exceeded, leave unblockTime
null so the subsequent lockdown / minimum-block-time checks install the
correct end time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant