From 8a77ef690d2b3541095725ebade1e2206355f16a Mon Sep 17 00:00:00 2001 From: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com> Date: Sat, 26 Jul 2025 10:42:38 +0200 Subject: [PATCH] feat: implement automatic timeout for hidden pages --- MMM-pages.js | 26 +++++++++++++++++++++++++- README.md | 8 +++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/MMM-pages.js b/MMM-pages.js index db2e0e0..ffbe6b7 100644 --- a/MMM-pages.js +++ b/MMM-pages.js @@ -66,6 +66,8 @@ Module.register('MMM-pages', { if (!this.config.useLockString) { Log.log('[MMM-pages] User opted to not use lock strings!'); } + + this.hiddenPageTimer = null; }, /** @@ -131,6 +133,7 @@ Module.register('MMM-pages', { break; case 'LEAVE_HIDDEN_PAGE': Log.log('[MMM-pages] received a notification to leave the current hidden page.'); + clearTimeout(this.hiddenPageTimer); this.animatePageChange(); this.setRotation(true); break; @@ -227,6 +230,7 @@ Module.register('MMM-pages', { * @param {number} delay the delay, in milliseconds. */ resetTimerWithDelay(delay) { + Log.debug(`[MMM-pages] resetTimerWithDelay called with delay: ${delay}ms`); if (this.config.timings.default > 0 || Object.keys(this.config.timings).length > 1) { // This timer is the auto rotate function. clearInterval(this.timer); @@ -239,6 +243,7 @@ Module.register('MMM-pages', { const self = this; this.delayTimer = setTimeout(() => { + Log.debug(`[MMM-pages] Starting auto rotation with interval: ${currentRotationTime}ms`); self.timer = setInterval(() => { // Inform other modules and page change. // MagicMirror automatically excludes the sender from receiving the @@ -296,11 +301,30 @@ Module.register('MMM-pages', { * @param {string} name the name of the hiddenPage we want to show */ showHiddenPage(name) { - // Only proceed if the named hidden page actually exists if (name in this.config.hiddenPages) { this.animatePageChange(name); + this.startHiddenPageTimer(name); } else { Log.error(`[MMM-pages] Hidden page "${name}" does not exist!`); } }, + + /** + * Starts a timer for a hidden page. + * + * @param {string} pageName - The name of the hidden page for which the timer is being started. + */ + startHiddenPageTimer(pageName) { + clearTimeout(this.hiddenPageTimer); + const timeout = this.config.timings[pageName]; + if (timeout && timeout > 0) { + Log.debug(`[MMM-pages] Starting hidden page timer for "${pageName}" with timeout ${timeout}ms`); + this.hiddenPageTimer = setTimeout(() => { + Log.debug(`[MMM-pages] Hidden page "${pageName}" timeout reached, returning to normal rotation`); + this.notificationReceived('LEAVE_HIDDEN_PAGE'); + }, timeout); + } else { + Log.debug(`[MMM-pages] No timeout configured for hidden page "${pageName}"`); + } + } }); diff --git a/README.md b/README.md index a5223e7..ce08900 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,8 @@ The first element of the array is the first page, the second element is the seco config: { timings: { default: 5000, // rotate every 5 seconds - 0: 20000 // page 0 rotates every 20 seconds + 0: 20000, // page 0 rotates every 20 seconds + "admin": 30000 // admin hidden page auto-returns after 30 seconds }, modules: [ ["newsfeed"], // page 0 @@ -108,7 +109,8 @@ Instead of using the module name, you can also use a class name for each page. T config: { timings: { default: 20000, // rotate every 20 seconds - 2: 30000 // page 2 rotates every 30 seconds + 2: 30000, // page 2 rotates every 30 seconds + "admin": 30000 // admin hidden page auto-returns after 30 seconds }, modules: [ ["page0"], // class name for page 0 @@ -172,7 +174,7 @@ You have to add the class name to the config of the module you want to show on a | `hiddenPages` | `{String: [String...]...}` | `{}` | An Object defining special `hiddenPages` which are not available on the normal page rotation and only accessible via a notification. Modules defined in `fixed` are ignored and need to be also added if you wish to have them on any hidden page. | | `animationTime` | `int` | `1000` | Fading animation time. Set to `0` for instant change. Value is in milliseconds (1 second = 1000 milliseconds). | | `rotationTime` | *NA* | *NA* | **Deprecated**. Use `timings` instead. | -| `timings` | `object` | `{ default: 0 }` | An object whose keys define the rotation time of the pages in milliseconds.
Example, where each page is 3 seconds, except page 3 which is 20 seconds:
`{ default: 3000, 2: 20000 }`
If a page is not defined, it will use the `default` value.
*Note:* Remember that the numbering starts at 0, so the first page is `0`, the second page is `1`, and so forth. | +| `timings` | `object` | `{ default: 0 }` | An object whose keys define the rotation time of the pages in milliseconds.
Example, where each page is 3 seconds, except page 3 which is 20 seconds:
`{ default: 3000, 2: 20000 }`
If a page is not defined, it will use the `default` value.
You can also specify timeouts for hidden pages by using the hidden page name as key (e.g., `"admin": 30000` will automatically return from the "admin" hidden page after 30 seconds).
*Note:* Remember that the numbering starts at 0, so the first page is `0`, the second page is `1`, and so forth. | | `rotationDelay` | `int` | `10000` | Time, in milliseconds, of how long should a manual page change linger before returning to automatic page changing. In other words, how long should the timer wait for after you manually change a page. This does include the animation time, so you may wish to increase it by a few seconds or so to account for the animation time. | | `rotationHomePage` | `int` | `0` | Time, in milliseconds, before automatically returning to the home page. If a home page is not set, this returns to the leftmost page instead. | | `rotationFirstPage` | *NA* | *NA* | **Deprecated**. Use `rotationHomePage` instead. |