Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to prevent access to options early #213

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 38 additions & 22 deletions common.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ const PER_SET_OPTIONS = {
reloadSecs: { type: "string", def: "", id: "reloadSecs" },
allowOverride: { type: "boolean", def: false, id: "allowOverride" },
prevOpts: { type: "boolean", def: false, id: "prevOpts" },
prevOffToggle: { type: "boolean", def: false, id: "prevOffToggle"},
prevOffset: { type: "string", def: "", id: "prevOffset"},
prevGenOpts: { type: "boolean", def: false, id: "prevGenOpts" },
prevAddons: { type: "boolean", def: false, id: "prevAddons" },
prevSupport: { type: "boolean", def: false, id: "prevSupport" },
Expand Down Expand Up @@ -316,20 +318,35 @@ function getMinPeriods(times) {
return minPeriods;
}

// Clean time periods
// Convert minute periods to a string
//
function cleanTimePeriods(times) {
// Convert to minute periods
let minPeriods = getMinPeriods(times);
if (minPeriods.length == 0) {
return ""; // nothing to do
function minPeriodsToString(minPeriods) {
// Convert back to string list of time periods
let cleanTimes = [];
for (let mp of minPeriods) {
let h1 = Math.floor(mp.start / 60);
let m1 = (mp.start % 60);
let h2 = Math.floor(mp.end / 60);
let m2 = (mp.end % 60);
let period =
((h1 < 10) ? "0" : "") + h1 +
((m1 < 10) ? "0" : "") + m1 +
"-" +
((h2 < 10) ? "0" : "") + h2 +
((m2 < 10) ? "0" : "") + m2;
cleanTimes.push(period);
}
return cleanTimes.join(",");
}

// Trim, merge and sort minute periods
//
function processMinPeriods(minPeriods) {
// Step 1: Fix any times > 2400
for (let mp of minPeriods) {
mp.start = Math.min(mp.start, 1440);
mp.end = Math.min(mp.end, 1440);
}
}

// Step 2: Remove any periods without +ve duration
for (let i = 0; i < minPeriods.length; i++) {
Expand All @@ -353,22 +370,21 @@ function cleanTimePeriods(times) {
}
}

// Convert back to string list of time periods
let cleanTimes = [];
for (let mp of minPeriods) {
let h1 = Math.floor(mp.start / 60);
let m1 = (mp.start % 60);
let h2 = Math.floor(mp.end / 60);
let m2 = (mp.end % 60);
let period =
((h1 < 10) ? "0" : "") + h1 +
((m1 < 10) ? "0" : "") + m1 +
"-" +
((h2 < 10) ? "0" : "") + h2 +
((m2 < 10) ? "0" : "") + m2;
cleanTimes.push(period);
return minPeriods;
}

// Clean time periods
//
function cleanTimePeriods(times) {
// Convert to minute periods
let minPeriods = getMinPeriods(times);
if (minPeriods.length == 0) {
return ""; // nothing to do
}
return cleanTimes.join(",");

const cleanPeriods = processMinPeriods(minPeriods);

return minPeriodsToString(cleanPeriods);
}

// Calculate start of time period from current time and time limit period
Expand Down
4 changes: 4 additions & 0 deletions options.html
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@
<input id="prevOpts1" type="checkbox">
<label for="prevOpts1">Prevent access to options for this block set at times when these sites are blocked</label>
</p>
<p>
<input id="prevOffToggle1" type="checkbox">
<label for="prevOffToggle1">Prevent access to options for this block set <input id="prevOffset1" type="text" size="2" title="Leave blank for no offset"> minutes early</label>
</p>
<p>
<input id="prevGenOpts1" type="checkbox">
<label for="prevGenOpts1">Prevent access to General options at times when these sites are blocked</label>
Expand Down
117 changes: 98 additions & 19 deletions options.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ function saveOptions(event) {
let delaySecs = $(`#delaySecs${set}`).val();
let reloadSecs = $(`#reloadSecs${set}`).val();
let blockURL = $(`#blockURL${set}`).val();
let optBlockOffset = $(`#prevOffset${set}`).val();

// Check field values
if (!checkTimePeriodsFormat(times)) {
Expand Down Expand Up @@ -166,6 +167,12 @@ function saveOptions(event) {
$("#alertBadBlockURL").dialog("open");
return false;
}
if (!checkPosIntFormat(optBlockOffset)) {
$("#tabs").tabs("option", "active", (set - 1));
$(`#prevOffset${set}`).focus();
$("#alertBadSeconds").dialog("open");
return false;
}
}

// Check format for text fields in general options
Expand Down Expand Up @@ -386,44 +393,116 @@ function retrieveOptions() {
// Get options
let timedata = options[`timedata${set}`];
let times = options[`times${set}`];
let minPeriods = getMinPeriods(times);
let minPeriods = processMinPeriods(getMinPeriods(times));
let limitMins = options[`limitMins${set}`];
let limitPeriod = options[`limitPeriod${set}`];
let limitOffset = options[`limitOffset${set}`];
let periodStart = getTimePeriodStart(now, limitPeriod, limitOffset);
let conjMode = options[`conjMode${set}`];
let days = options[`days${set}`];
let blockOffToggle = options[`prevOffToggle${set}`];
let blockOffset = options[`prevOffset${set}`];

// Check day
let onSelectedDay = days[timedate.getDay()];

// Check time periods
let withinTimePeriods = false;
if (onSelectedDay && times) {
// Check each time period in turn
let currentDay = timedate.getDay();
let onSelectedDay = days[currentDay];

// Check inputs
let useBlockTimes = times;
let useTimeLimit = limitMins && limitPeriod && ((limitMins * 60) < limitPeriod);

// Check option lock scheme
let lockScheme = blockOffToggle && blockOffset;

// Change 'if(lockScheme)' to 'switch(lockScheme)' if more schemes are added
let optionsLocked = false;
if (lockScheme) {
/** 24 hours in minutes */
const fullDay = 24 * 60;

// Setup
let earlyStart = Math.max(0, Math.min(fullDay, parseInt(blockOffset))) || 0;
let tomorrowSelected = days[(currentDay + 1) % 7];
let checkTomorrow = tomorrowSelected && ((mins - fullDay + earlyStart) >= 0);

/** If any minPeriod is active or within range */
let nearTimePeriods = false;
// Check time period proximity
for (let mp of minPeriods) {
if (mins >= mp.start && mins < mp.end) {
withinTimePeriods = true;
// Check time periods as normal if today is selected
if (onSelectedDay) {
if (mins >= (mp.start - earlyStart) && mins <= mp.end) {
nearTimePeriods = true;
}
}

// Check across day boundary if tomorrow is selected
if (tomorrowSelected) {
/** 'mins' relative to midnight tomorrow */
let shiftedMins = mins - fullDay;
// Check tomorrow's time periods
if (shiftedMins >= (mp.start - earlyStart) && shiftedMins <= mp.end) {
nearTimePeriods = true;
}
}
}
}

// Check time limit
let afterTimeLimit = false;
if (onSelectedDay && limitMins && limitPeriod) {
// Check time period and time limit
if (timedata[2] == periodStart && timedata[3] >= (limitMins * 60)) {
afterTimeLimit = true;
/** If timelimits need to be checked at all */
let checkTimeLimit = onSelectedDay || checkTomorrow;

/** If a current/upcoming timelimit does not have enough time left */
let nearTimeLimit = false;
// Check time limit proximity
if (useTimeLimit && checkTimeLimit) {
/** The amount of the timelimit that can be used before options lock */
let lockTimeLimit = limitMins - earlyStart;

// Positive lock TL: Check only the active time limit period
if (lockTimeLimit > 0) {
let secondsLeft = lockTimeLimit * 60;
if (timedata[2] == periodStart) {
secondsLeft = Math.max(0, secondsLeft - timedata[3]);
}
nearTimeLimit = secondsLeft <= 0;
} else {
// Negative lock TL: Complex interactions with timedata/time periods/day borders
// skipped for simplicity
nearTimeLimit = true;
}
}

optionsLocked = (!conjMode && (nearTimePeriods || nearTimeLimit)) ||
(conjMode && (nearTimePeriods && nearTimeLimit));
} else {
// Check time periods
let withinTimePeriods = false;
if (useBlockTimes && onSelectedDay) {
// Check each time period in turn
for (let mp of minPeriods) {
if (mins >= mp.start && mins < mp.end) {
withinTimePeriods = true;
}
}
}

// Check time limit
let afterTimeLimit = false;
if (useTimeLimit && onSelectedDay) {
// Check time period and time limit
if (timedata[2] == periodStart && timedata[3] >= (limitMins * 60)) {
afterTimeLimit = true;
}
}

optionsLocked = (!conjMode && (withinTimePeriods || afterTimeLimit))
|| (conjMode && (withinTimePeriods && afterTimeLimit));
}

// Check lockdown condition
let lockdown = (timedata[4] > now);

// Disable options if specified block conditions are fulfilled
if (lockdown
|| (!conjMode && (withinTimePeriods || afterTimeLimit))
|| (conjMode && (withinTimePeriods && afterTimeLimit))) {
if (lockdown || optionsLocked) {
if (options[`prevOpts${set}`]) {
gNumSetsMin = set;
// Disable options for this set
Expand Down