Skip to content

Commit dc4fad4

Browse files
author
veeck
committed
Merge branch 'mm_develop' into envcanada
2 parents e7d8413 + a49fbed commit dc4fad4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+4553
-3326
lines changed

.github/workflows/automated-tests.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
- name: "Checkout code"
2121
uses: actions/checkout@v5
2222
- name: "Use Node.js"
23-
uses: actions/setup-node@v4
23+
uses: actions/setup-node@v5
2424
with:
2525
node-version: lts/*
2626
cache: "npm"
@@ -38,7 +38,7 @@ jobs:
3838
timeout-minutes: 30
3939
strategy:
4040
matrix:
41-
node-version: [22.14.0, 22.x, 24.x]
41+
node-version: [22.18.0, 22.x, 24.x]
4242
steps:
4343
- name: Install electron dependencies and labwc
4444
run: |
@@ -47,7 +47,7 @@ jobs:
4747
- name: "Checkout code"
4848
uses: actions/checkout@v5
4949
- name: "Use Node.js ${{ matrix.node-version }}"
50-
uses: actions/setup-node@v4
50+
uses: actions/setup-node@v5
5151
with:
5252
node-version: ${{ matrix.node-version }}
5353
check-latest: true

.github/workflows/electron-rebuild.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ jobs:
88
runs-on: ubuntu-latest
99
strategy:
1010
matrix:
11-
node-version: [22.14.0, 22.x, 24.x]
11+
node-version: [22.18.0, 22.x, 24.x]
1212
steps:
1313
- name: Checkout code
1414
uses: actions/checkout@v5
1515
- name: "Use Node.js ${{ matrix.node-version }}"
16-
uses: actions/setup-node@v4
16+
uses: actions/setup-node@v5
1717
with:
1818
node-version: ${{ matrix.node-version }}
1919
check-latest: true

.github/workflows/spellcheck.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
with:
2020
ref: develop
2121
- name: Set up Node.js
22-
uses: actions/setup-node@v4
22+
uses: actions/setup-node@v5
2323
with:
2424
node-version: lts/*
2525
check-latest: true

.github/workflows/stale.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
stale:
1313
runs-on: ubuntu-latest
1414
steps:
15-
- uses: actions/stale@v9
15+
- uses: actions/stale@v10
1616
with:
1717
stale-issue-message: "This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions."
1818
days-before-issue-stale: 60

CHANGELOG.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,20 @@ planned for 2025-10-01
1313

1414
Thanks to: @dathbe.
1515

16+
> ⚠️ This release needs nodejs version `v22.18.0 or higher`
17+
1618
### Added
1719

18-
- Added configuration option for `User-Agent`, used by calendar & news module (#3255)
20+
- Add configuration option for `User-Agent`, used by calendar & news module (#3255)
21+
- [linter] Add prettier plugin for nunjuck templates (#3887)
22+
- [core] Add clear log for occupied port at startup (#3890)
1923

2024
### Changed
2125

2226
- [clock] Add CSS to prevent line breaking of sunset/sunrise time display (#3816)
2327
- [core] Enhance system information logging format and include additional env and RAM details (#3839, #3843)
2428
- [refactor] Add new file `js/module_functions.js` to move code used in several modules to one place (#3837)
29+
- [refactor] Use global.root_path where possible and add tests for config:check (#3883, #3885, #3886, #3889)
2530
- [tests] refactor: simplify jest config file (#3844)
2631
- [tests] refactor: extract constants for weather electron tests (#3845)
2732
- [tests] refactor: add `setupDOMEnvironment` helper function to eliminate repetitive JSDOM setup code (#3860)
@@ -35,10 +40,14 @@ Thanks to: @dathbe.
3540
- Avoid potential port conflicts by using port 3001 for translator unit tests
3641
- Improve test reliability and maintainability
3742
- [tests] add alert module tests for different welcome_message configurations (#3867)
43+
- [lint-staged] use `prettier --write --ignore-unknown` in `lint-staged` to avoid errors on unsupported files (#3888)
3844

3945
### Updated
4046

41-
- [core] Update dependencies including electron to v37 as well as github actions (#3831, #3849, #3857, #3858)
47+
- [calendar] Update defaultSymbol name and also the link to the icon search site (#3879)
48+
- [core] Update dependencies including electron to v38 as well as github actions (#3831, #3849, #3857, #3858, #3872, #3876, #3882, #3891)
49+
- [weather] Update feels_like temperature calculation formula (#3869)
50+
- [weather] Update null value handling for weather type (#3892)
4251

4352
### Fixed
4453

@@ -48,6 +57,7 @@ Thanks to: @dathbe.
4857
- [calendar] Fix regression handling of limit days (#3840)
4958
- [calendar] Fixed regression of calendarfetcherutils.shouldEventBeExcluded (#3841)
5059
- [core] Fixed socket.io timeout when server is slow to send notification, notification lost at client (#3380)
60+
- [tests] refactor AnimateCSS tests after jsdom 27 upgrade (#3891)
5161
- [weather] Use `apparent_temperature` data from openmeteo's hourly weather for current feelsLikeTemp (#3868).
5262
- [weather] Updated envcanada Provider to use new database/URL schema for accessing weather data (#3822).
5363

@@ -304,7 +314,7 @@ For more info, please read the following post: [A New Chapter for MagicMirror: T
304314
### Added
305315

306316
- Output of system information to the console for troubleshooting (#3328 and #3337), ignore errors under aarch64 (#3349)
307-
- [core] Add `eslint-plugin-package-json` to lint the `package.json` files (#3368)
317+
- [linter] Add `eslint-plugin-package-json` to lint the `package.json` files (#3368)
308318
- [weather] `showHumidity` config is now a string describing where to show this element. Supported values: "wind", "temp", "feelslike", "below", "none". (#3330)
309319
- electron-rebuild test suite for electron and 3rd party modules compatibility (#3392)
310320
- Create MM² icon and attach it to electron process (#3407)
@@ -466,7 +476,7 @@ Special thanks to @khassel, @rejas and @sdetweil for taking over most (if not al
466476
- Added UV Index to hourly and current Weather, with support for Openmeteo
467477
- Added tests for serveronly
468478
- Set Timezone `Europe/Berlin` in unit tests (needed for new formatTime tests)
469-
- Added no-param-reassign eslint rule and fix warnings
479+
- [linter] Added no-param-reassign eslint rule and fix warnings
470480
- [updatenotification] Added `sendUpdatesNotifications` feature. Broadcast update with `UPDATES` notification to other modules
471481
- [updatenotification] Allow force scanning with `SCAN_UPDATES` notification from other modules
472482
- Added per-calendar fetchInterval

Collaboration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Are done by
3535
- [ ] test `prep-release` branch
3636
- [ ] update `CHANGELOG.md`
3737
- [ ] add all contributor names: `...`
38-
- [ ] add min. node version: > ⚠️ This release needs nodejs version `v22.14.0` or higher
38+
- [ ] add min. node version: > ⚠️ This release needs nodejs version `v22.18.0` or higher
3939
- [ ] check release link at the bottom of the file
4040
- [ ] commit and push all changes
4141
- [ ] create pull request from `prep-release` to `develop` branch with title `Prepare Release 2.xx.0`

eslint.config.mjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import globals from "globals";
33
import {flatConfigs as importX} from "eslint-plugin-import-x";
44
import jest from "eslint-plugin-jest";
55
import js from "@eslint/js";
6-
import jsdoc from "eslint-plugin-jsdoc";
6+
import jsdocPlugin from "eslint-plugin-jsdoc";
77
import packageJson from "eslint-plugin-package-json";
88
import stylistic from "@stylistic/eslint-plugin";
99

@@ -23,8 +23,8 @@ export default defineConfig([
2323
moment: "readonly"
2424
}
2525
},
26-
plugins: {js, jsdoc, stylistic},
27-
extends: [importX.recommended, jest.configs["flat/recommended"], "js/recommended", jsdoc.configs["flat/recommended"], "stylistic/all"],
26+
plugins: {js, stylistic},
27+
extends: [importX.recommended, jest.configs["flat/recommended"], "js/recommended", jsdocPlugin.configs["flat/recommended"], "stylistic/all"],
2828
rules: {
2929
"@stylistic/array-element-newline": ["error", "consistent"],
3030
"@stylistic/arrow-parens": ["error", "always"],

js/app.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,27 @@ const path = require("node:path");
66
const envsub = require("envsub");
77
const Log = require("logger");
88

9+
// global absolute root path
10+
global.root_path = path.resolve(`${__dirname}/../`);
11+
912
const Server = require(`${__dirname}/server`);
1013
const Utils = require(`${__dirname}/utils`);
11-
const defaultModules = require(`${__dirname}/../modules/default/defaultmodules`);
14+
15+
const defaultModules = require(`${global.root_path}/modules/default/defaultmodules`);
1216
// used to control fetch timeout for node_helpers
1317
const { setGlobalDispatcher, Agent } = require("undici");
1418
const { getEnvVarsAsObj } = require("#server_functions");
1519
// common timeout value, provide environment override in case
1620
const fetch_timeout = process.env.mmFetchTimeout !== undefined ? process.env.mmFetchTimeout : 30000;
1721

1822
// Get version number.
19-
global.version = require(`${__dirname}/../package.json`).version;
23+
global.version = require(`${global.root_path}/package.json`).version;
2024
global.mmTestMode = process.env.mmTestMode === "true";
2125
Log.log(`Starting MagicMirror: v${global.version}`);
2226

2327
// Log system information.
2428
Utils.logSystemInformation(global.version);
2529

26-
// global absolute root path
27-
global.root_path = path.resolve(`${__dirname}/../`);
28-
2930
if (process.env.MM_CONFIG_FILE) {
3031
global.configuration_file = process.env.MM_CONFIG_FILE.replace(`${global.root_path}/`, "");
3132
}
@@ -180,10 +181,10 @@ function App () {
180181
const elements = module.split("/");
181182
const moduleName = elements[elements.length - 1];
182183
const env = getEnvVarsAsObj();
183-
let moduleFolder = path.resolve(`${__dirname}/../${env.modulesDir}`, module);
184+
let moduleFolder = path.resolve(`${global.root_path}/${env.modulesDir}`, module);
184185

185186
if (defaultModules.includes(moduleName)) {
186-
const defaultModuleFolder = path.resolve(`${__dirname}/../modules/default/`, module);
187+
const defaultModuleFolder = path.resolve(`${global.root_path}/modules/default/`, module);
187188
if (process.env.JEST_WORKER_ID === undefined) {
188189
moduleFolder = defaultModuleFolder;
189190
} else {

js/server.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,29 @@ function Server (config) {
5555
});
5656

5757
Log.log(`Starting server on port ${port} ... `);
58+
59+
// Add explicit error handling BEFORE calling listen so we can give user-friendly feedback
60+
server.once("error", (err) => {
61+
if (err && err.code === "EADDRINUSE") {
62+
const bindAddr = config.address || "localhost";
63+
const portInUseMessage = [
64+
"",
65+
"────────────────────────────────────────────────────────────────",
66+
` PORT IN USE: ${bindAddr}:${port}`,
67+
"",
68+
" Another process (most likely another MagicMirror instance)",
69+
" is already using this port.",
70+
"",
71+
" Stop the other process (free the port) or use a different port.",
72+
"────────────────────────────────────────────────────────────────"
73+
].join("\n");
74+
Log.error(portInUseMessage);
75+
return;
76+
}
77+
78+
Log.error("Failed to start server:", err);
79+
});
80+
5881
server.listen(port, config.address || "localhost");
5982

6083
if (config.ipWhitelist instanceof Array && config.ipWhitelist.length === 0) {
Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
{% if imageUrl or imageFA %}
2-
{% set imageHeight = imageHeight if imageHeight else "80px" %}
3-
{% if imageUrl %}
4-
<img src="{{ imageUrl }}"
5-
height="{{ imageHeight }}"
6-
style="margin-bottom: 10px" />
7-
{% else %}
8-
<span class="bright fas fa-{{ imageFA }}"
9-
style="margin-bottom: 10px;
10-
font-size: {{ imageHeight }}"></span>
11-
{% endif %}
12-
<br />
2+
{% set imageHeight = imageHeight if imageHeight else "80px" %}
3+
{% if imageUrl %}
4+
<img src="{{ imageUrl }}" height="{{ imageHeight }}" style="margin-bottom: 10px" />
5+
{% else %}
6+
<span
7+
class="bright fas fa-{{ imageFA }}"
8+
style="margin-bottom: 10px;
9+
font-size: {{ imageHeight }}"
10+
></span>
11+
{% endif %}
12+
<br />
1313
{% endif %}
1414
{% if title %}
15-
<span class="thin dimmed medium">{{ title if titleType == 'text' else title | safe }}</span>
15+
<span class="thin dimmed medium">{{ title if titleType == 'text' else title | safe }}</span>
1616
{% endif %}
1717
{% if message %}
18-
{% if title %}<br />{% endif %}
19-
<span class="light bright small">{{ message if messageType == 'text' else message | safe }}</span>
18+
{% if title %}<br />{% endif %}
19+
<span class="light bright small">{{ message if messageType == 'text' else message | safe }}</span>
2020
{% endif %}

0 commit comments

Comments
 (0)