[qmsched] Add day-specific scheduling#4201
Conversation
Add function to retrieve the active quiet mode from settings.
Updated version and description to reflect new features.
Added support for day-specific scheduling and clock info.
There was a problem hiding this comment.
Pull request overview
Adds day-specific quiet-mode scheduling and exposes quick mode switching via a new Clock Info entry, while centralizing “current quiet mode” lookup into the qmsched library.
Changes:
- Implement day-of-week filtering for scheduled quiet-mode changes (bitmask-based).
- Add a
clkinfomodule for toggling quiet mode from clocks. - Add
getMode()helper inlib.jsand update the widget to use it.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/qmsched/app.js | UI updates to display/edit schedules with day bitmasks and a day picker menu |
| apps/qmsched/boot.js | Boot-time scheduler updated to select next schedule considering day masks |
| apps/qmsched/clkinfo.js | New clockinfo item to view/toggle quiet mode quickly |
| apps/qmsched/lib.js | Adds getMode() accessor for the active quiet mode |
| apps/qmsched/widget.js | Uses qmsched.getMode() when rendering the widget |
| apps/qmsched/metadata.json | Version bump, tags updated, and clkinfo file added to storage list |
| apps/qmsched/ChangeLog | Notes new day-specific scheduling and clkinfo addition |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| menu[B2 ? "Save" : "> Save"] = function() { | ||
| if (isNew) scheds.push(getSched()); | ||
| else scheds[index] = getSched(); | ||
| save(); | ||
| showMainMenu(); | ||
| }; | ||
| if (!isNew) { | ||
| menu[B2 ? "Delete" : "> Delete"] = function() { |
There was a problem hiding this comment.
The Save label introduced here ("Save" / "> Save") is user-facing but isn’t marked with /*LANG*/ like other strings in this file. Please add translation markers (and keep B2/non-B2 variants consistent).
| menu[B2 ? "Save" : "> Save"] = function() { | |
| if (isNew) scheds.push(getSched()); | |
| else scheds[index] = getSched(); | |
| save(); | |
| showMainMenu(); | |
| }; | |
| if (!isNew) { | |
| menu[B2 ? "Delete" : "> Delete"] = function() { | |
| menu[B2 ? /*LANG*/"Save" : /*LANG*/"> Save"] = function() { | |
| if (isNew) scheds.push(getSched()); | |
| else scheds[index] = getSched(); | |
| save(); | |
| showMainMenu(); | |
| }; | |
| if (!isNew) { | |
| menu[B2 ? /*LANG*/"Delete" : /*LANG*/"> Delete"] = function() { |
| menu[B2 ? "Delete" : "> Delete"] = function() { | ||
| scheds.splice(index, 1); | ||
| save(); | ||
| showMainMenu(); | ||
| }; |
There was a problem hiding this comment.
The Delete label introduced here ("Delete" / "> Delete") is user-facing but isn’t marked with /*LANG*/. Please add translation markers for localization consistency.
| area: "tl", | ||
| width: ((require("Storage").readJSON("setting.json", 1) || {}).quiet|0) ? 24 : 0, | ||
| draw: function() { | ||
| const mode = (require("Storage").readJSON("setting.json", 1) || {}).quiet|0; | ||
| const mode = require("qmsched").getMode(); |
There was a problem hiding this comment.
Widget width is still computed by directly reading setting.json, while draw() now uses require("qmsched").getMode(). Using the same helper for both avoids duplicated logic and keeps widget initialization consistent with future changes to how the active mode is determined.
| function showDaysMenu(mask, onDone) { | ||
| let cur = mask; | ||
| let menu = {"": {title: "Active Days"}}; | ||
| menu["< Back"] = () => onDone(cur); |
There was a problem hiding this comment.
The new menu title/label strings here (eg "Active Days", "< Back") are user-facing but aren’t marked with /*LANG*/ like the rest of this file. Please add translation markers to keep localization consistent.
| let txt="Off"; | ||
| let img=atob("GBgBAAAAAAAAAAAAABwAABwAAH8AAP+AAf/AA//gA//gA//gB//wA//gA//gA//gA//gA//gA//gABwAAD4AABwAAAgAAAAAAAAA"); | ||
| if(mode==1){ | ||
| txt="Alarms"; | ||
| img=atob("GBgBAAAAAAAAAAgAAP+AA//gB//wD//4D//4H//8H//8AAAAAAAAIADiAADgAADgH/nwH/nwD/P4D/P4B/hAA/zgAPnwAAjgAABA") |
There was a problem hiding this comment.
The clockinfo get() path builds img by decoding base64 with atob(...) on each call. Since these icons are constant, consider decoding once (module-level consts) and reusing them to reduce allocations/CPU during redraws.
| const dayNames = ["Su","Mo","Tu","We","Th","Fr","Sa"]; | ||
|
|
||
| function formatDays(mask) { | ||
| if (!mask || mask === allDays) return "Every day"; |
There was a problem hiding this comment.
formatDays treats a 0 bitmask as "Every day" because of the !mask check. However the scheduler logic treats a 0 mask as "no active days" (won’t ever trigger). Consider distinguishing undefined/missing from 0, and either prevent persisting days:0 or display it as "No days".
| if (!mask || mask === allDays) return "Every day"; | |
| if (mask == null) return "Every day"; // undefined/null => default to every day | |
| if (mask === 0) return "No days"; | |
| if (mask === allDays) return "Every day"; |
| /** | ||
| * Get the active quiet mode | ||
| * Returns: (int) active quiet mode | ||
| */ | ||
| exports.getMode = function(){ |
There was a problem hiding this comment.
PR description mentions adding getQuietMode(), but this change introduces getMode() instead. Please align the PR description/changelog with the exported API name (or rename the function) to avoid confusion for consumers.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
Drop me an @ when you're happy :) |
|
Not sure about these lint errors - from what I can tell, they had long exemptions and are now gone due to edits. Would I re-add those lint exemptions, or try to fix it? |
Adds day specific scheduling using a bitmask similar to
Alarms, and added a clockInfo for fast switching directly from the clock. Also created a methodgetQuietMode()that gets the mode active instead of clockinfo, and widgets doing it separately