Skip to content

Commit 1ce0f46

Browse files
committed
fix changelog
2 parents 212771e + 76fac78 commit 1ce0f46

Some content is hidden

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

42 files changed

+1462
-141
lines changed

.github/CONTRIBUTING.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,28 @@ We hold our code to standard, and these standards are documented below.
66

77
## Linters
88

9-
We use prettier for automatic linting of all our files: `npm run lint:prettier`.
9+
We use [prettier](https://prettier.io/) for automatic formatting a lot all our files. The configuration is in our `prettier.config.mjs` file.
1010

11-
### JavaScript: Run ESLint
11+
To run prettier, use `npm run lint:prettier`.
1212

13-
We use [ESLint](https://eslint.org) on our JavaScript files.
13+
### JavaScript: Run ESLint
1414

15-
The ESLint configuration is in our `eslint.config.mjs` file.
15+
We use [ESLint](https://eslint.org) to lint our JavaScript files. The configuration is in our `eslint.config.mjs` file.
1616

1717
To run ESLint, use `npm run lint:js`.
1818

1919
### CSS: Run StyleLint
2020

21-
We use [StyleLint](https://stylelint.io) to lint our CSS. Our configuration is in our `.stylelintrc` file.
21+
We use [StyleLint](https://stylelint.io) to lint our CSS. The configuration is in our `.stylelintrc.json` file.
2222

2323
To run StyleLint, use `npm run lint:css`.
2424

25+
### Markdown: Run markdownlint
26+
27+
We use [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) to lint our markdown files. The configuration is in our `.markdownlint.json` file.
28+
29+
To run markdownlint, use `npm run markdownlint:css`.
30+
2531
## Testing
2632

2733
We use [Jest](https://jestjs.io) for JavaScript testing.

.github/workflows/automated-tests.yaml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,26 @@ permissions:
1313
contents: read
1414

1515
jobs:
16+
code-style-check:
17+
runs-on: ubuntu-latest
18+
timeout-minutes: 15
19+
steps:
20+
- name: "Checkout code"
21+
uses: actions/checkout@v4
22+
- name: "Use Node.js"
23+
uses: actions/setup-node@v4
24+
with:
25+
node-version: 23
26+
cache: "npm"
27+
- name: "Install dependencies"
28+
run: |
29+
npm run install-mm:dev
30+
- name: "Run linter tests"
31+
run: |
32+
npm run test:prettier
33+
npm run test:js
34+
npm run test:css
35+
npm run test:markdown
1636
test:
1737
runs-on: ubuntu-latest
1838
timeout-minutes: 30
@@ -36,7 +56,4 @@ jobs:
3656
Xvfb :99 -screen 0 1024x768x16 &
3757
export DISPLAY=:99
3858
touch css/custom.css
39-
npm run test:prettier
40-
npm run test:js
41-
npm run test:css
4259
npm run test

.markdownlint.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"line_length": false,
3+
"no-duplicate-heading": false,
4+
"no-inline-html": false,
5+
"no-trailing-punctuation": false
6+
}

.prettierrc.json

Lines changed: 0 additions & 3 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,26 @@ _This release is scheduled to be released on 2025-01-01._
1616
- [core] Add wayland and windows start options to `package.json` (#3594)
1717
- [docs] Add step for npm publishing in release process (#3595)
1818
- [core] Add GitHub workflow to run spellcheck a few days before each release (#3623)
19-
- [core] Add intest flag to index.html to pass to module js for test mode detection (needed by #3630)
20-
- [compliments] add support for refreshing remote compliments file, and testcases (#3630)
19+
- [core] Add test flag to `index.html` to pass to module js for test mode detection (needed by #3630)
20+
- [core] Add export on animation names (#3644)
21+
- [compliments] Add support for refreshing remote compliments file, and test cases (#3630)
2122
- [linter] Re-add `eslint-plugin-import`now that it supports ESLint v9 (#3586)
22-
- [linter] Re-activate `eslint-plugin-package-json` to lint `package.json`
23-
- [core] Add export on animation names
23+
- [linter] Re-activate `eslint-plugin-package-json` to lint `package.json` (#3643)
24+
- [linter] Add linting for markdown files (#3646)
25+
- [calendar] - added ability to display end date for full date events, where end is not same day (showEnd=true)
26+
27+
### Changed
28+
29+
- [core] Run code style checks in workflow only once.
2430

2531
### Removed
2632

27-
- [tests] Removed node-pty and drivelist from rebuilded test (#3575)
33+
- [tests] Remove `node-pty` and `drivelist` from rebuilded test (#3575)
2834
- [deps] Remove `@eslint/js` dependency. Already installed with `eslint` in deep (#3636)
2935

3036
### Updated
3137

32-
- [repo] reactivated `stale.yaml` as github action to mark issues as stale after 60 days and close them 7 days later (if no activity)
38+
- [repo] Reactivate `stale.yaml` as GitHub action to mark issues as stale after 60 days and close them 7 days later (if no activity) (#3577, #3580, #3581)
3339
- [core] Update electron dependency to v32 (test electron rebuild) and other dependencies too
3440
- [tests] All test configs have been updated to allow full external access, allowing for easier debugging (especially when running as a container)
3541
- [core] Run and test with node 23 (#3588)
@@ -38,12 +44,17 @@ _This release is scheduled to be released on 2025-01-01._
3844

3945
- [updatenotification] Fix pm2 using detection when pm2 script is inside or outside MagicMirror root folder (#3576) (#3605) (#3626) (#3628)
4046
- [core] Fix loading node_helper of modules: avoid black screen, display errors and continue loading with next module (#3578)
41-
- [weather] Changed default value for weatherEndpoint of provider openweathermap to "/onecall" (#3574)
42-
- [tests] Fix electron tests with mock dates, the mock on server side was missing (#3597)
43-
- [tests] Fix test cases with hard coded Date.now (#3597)
47+
- [weather] changed default value for weatherEndpoint of provider openweathermap to "/onecall" (#3574)
48+
- [tests] fix electron tests with mock dates, the mock on server side was missing (#3597)
49+
- [tests] fix testcases with hard coded Date.now (#3597)
4450
- [core] Fix missing `basePath` where `location.host` is used (#3613)
4551
- [compliments] croner library changed filenames used in latest version (#3624)
46-
- [linter] Fix ESLint ignore pattern which caused that default modules not to be linted. (#3632).
52+
- [linter] Fix ESLint ignore pattern which caused that default modules not to be linted (#3632)
53+
- [calendar] - update to resolve issues #3098 #3144 #3351 #3422 #3443 #3467 #3537 related to timezone changes
54+
- [calendar] - fixes #3267 (styles array), also fixes event with both exdate AND recurrence(and testcase)
55+
- [calendar] - fix showEndsOnlyWithDuration not working, #3598, applies ONLY to full day events
56+
- [calendar] - fix showEnd for Full Day events #3602
57+
- [tests] Suppress "module is not defined" in e2e tests
4758

4859
## [2.29.0] - 2024-10-01
4960

Collaboration.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Collaboration
2+
13
This document describes how collaborators of this repository should work together.
24

35
## Pull Requests

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
![MagicMirror²: The open source modular smart mirror platform. ](.github/header.png)
1+
# ![MagicMirror²: The open source modular smart mirror platform.](.github/header.png)
22

33
<p style="text-align: center">
44
<a href="https://choosealicense.com/licenses/mit">
5-
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License">
6-
</a>
7-
<img src="https://img.shields.io/github/actions/workflow/status/magicmirrororg/magicmirror/automated-tests.yaml" alt="GitHub Actions">
8-
<img src="https://img.shields.io/github/check-runs/magicmirrororg/magicmirror/master" alt="Build Status">
9-
<a href="https://github.com/MagicMirrorOrg/MagicMirror">
10-
<img src="https://img.shields.io/github/stars/magicmirrororg/magicmirror?style=social">
11-
</a>
5+
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License">
6+
</a>
7+
<img src="https://img.shields.io/github/actions/workflow/status/magicmirrororg/magicmirror/automated-tests.yaml" alt="GitHub Actions">
8+
<img src="https://img.shields.io/github/check-runs/magicmirrororg/magicmirror/master" alt="Build Status">
9+
<a href="https://github.com/MagicMirrorOrg/MagicMirror">
10+
<img src="https://img.shields.io/github/stars/magicmirrororg/magicmirror?style=social" alt="GitHub Stars">
11+
</a>
1212
</p>
1313

1414
**MagicMirror²** is an open source modular smart mirror platform. With a growing list of installable modules, the **MagicMirror²** allows you to convert your hallway or bathroom mirror into your personal assistant. **MagicMirror²** is built by the creator of [the original MagicMirror](https://michaelteeuw.nl/tagged/magicmirror) with the incredible help of a [growing community of contributors](https://github.com/MagicMirrorOrg/MagicMirror/graphs/contributors).
@@ -24,7 +24,7 @@ For the full documentation including **[installation instructions](https://docs.
2424
- Website: [https://magicmirror.builders](https://magicmirror.builders)
2525
- Documentation: [https://docs.magicmirror.builders](https://docs.magicmirror.builders)
2626
- Forum: [https://forum.magicmirror.builders](https://forum.magicmirror.builders)
27-
- Technical discussions: https://forum.magicmirror.builders/category/11/core-system
27+
- Technical discussions: <https://forum.magicmirror.builders/category/11/core-system>
2828
- Discord: [https://discord.gg/J5BAtvx](https://discord.gg/J5BAtvx)
2929
- Blog: [https://michaelteeuw.nl/tagged/magicmirror](https://michaelteeuw.nl/tagged/magicmirror)
3030
- Donations: [https://magicmirror.builders/#donate](https://magicmirror.builders/#donate)
@@ -49,5 +49,5 @@ If we receive enough donations we might even be able to free up some working hou
4949
To donate, please follow [this](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=G5D8E9MR5DTD2&source=url) link.
5050

5151
<p style="text-align: center">
52-
<a href="https://forum.magicmirror.builders/topic/728/magicmirror-is-voted-number-1-in-the-magpi-top-50"><img src="https://magicmirror.builders/img/magpi-best-watermark-custom.png" width="150" alt="MagPi Top 50"></a>
52+
<a href="https://forum.magicmirror.builders/topic/728/magicmirror-is-voted-number-1-in-the-magpi-top-50"><img src="https://magicmirror.builders/img/magpi-best-watermark-custom.png" width="150" alt="MagPi Top 50"></a>
5353
</p>

cspell.config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@
198198
"tada",
199199
"taglist",
200200
"Teeuw",
201+
"TESTMODE",
201202
"thomasrockhu",
202203
"tomzt",
203204
"ukmetoffice",

modules/default/calendar/calendar.js

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,17 @@ Module.register("calendar", {
168168

169169
this.selfUpdate();
170170
},
171+
notificationReceived (notification, payload, sender) {
171172

172-
// Override socket notification handler.
173-
socketNotificationReceived (notification, payload) {
174173
if (notification === "FETCH_CALENDAR") {
175-
this.sendSocketNotification(notification, { url: payload.url, id: this.identifier });
174+
if (this.hasCalendarURL(payload.url)) {
175+
this.sendSocketNotification(notification, { url: payload.url, id: this.identifier });
176+
}
176177
}
178+
},
179+
180+
// Override socket notification handler.
181+
socketNotificationReceived (notification, payload) {
177182

178183
if (this.identifier !== payload.id) {
179184
return;
@@ -417,18 +422,26 @@ Module.register("calendar", {
417422
timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").format(this.config.dateFormat));
418423
// Add end time if showEnd
419424
if (this.config.showEnd) {
420-
if (this.config.showEndsOnlyWithDuration && event.startDate === event.endDate) {
421-
// no duration here, don't display end
422-
} else {
425+
// and has a duation
426+
if (event.startDate !== event.endDate) {
423427
timeWrapper.innerHTML += "-";
424428
timeWrapper.innerHTML += CalendarUtils.capFirst(moment(event.endDate, "x").format(this.config.dateEndFormat));
425429
}
426430
}
431+
427432
// For full day events we use the fullDayEventDateFormat
428433
if (event.fullDayEvent) {
429434
//subtract one second so that fullDayEvents end at 23:59:59, and not at 0:00:00 one the next day
430435
event.endDate -= ONE_SECOND;
431436
timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").format(this.config.fullDayEventDateFormat));
437+
// only show end if requested and allowed and the dates are different
438+
if (this.config.showEnd && !this.config.showEndsOnlyWithDuration && moment(event.startDate, "x").format("YYYYMMDD") !== moment(event.endDate, "x").format("YYYYMMDD")) {
439+
timeWrapper.innerHTML += "-";
440+
timeWrapper.innerHTML += CalendarUtils.capFirst(moment(event.endDate, "x").format(this.config.fullDayEventDateFormat));
441+
} else
442+
if ((moment(event.startDate, "x").format("YYYYMMDD") !== moment(event.endDate, "x").format("YYYYMMDD")) && (moment(event.startDate, "x") < moment(now, "x"))) {
443+
timeWrapper.innerHTML = CalendarUtils.capFirst(moment(now, "x").format(this.config.fullDayEventDateFormat));
444+
}
432445
} else if (this.config.getRelative > 0 && event.startDate < now) {
433446
// Ongoing and getRelative is set
434447
timeWrapper.innerHTML = CalendarUtils.capFirst(
@@ -460,16 +473,18 @@ Module.register("calendar", {
460473
if (event.startDate >= now || (event.fullDayEvent && this.eventEndingWithinNextFullTimeUnit(event, ONE_DAY))) {
461474
// Use relative time
462475
if (!this.config.hideTime && !event.fullDayEvent) {
463-
timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").calendar(null, { sameElse: this.config.dateFormat }));
476+
Log.debug("event not hidden and not fullday");
477+
timeWrapper.innerHTML = `${CalendarUtils.capFirst(moment(event.startDate, "x").calendar(null, { sameElse: this.config.dateFormat }))}`;
464478
} else {
465-
timeWrapper.innerHTML = CalendarUtils.capFirst(
479+
Log.debug("event full day or hidden");
480+
timeWrapper.innerHTML = `${CalendarUtils.capFirst(
466481
moment(event.startDate, "x").calendar(null, {
467482
sameDay: this.config.showTimeToday ? "LT" : `[${this.translate("TODAY")}]`,
468483
nextDay: `[${this.translate("TOMORROW")}]`,
469484
nextWeek: "dddd",
470485
sameElse: event.fullDayEvent ? this.config.fullDayEventDateFormat : this.config.dateFormat
471486
})
472-
);
487+
)}`;
473488
}
474489
if (event.fullDayEvent) {
475490
// Full days events within the next two days
@@ -488,9 +503,11 @@ Module.register("calendar", {
488503
timeWrapper.innerHTML = CalendarUtils.capFirst(this.translate("DAYAFTERTOMORROW"));
489504
}
490505
}
506+
Log.info("event fullday");
491507
} else if (event.startDate - now < this.config.getRelative * ONE_HOUR) {
508+
Log.info("not full day but within getrelative size");
492509
// If event is within getRelative hours, display 'in xxx' time format or moment.fromNow()
493-
timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").fromNow());
510+
timeWrapper.innerHTML = `${CalendarUtils.capFirst(moment(event.startDate, "x").fromNow())}`;
494511
}
495512
} else {
496513
// Ongoing event
@@ -603,6 +620,7 @@ Module.register("calendar", {
603620
const calendar = this.calendarData[calendarUrl];
604621
let remainingEntries = this.maximumEntriesForUrl(calendarUrl);
605622
let maxPastDaysCompare = now - this.maximumPastDaysForUrl(calendarUrl) * ONE_DAY;
623+
let by_url_calevents = [];
606624
for (const e in calendar) {
607625
const event = JSON.parse(JSON.stringify(calendar[e])); // clone object
608626

@@ -620,9 +638,6 @@ Module.register("calendar", {
620638
if (this.config.hideDuplicates && this.listContainsEvent(events, event)) {
621639
continue;
622640
}
623-
if (--remainingEntries < 0) {
624-
break;
625-
}
626641
}
627642

628643
event.url = calendarUrl;
@@ -667,15 +682,21 @@ Module.register("calendar", {
667682

668683
for (let splitEvent of splitEvents) {
669684
if (splitEvent.endDate > now && splitEvent.endDate <= future) {
670-
events.push(splitEvent);
685+
by_url_calevents.push(splitEvent);
671686
}
672687
}
673688
} else {
674-
events.push(event);
689+
by_url_calevents.push(event);
675690
}
676691
}
692+
by_url_calevents.sort(function (a, b) {
693+
return a.startDate - b.startDate;
694+
});
695+
Log.debug(`pushing ${by_url_calevents.length} events to total with room for ${remainingEntries}`);
696+
events = events.concat(by_url_calevents.slice(0, remainingEntries));
697+
Log.debug(`events for calendar=${events.length}`);
677698
}
678-
699+
Log.info(`sorting events count=${events.length}`);
679700
events.sort(function (a, b) {
680701
return a.startDate - b.startDate;
681702
});
@@ -715,7 +736,7 @@ Module.register("calendar", {
715736
}
716737
events = newEvents;
717738
}
718-
739+
Log.info(`slicing events total maxcount=${this.config.maximumEntries}`);
719740
return events.slice(0, this.config.maximumEntries);
720741
},
721742

modules/default/calendar/calendarfetcher.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn
5656

5757
try {
5858
data = ical.parseICS(responseData);
59-
Log.debug(`parsed data=${JSON.stringify(data)}`);
59+
Log.debug(`parsed data=${JSON.stringify(data, null, 2)}`);
6060
events = CalendarFetcherUtils.filterEvents(data, {
6161
excludedEvents,
6262
includePastEvents,

0 commit comments

Comments
 (0)