mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-06-28 09:42:21 -04:00
Release 2.28.0 (#3490)
## [2.28.0] - 2024-07-01 Thanks to: @btoconnor, @bugsounet, @JasonStieber, @khassel, @kleinmantara and @WallysWellies. > ⚠️ This release needs nodejs version >= v20 ### Added - [calendar] Added config option "showEndsOnlyWithDuration" for default calendar - [compliments] Added `specialDayUnique` config option, defaults to `false` (#3465) - [weather] Provider weathergov: Use `precipitationLast3Hours` if `precipitationLastHour` is `null` (#3124) ### Removed - [tests] delete node v18 support (#3462) ### Updated - [core] Update dependencies including electron to v31 - [core] use node >= v20 (#3462) - [core] Update `config.js.sample` to use openmeteo as weather provider which needs no api key - [tests] Use latest@version of node for `automated-tests.yaml` (#3483) - [updatenotification] Avoid using pm2 when running in docker container ### Fixed - [core] Fixed crash possibility if `module: <name>` is not defined and on `postion: <positon>` mistake (#3445) - [weather] Fixed precipitationProbability in forecast for provider openmeteo (#3446) - [weather] Fixed type=daily for provider openmeteo having no data when running after 23:00 (#3449) - [weather] Fixed type=daily for provider openmeteo showing nightly icons in forecast when current time is "nightly" (#3458) - [weather] Fixed forecast and hourly weather for provider openmeteo to use real temperatures, not apparent temperatures (#3466) - [tests] Fixed e2e tests running in docker container which needs `address: "0.0.0.0"` (#3479) --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Michael Teeuw <michael@xonaymedia.nl> Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ross Younger <crazyscot@gmail.com> Co-authored-by: Veeck <github@veeck.de> Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr> Co-authored-by: jkriegshauser <joshuakr@nvidia.com> Co-authored-by: illimarkangur <116028111+illimarkangur@users.noreply.github.com> Co-authored-by: sam detweiler <sdetweil@gmail.com> Co-authored-by: vppencilsharpener <tim.pray@gmail.com> Co-authored-by: veeck <michael.veeck@nebenan.de> Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com> Co-authored-by: Brian O'Connor <btoconnor@users.noreply.github.com> Co-authored-by: WallysWellies <59727507+WallysWellies@users.noreply.github.com> Co-authored-by: Jason Stieber <jrstieber@gmail.com>
This commit is contained in:
parent
5ea8a3469a
commit
53fc814ff8
23 changed files with 2330 additions and 1254 deletions
3
.github/workflows/automated-tests.yaml
vendored
3
.github/workflows/automated-tests.yaml
vendored
|
@ -18,7 +18,7 @@ jobs:
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [18.x, 20.x, 21.x]
|
node-version: [20.x, 22.x]
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
@ -26,6 +26,7 @@ jobs:
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
|
check-latest: true
|
||||||
cache: "npm"
|
cache: "npm"
|
||||||
- name: "Install dependencies"
|
- name: "Install dependencies"
|
||||||
run: |
|
run: |
|
||||||
|
|
8
.github/workflows/electronRebuild.yaml
vendored
8
.github/workflows/electronRebuild.yaml
vendored
|
@ -6,9 +6,17 @@ jobs:
|
||||||
rebuild:
|
rebuild:
|
||||||
name: Run electron-rebuild
|
name: Run electron-rebuild
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [20.x, 22.x]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
- name: "Use Node.js ${{ matrix.node-version }}"
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
check-latest: true
|
||||||
- name: Install MagicMirror
|
- name: Install MagicMirror
|
||||||
run: npm run install-mm
|
run: npm run install-mm
|
||||||
- name: Install @electron/rebuild
|
- name: Install @electron/rebuild
|
||||||
|
|
45
CHANGELOG.md
45
CHANGELOG.md
|
@ -5,6 +5,39 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||||
|
|
||||||
❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/#donate) With your help we can continue to improve the MagicMirror².
|
❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/#donate) With your help we can continue to improve the MagicMirror².
|
||||||
|
|
||||||
|
## [2.28.0] - 2024-07-01
|
||||||
|
|
||||||
|
Thanks to: @btoconnor, @bugsounet, @JasonStieber, @khassel, @kleinmantara and @WallysWellies.
|
||||||
|
|
||||||
|
> ⚠️ This release needs nodejs version >= v20
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- [calendar] Added config option "showEndsOnlyWithDuration" for default calendar
|
||||||
|
- [compliments] Added `specialDayUnique` config option, defaults to `false` (#3465)
|
||||||
|
- [weather] Provider weathergov: Use `precipitationLast3Hours` if `precipitationLastHour` is `null` (#3124)
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- [tests] delete node v18 support (#3462)
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- [core] Update dependencies including electron to v31
|
||||||
|
- [core] use node >= v20 (#3462)
|
||||||
|
- [core] Update `config.js.sample` to use openmeteo as weather provider which needs no api key
|
||||||
|
- [tests] Use latest@version of node for `automated-tests.yaml` (#3483)
|
||||||
|
- [updatenotification] Avoid using pm2 when running in docker container
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- [core] Fixed crash possibility if `module: <name>` is not defined and on `postion: <positon>` mistake (#3445)
|
||||||
|
- [weather] Fixed precipitationProbability in forecast for provider openmeteo (#3446)
|
||||||
|
- [weather] Fixed type=daily for provider openmeteo having no data when running after 23:00 (#3449)
|
||||||
|
- [weather] Fixed type=daily for provider openmeteo showing nightly icons in forecast when current time is "nightly" (#3458)
|
||||||
|
- [weather] Fixed forecast and hourly weather for provider openmeteo to use real temperatures, not apparent temperatures (#3466)
|
||||||
|
- [tests] Fixed e2e tests running in docker container which needs `address: "0.0.0.0"` (#3479)
|
||||||
|
|
||||||
## [2.27.0] - 2024-04-01
|
## [2.27.0] - 2024-04-01
|
||||||
|
|
||||||
Thanks to: @bugsounet, @crazyscot, @illimarkangur, @jkriegshauser, @khassel, @KristjanESPERANTO, @Paranoid93, @rejas, @sdetweil and @vppencilsharpener.
|
Thanks to: @bugsounet, @crazyscot, @illimarkangur, @jkriegshauser, @khassel, @KristjanESPERANTO, @Paranoid93, @rejas, @sdetweil and @vppencilsharpener.
|
||||||
|
@ -16,7 +49,7 @@ For more info, please read the following post: [A New Chapter for MagicMirror: T
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Output of system information to the console for troubleshooting (#3328 and #3337), ignore errors under aarch64 (#3349)
|
- Output of system information to the console for troubleshooting (#3328 and #3337), ignore errors under aarch64 (#3349)
|
||||||
- [chore] Add `eslint-plugin-package-json` to lint the `package.json` files (#3368)
|
- [core] Add `eslint-plugin-package-json` to lint the `package.json` files (#3368)
|
||||||
- [weather] `showHumidity` config is now a string describing where to show this element. Supported values: "wind", "temp", "feelslike", "below", "none". (#3330)
|
- [weather] `showHumidity` config is now a string describing where to show this element. Supported values: "wind", "temp", "feelslike", "below", "none". (#3330)
|
||||||
- electron-rebuild test suite for electron and 3rd party modules compatibility (#3392)
|
- electron-rebuild test suite for electron and 3rd party modules compatibility (#3392)
|
||||||
- Create MM² icon and attach it to electron process (#3407)
|
- Create MM² icon and attach it to electron process (#3407)
|
||||||
|
@ -28,8 +61,8 @@ For more info, please read the following post: [A New Chapter for MagicMirror: T
|
||||||
- Use node prefix for build-in modules (#3340)
|
- Use node prefix for build-in modules (#3340)
|
||||||
- Rework logging colors (#3350)
|
- Rework logging colors (#3350)
|
||||||
- Update pm2 to v5.3.1 with no allow-ghsas (#3364)
|
- Update pm2 to v5.3.1 with no allow-ghsas (#3364)
|
||||||
- [chore] Update husky and let lint-staged fix ESLint issues
|
- [core] Update husky and let lint-staged fix ESLint issues
|
||||||
- [chore] Update dependencies including electron to v29 (#3357) and node-ical
|
- [core] Update dependencies including electron to v29 (#3357) and node-ical
|
||||||
- Update translations for estonian (#3371)
|
- Update translations for estonian (#3371)
|
||||||
- Update electron to v29 and update other dependencies
|
- Update electron to v29 and update other dependencies
|
||||||
- [calendar] fullDay events over several days now show the left days from the first day on and 'today' on the last day
|
- [calendar] fullDay events over several days now show the left days from the first day on and 'today' on the last day
|
||||||
|
@ -51,9 +84,9 @@ For more info, please read the following post: [A New Chapter for MagicMirror: T
|
||||||
- added message in case where config.js is missing the module.export line PR #3383
|
- added message in case where config.js is missing the module.export line PR #3383
|
||||||
- Fixed an issue where recurring events could extend past their recurrence end date (#3393)
|
- Fixed an issue where recurring events could extend past their recurrence end date (#3393)
|
||||||
- Don't display any `npm WARN <....>` on install (#3399)
|
- Don't display any `npm WARN <....>` on install (#3399)
|
||||||
- Fixed move suncalc dependency to production from dev, as it is used by clock module
|
- [core] Moved suncalc dependency to production from dev, as it is used by clock module
|
||||||
- [compliments] Fix mirror not responding anymore when no compliments are to be shown (#3385)
|
- [compliments] Fix mirror not responding anymore when no compliments are to be shown (#3385)
|
||||||
- [chore] Fixed mastermerge workflow (#3415)
|
- [core] Fixed mastermerge workflow (#3415)
|
||||||
|
|
||||||
### Deleted
|
### Deleted
|
||||||
|
|
||||||
|
@ -87,7 +120,7 @@ This release also marks the latest release by Michael Teeuw. For more info, plea
|
||||||
- Update electron to v27 and update other dependencies as well as github actions
|
- Update electron to v27 and update other dependencies as well as github actions
|
||||||
- Update newsfeed: Use `html-to-text` instead of regex for transform description
|
- Update newsfeed: Use `html-to-text` instead of regex for transform description
|
||||||
- Review ESLint config (#3269)
|
- Review ESLint config (#3269)
|
||||||
- Updated dependencies
|
- Update dependencies
|
||||||
- Clock module: optionally display current moon phase in addition to rise/set times
|
- Clock module: optionally display current moon phase in addition to rise/set times
|
||||||
- electron is now per default started without gpu, if needed it must be enabled with new env var `ELECTRON_ENABLE_GPU=1` on startup (#3226)
|
- electron is now per default started without gpu, if needed it must be enabled with new env var `ELECTRON_ENABLE_GPU=1` on startup (#3226)
|
||||||
- Replace prettier by stylistic in ESLint config to lint JavaScript (and disable some rules for `config/config.js*` files)
|
- Replace prettier by stylistic in ESLint config to lint JavaScript (and disable some rules for `config/config.js*` files)
|
||||||
|
|
|
@ -67,11 +67,10 @@ let config = {
|
||||||
module: "weather",
|
module: "weather",
|
||||||
position: "top_right",
|
position: "top_right",
|
||||||
config: {
|
config: {
|
||||||
weatherProvider: "openweathermap",
|
weatherProvider: "openmeteo",
|
||||||
type: "current",
|
type: "current",
|
||||||
location: "New York",
|
lat: 40.776676,
|
||||||
locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city
|
lon: -73.971321
|
||||||
apiKey: "YOUR_OPENWEATHER_API_KEY"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -79,11 +78,10 @@ let config = {
|
||||||
position: "top_right",
|
position: "top_right",
|
||||||
header: "Weather Forecast",
|
header: "Weather Forecast",
|
||||||
config: {
|
config: {
|
||||||
weatherProvider: "openweathermap",
|
weatherProvider: "openmeteo",
|
||||||
type: "forecast",
|
type: "forecast",
|
||||||
location: "New York",
|
lat: 40.776676,
|
||||||
locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city
|
lon: -73.971321
|
||||||
apiKey: "YOUR_OPENWEATHER_API_KEY"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
16
fonts/package-lock.json
generated
16
fonts/package-lock.json
generated
|
@ -9,19 +9,19 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/roboto": "^5.0.12",
|
"@fontsource/roboto": "^5.0.13",
|
||||||
"@fontsource/roboto-condensed": "^5.0.15"
|
"@fontsource/roboto-condensed": "^5.0.16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@fontsource/roboto": {
|
"node_modules/@fontsource/roboto": {
|
||||||
"version": "5.0.12",
|
"version": "5.0.13",
|
||||||
"resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.0.12.tgz",
|
"resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.0.13.tgz",
|
||||||
"integrity": "sha512-x0o17jvgoSSbS9OZnUX2+xJmVRvVCfeaYJjkS7w62iN7CuJWtMf5vJj8LqgC7ibqIkitOHVW+XssRjgrcHn62g=="
|
"integrity": "sha512-j61DHjsdUCKMXSdNLTOxcG701FWnF0jcqNNQi2iPCDxU8seN/sMxeh62dC++UiagCWq9ghTypX+Pcy7kX+QOeQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@fontsource/roboto-condensed": {
|
"node_modules/@fontsource/roboto-condensed": {
|
||||||
"version": "5.0.15",
|
"version": "5.0.16",
|
||||||
"resolved": "https://registry.npmjs.org/@fontsource/roboto-condensed/-/roboto-condensed-5.0.15.tgz",
|
"resolved": "https://registry.npmjs.org/@fontsource/roboto-condensed/-/roboto-condensed-5.0.16.tgz",
|
||||||
"integrity": "sha512-0AFvcI/8JQ5+FZE12hdaE1W/1ooJUzd5XP7jD74+SP+PArsswJ+6OV/oKTasgeQeZlvGrcD3chO6yr5K4JGwzA=="
|
"integrity": "sha512-pjO80g5x/hkqzWCIafvkS3JrkBDxSiTjEy4LdqQKJYrmoGx8x2AlhSUMgzIzG/ge4kT98bA7+gmm7yquzrrZ/w=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
"name": "magicmirror-fonts",
|
"name": "magicmirror-fonts",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Package for fonts use by MagicMirror² core.",
|
"description": "Package for fonts use by MagicMirror² core.",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/MagicMirrorOrg/MagicMirror/issues"
|
||||||
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/MagicMirrorOrg/MagicMirror"
|
"url": "https://github.com/MagicMirrorOrg/MagicMirror"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/MagicMirrorOrg/MagicMirror/issues"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/roboto": "^5.0.12",
|
"@fontsource/roboto": "^5.0.13",
|
||||||
"@fontsource/roboto-condensed": "^5.0.15"
|
"@fontsource/roboto-condensed": "^5.0.16"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
js/app.js
15
js/app.js
|
@ -58,6 +58,10 @@ function App () {
|
||||||
async function loadConfig () {
|
async function loadConfig () {
|
||||||
Log.log("Loading config ...");
|
Log.log("Loading config ...");
|
||||||
const defaults = require(`${__dirname}/defaults`);
|
const defaults = require(`${__dirname}/defaults`);
|
||||||
|
if (process.env.JEST_WORKER_ID !== undefined) {
|
||||||
|
// if we are running with jest
|
||||||
|
defaults.address = "0.0.0.0";
|
||||||
|
}
|
||||||
|
|
||||||
// For this check proposed to TestSuite
|
// For this check proposed to TestSuite
|
||||||
// https://forum.magicmirror.builders/topic/1456/test-suite-for-magicmirror/8
|
// https://forum.magicmirror.builders/topic/1456/test-suite-for-magicmirror/8
|
||||||
|
@ -253,8 +257,15 @@ function App () {
|
||||||
|
|
||||||
let modules = [];
|
let modules = [];
|
||||||
for (const module of config.modules) {
|
for (const module of config.modules) {
|
||||||
if (!modules.includes(module.module) && !module.disabled) {
|
if (module.disabled) continue;
|
||||||
modules.push(module.module);
|
if (module.module) {
|
||||||
|
if (Utils.moduleHasValidPosition(module.position) || typeof (module.position) === "undefined") {
|
||||||
|
modules.push(module.module);
|
||||||
|
} else {
|
||||||
|
Log.warn("Invalid module position found for this configuration:", module);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.warn("No module name found for this configuration:", module);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,10 @@ const { Linter } = require("eslint");
|
||||||
|
|
||||||
const linter = new Linter();
|
const linter = new Linter();
|
||||||
|
|
||||||
|
const Ajv = require("ajv");
|
||||||
|
|
||||||
|
const ajv = new Ajv();
|
||||||
|
|
||||||
const rootPath = path.resolve(`${__dirname}/../`);
|
const rootPath = path.resolve(`${__dirname}/../`);
|
||||||
const Log = require(`${rootPath}/js/logger.js`);
|
const Log = require(`${rootPath}/js/logger.js`);
|
||||||
|
|
||||||
|
@ -59,6 +63,68 @@ function checkConfigFile () {
|
||||||
for (const error of errors) {
|
for (const error of errors) {
|
||||||
Log.error(`Line ${error.line} column ${error.column}: ${error.message}`);
|
Log.error(`Line ${error.line} column ${error.column}: ${error.message}`);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.info("Checking modules structure configuration... ");
|
||||||
|
|
||||||
|
// Make Ajv schema confguration of modules config
|
||||||
|
// only scan "module" and "position"
|
||||||
|
const schema = {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
modules: {
|
||||||
|
type: "array",
|
||||||
|
items: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
module: {
|
||||||
|
type: "string"
|
||||||
|
},
|
||||||
|
position: {
|
||||||
|
type: "string",
|
||||||
|
enum: [
|
||||||
|
"top_bar",
|
||||||
|
"top_left",
|
||||||
|
"top_center",
|
||||||
|
"top_right",
|
||||||
|
"upper_third",
|
||||||
|
"middle_center",
|
||||||
|
"lower_third",
|
||||||
|
"bottom_left",
|
||||||
|
"bottom_center",
|
||||||
|
"bottom_right",
|
||||||
|
"bottom_bar",
|
||||||
|
"fullscreen_above",
|
||||||
|
"fullscreen_below"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
required: ["module"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// scan all modules
|
||||||
|
const validate = ajv.compile(schema);
|
||||||
|
const data = require(configFileName);
|
||||||
|
|
||||||
|
const valid = validate(data);
|
||||||
|
if (!valid) {
|
||||||
|
let module = validate.errors[0].instancePath.split("/")[2];
|
||||||
|
let position = validate.errors[0].instancePath.split("/")[3];
|
||||||
|
|
||||||
|
Log.error(colors.red("This module configuration contains errors:"));
|
||||||
|
Log.error(data.modules[module]);
|
||||||
|
if (position) {
|
||||||
|
Log.error(colors.red(`${position}: ${validate.errors[0].message}`));
|
||||||
|
Log.error(validate.errors[0].params.allowedValues);
|
||||||
|
} else {
|
||||||
|
Log.error(colors.red(validate.errors[0].message));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.info(colors.green("Your modules structure configuration doesn't contain errors :)"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,8 @@ const Loader = (function () {
|
||||||
* @returns {object[]} module data as configured in config
|
* @returns {object[]} module data as configured in config
|
||||||
*/
|
*/
|
||||||
const getAllModules = function () {
|
const getAllModules = function () {
|
||||||
return config.modules;
|
const AllModules = config.modules.filter((module) => (module.module !== undefined) && (MM.getAvailableModulePositions.indexOf(module.position) > -1 || typeof (module.position) === "undefined"));
|
||||||
|
return AllModules;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
11
js/main.js
11
js/main.js
|
@ -450,10 +450,10 @@ const MM = (function () {
|
||||||
* an ugly top margin. By using this function, the top bar will be hidden if the
|
* an ugly top margin. By using this function, the top bar will be hidden if the
|
||||||
* update notification is not visible.
|
* update notification is not visible.
|
||||||
*/
|
*/
|
||||||
const updateWrapperStates = function () {
|
const modulePositions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", "bottom_bar", "fullscreen_above", "fullscreen_below"];
|
||||||
const positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", "bottom_bar", "fullscreen_above", "fullscreen_below"];
|
|
||||||
|
|
||||||
positions.forEach(function (position) {
|
const updateWrapperStates = function () {
|
||||||
|
modulePositions.forEach(function (position) {
|
||||||
const wrapper = selectWrapper(position);
|
const wrapper = selectWrapper(position);
|
||||||
const moduleWrappers = wrapper.getElementsByClassName("module");
|
const moduleWrappers = wrapper.getElementsByClassName("module");
|
||||||
|
|
||||||
|
@ -701,7 +701,10 @@ const MM = (function () {
|
||||||
showModule (module, speed, callback, options) {
|
showModule (module, speed, callback, options) {
|
||||||
// do not change module.hidden yet, only if we really show it later
|
// do not change module.hidden yet, only if we really show it later
|
||||||
showModule(module, speed, callback, options);
|
showModule(module, speed, callback, options);
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// return all available module postions.
|
||||||
|
getAvailableModulePositions: modulePositions
|
||||||
};
|
};
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
|
11
js/utils.js
11
js/utils.js
|
@ -25,5 +25,16 @@ module.exports = {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.error(e);
|
Log.error(e);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// return all available module positions
|
||||||
|
getAvailableModulePositions () {
|
||||||
|
return ["top_bar", "top_left", "top_center", "top_right", "upper_third", "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", "bottom_bar", "fullscreen_above", "fullscreen_below"];
|
||||||
|
},
|
||||||
|
|
||||||
|
// return if postion is on modulePositions Array (true/false)
|
||||||
|
moduleHasValidPosition (position) {
|
||||||
|
if (this.getAvailableModulePositions().indexOf(position) === -1) return false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,6 +29,7 @@ Module.register("calendar", {
|
||||||
dateEndFormat: "LT",
|
dateEndFormat: "LT",
|
||||||
fullDayEventDateFormat: "MMM Do",
|
fullDayEventDateFormat: "MMM Do",
|
||||||
showEnd: false,
|
showEnd: false,
|
||||||
|
showEndsOnlyWithDuration: false,
|
||||||
getRelative: 6,
|
getRelative: 6,
|
||||||
hidePrivate: false,
|
hidePrivate: false,
|
||||||
hideOngoing: false,
|
hideOngoing: false,
|
||||||
|
@ -388,7 +389,11 @@ Module.register("calendar", {
|
||||||
|
|
||||||
// Add endDate to dataheaders if showEnd is enabled
|
// Add endDate to dataheaders if showEnd is enabled
|
||||||
if (this.config.showEnd) {
|
if (this.config.showEnd) {
|
||||||
timeWrapper.innerHTML += ` - ${CalendarUtils.capFirst(moment(event.endDate, "x").format("LT"))}`;
|
if (this.config.showEndsOnlyWithDuration && event.startDate === event.endDate) {
|
||||||
|
// no duration here, don't display end
|
||||||
|
} else {
|
||||||
|
timeWrapper.innerHTML += ` - ${CalendarUtils.capFirst(moment(event.endDate, "x").format("LT"))}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eventWrapper.appendChild(timeWrapper);
|
eventWrapper.appendChild(timeWrapper);
|
||||||
|
@ -407,8 +412,12 @@ Module.register("calendar", {
|
||||||
timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").format(this.config.dateFormat));
|
timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").format(this.config.dateFormat));
|
||||||
// Add end time if showEnd
|
// Add end time if showEnd
|
||||||
if (this.config.showEnd) {
|
if (this.config.showEnd) {
|
||||||
timeWrapper.innerHTML += "-";
|
if (this.config.showEndsOnlyWithDuration && event.startDate === event.endDate) {
|
||||||
timeWrapper.innerHTML += CalendarUtils.capFirst(moment(event.endDate, "x").format(this.config.dateEndFormat));
|
// no duration here, don't display end
|
||||||
|
} else {
|
||||||
|
timeWrapper.innerHTML += "-";
|
||||||
|
timeWrapper.innerHTML += CalendarUtils.capFirst(moment(event.endDate, "x").format(this.config.dateEndFormat));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// For full day events we use the fullDayEventDateFormat
|
// For full day events we use the fullDayEventDateFormat
|
||||||
if (event.fullDayEvent) {
|
if (event.fullDayEvent) {
|
||||||
|
|
|
@ -15,7 +15,8 @@ Module.register("compliments", {
|
||||||
morningEndTime: 12,
|
morningEndTime: 12,
|
||||||
afternoonStartTime: 12,
|
afternoonStartTime: 12,
|
||||||
afternoonEndTime: 17,
|
afternoonEndTime: 17,
|
||||||
random: true
|
random: true,
|
||||||
|
specialDayUnique: false
|
||||||
},
|
},
|
||||||
lastIndexUsed: -1,
|
lastIndexUsed: -1,
|
||||||
// Set currentweather from module
|
// Set currentweather from module
|
||||||
|
@ -98,6 +99,10 @@ Module.register("compliments", {
|
||||||
// Add compliments for special days
|
// Add compliments for special days
|
||||||
for (let entry in this.config.compliments) {
|
for (let entry in this.config.compliments) {
|
||||||
if (new RegExp(entry).test(date)) {
|
if (new RegExp(entry).test(date)) {
|
||||||
|
// Only display compliments configured for the day if specialDayUnique is set to true
|
||||||
|
if (this.config.specialDayUnique) {
|
||||||
|
compliments.length = 0;
|
||||||
|
}
|
||||||
Array.prototype.push.apply(compliments, this.config.compliments[entry]);
|
Array.prototype.push.apply(compliments, this.config.compliments[entry]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const Exec = require("node:child_process").exec;
|
const Exec = require("node:child_process").exec;
|
||||||
const Spawn = require("node:child_process").spawn;
|
const Spawn = require("node:child_process").spawn;
|
||||||
const pm2 = require("pm2");
|
const fs = require("node:fs");
|
||||||
|
|
||||||
const Log = require("logger");
|
const Log = require("logger");
|
||||||
|
|
||||||
|
@ -139,6 +139,7 @@ class Updater {
|
||||||
// restart MagicMiror with "pm2"
|
// restart MagicMiror with "pm2"
|
||||||
pm2Restart () {
|
pm2Restart () {
|
||||||
Log.info("updatenotification: PM2 will restarting MagicMirror...");
|
Log.info("updatenotification: PM2 will restarting MagicMirror...");
|
||||||
|
const pm2 = require("pm2");
|
||||||
pm2.restart(this.PM2, (err, proc) => {
|
pm2.restart(this.PM2, (err, proc) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
Log.error("updatenotification:[PM2] restart Error", err);
|
Log.error("updatenotification:[PM2] restart Error", err);
|
||||||
|
@ -160,6 +161,14 @@ class Updater {
|
||||||
check_PM2_Process () {
|
check_PM2_Process () {
|
||||||
Log.info("updatenotification: Checking PM2 using...");
|
Log.info("updatenotification: Checking PM2 using...");
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
|
if (fs.existsSync("/.dockerenv")) {
|
||||||
|
Log.info("updatenotification: Running in docker container, not using PM2 ...");
|
||||||
|
this.usePM2 = false;
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pm2 = require("pm2");
|
||||||
pm2.connect((err) => {
|
pm2.connect((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
Log.error("updatenotification: [PM2]", err);
|
Log.error("updatenotification: [PM2]", err);
|
||||||
|
|
|
@ -398,14 +398,14 @@ WeatherProvider.register("openmeteo", {
|
||||||
currentWeather.windFromDirection = weather.winddirection_10m_dominant;
|
currentWeather.windFromDirection = weather.winddirection_10m_dominant;
|
||||||
currentWeather.sunrise = weather.sunrise;
|
currentWeather.sunrise = weather.sunrise;
|
||||||
currentWeather.sunset = weather.sunset;
|
currentWeather.sunset = weather.sunset;
|
||||||
currentWeather.temperature = parseFloat((weather.apparent_temperature_max + weather.apparent_temperature_min) / 2);
|
currentWeather.temperature = parseFloat((weather.temperature_2m_max + weather.temperature_2m_min) / 2);
|
||||||
currentWeather.minTemperature = parseFloat(weather.apparent_temperature_min);
|
currentWeather.minTemperature = parseFloat(weather.temperature_2m_min);
|
||||||
currentWeather.maxTemperature = parseFloat(weather.apparent_temperature_max);
|
currentWeather.maxTemperature = parseFloat(weather.temperature_2m_max);
|
||||||
currentWeather.weatherType = this.convertWeatherType(weather.weathercode, currentWeather.isDayTime());
|
currentWeather.weatherType = this.convertWeatherType(weather.weathercode, true);
|
||||||
currentWeather.rain = parseFloat(weather.rain_sum);
|
currentWeather.rain = parseFloat(weather.rain_sum);
|
||||||
currentWeather.snow = parseFloat(weather.snowfall_sum * 10);
|
currentWeather.snow = parseFloat(weather.snowfall_sum * 10);
|
||||||
currentWeather.precipitationAmount = parseFloat(weather.precipitation_sum);
|
currentWeather.precipitationAmount = parseFloat(weather.precipitation_sum);
|
||||||
currentWeather.precipitationProbability = parseFloat(weather.precipitation_probability);
|
currentWeather.precipitationProbability = parseFloat(weather.precipitation_hours * 100 / 24);
|
||||||
currentWeather.uv_index = parseFloat(weather.uv_index_max);
|
currentWeather.uv_index = parseFloat(weather.uv_index_max);
|
||||||
|
|
||||||
days.push(currentWeather);
|
days.push(currentWeather);
|
||||||
|
@ -420,7 +420,7 @@ WeatherProvider.register("openmeteo", {
|
||||||
const now = moment();
|
const now = moment();
|
||||||
|
|
||||||
weathers.hourly.forEach((weather, i) => {
|
weathers.hourly.forEach((weather, i) => {
|
||||||
if ((hours.length === 0 && weather.time.hour() <= now.hour()) || hours.length >= this.config.maxEntries) {
|
if ((hours.length === 0 && weather.time <= now) || hours.length >= this.config.maxEntries) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,9 +432,9 @@ WeatherProvider.register("openmeteo", {
|
||||||
currentWeather.windFromDirection = weather.winddirection_10m;
|
currentWeather.windFromDirection = weather.winddirection_10m;
|
||||||
currentWeather.sunrise = weathers.daily[h].sunrise;
|
currentWeather.sunrise = weathers.daily[h].sunrise;
|
||||||
currentWeather.sunset = weathers.daily[h].sunset;
|
currentWeather.sunset = weathers.daily[h].sunset;
|
||||||
currentWeather.temperature = parseFloat(weather.apparent_temperature);
|
currentWeather.temperature = parseFloat(weather.temperature_2m);
|
||||||
currentWeather.minTemperature = parseFloat(weathers.daily[h].apparent_temperature_min);
|
currentWeather.minTemperature = parseFloat(weathers.daily[h].temperature_2m_min);
|
||||||
currentWeather.maxTemperature = parseFloat(weathers.daily[h].apparent_temperature_max);
|
currentWeather.maxTemperature = parseFloat(weathers.daily[h].temperature_2m_max);
|
||||||
currentWeather.weatherType = this.convertWeatherType(weather.weathercode, currentWeather.isDayTime());
|
currentWeather.weatherType = this.convertWeatherType(weather.weathercode, currentWeather.isDayTime());
|
||||||
currentWeather.humidity = parseFloat(weather.relativehumidity_2m);
|
currentWeather.humidity = parseFloat(weather.relativehumidity_2m);
|
||||||
currentWeather.rain = parseFloat(weather.rain);
|
currentWeather.rain = parseFloat(weather.rain);
|
||||||
|
|
|
@ -211,7 +211,7 @@ WeatherProvider.register("weathergov", {
|
||||||
currentWeather.minTemperature = currentWeatherData.minTemperatureLast24Hours.value;
|
currentWeather.minTemperature = currentWeatherData.minTemperatureLast24Hours.value;
|
||||||
currentWeather.maxTemperature = currentWeatherData.maxTemperatureLast24Hours.value;
|
currentWeather.maxTemperature = currentWeatherData.maxTemperatureLast24Hours.value;
|
||||||
currentWeather.humidity = Math.round(currentWeatherData.relativeHumidity.value);
|
currentWeather.humidity = Math.round(currentWeatherData.relativeHumidity.value);
|
||||||
currentWeather.precipitationAmount = currentWeatherData.precipitationLastHour.value;
|
currentWeather.precipitationAmount = currentWeatherData.precipitationLastHour.value ? currentWeatherData.precipitationLastHour.value : currentWeatherData.precipitationLast3Hours.value;
|
||||||
if (currentWeatherData.heatIndex.value !== null) {
|
if (currentWeatherData.heatIndex.value !== null) {
|
||||||
currentWeather.feelsLikeTemp = currentWeatherData.heatIndex.value;
|
currentWeather.feelsLikeTemp = currentWeatherData.heatIndex.value;
|
||||||
} else if (currentWeatherData.windChill.value !== null) {
|
} else if (currentWeatherData.windChill.value !== null) {
|
||||||
|
|
3140
package-lock.json
generated
3140
package-lock.json
generated
File diff suppressed because it is too large
Load diff
105
package.json
105
package.json
|
@ -1,7 +1,27 @@
|
||||||
{
|
{
|
||||||
"name": "magicmirror",
|
"name": "magicmirror",
|
||||||
"version": "2.27.0",
|
"version": "2.28.0",
|
||||||
"description": "The open source modular smart mirror platform.",
|
"description": "The open source modular smart mirror platform.",
|
||||||
|
"keywords": [
|
||||||
|
"magic mirror",
|
||||||
|
"magicmirror",
|
||||||
|
"smart mirror",
|
||||||
|
"mirror UI",
|
||||||
|
"modular"
|
||||||
|
],
|
||||||
|
"homepage": "https://magicmirror.builders",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/MagicMirrorOrg/MagicMirror/issues"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/MagicMirrorOrg/MagicMirror"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"author": "Michael Teeuw",
|
||||||
|
"contributors": [
|
||||||
|
"https://github.com/MagicMirrorOrg/MagicMirror/graphs/contributors"
|
||||||
|
],
|
||||||
"main": "js/electron.js",
|
"main": "js/electron.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "DISPLAY=\"${DISPLAY:=:0}\" ./node_modules/.bin/electron js/electron.js",
|
"start": "DISPLAY=\"${DISPLAY:=:0}\" ./node_modules/.bin/electron js/electron.js",
|
||||||
|
@ -28,50 +48,14 @@
|
||||||
"lint:staged": "lint-staged",
|
"lint:staged": "lint-staged",
|
||||||
"prepare": "[ -f node_modules/.bin/husky ] && husky || echo no husky installed."
|
"prepare": "[ -f node_modules/.bin/husky ] && husky || echo no husky installed."
|
||||||
},
|
},
|
||||||
"repository": {
|
"lint-staged": {
|
||||||
"type": "git",
|
"*": "prettier --write",
|
||||||
"url": "https://github.com/MagicMirrorOrg/MagicMirror"
|
"*.js": "eslint --fix",
|
||||||
},
|
"*.css": "stylelint --fix"
|
||||||
"keywords": [
|
|
||||||
"magic mirror",
|
|
||||||
"magicmirror",
|
|
||||||
"smart mirror",
|
|
||||||
"mirror UI",
|
|
||||||
"modular"
|
|
||||||
],
|
|
||||||
"author": "Michael Teeuw",
|
|
||||||
"contributors": [
|
|
||||||
"https://github.com/MagicMirrorOrg/MagicMirror/graphs/contributors"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/MagicMirrorOrg/MagicMirror/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://magicmirror.builders",
|
|
||||||
"devDependencies": {
|
|
||||||
"@stylistic/eslint-plugin": "^1.7.0",
|
|
||||||
"eslint-plugin-import": "^2.29.1",
|
|
||||||
"eslint-plugin-jest": "^27.9.0",
|
|
||||||
"eslint-plugin-jsdoc": "^48.2.2",
|
|
||||||
"eslint-plugin-package-json": "^0.12.1",
|
|
||||||
"eslint-plugin-unicorn": "^51.0.1",
|
|
||||||
"express-basic-auth": "^1.2.1",
|
|
||||||
"husky": "^9.0.11",
|
|
||||||
"jest": "^29.7.0",
|
|
||||||
"jsdom": "^24.0.0",
|
|
||||||
"lint-staged": "^15.2.2",
|
|
||||||
"playwright": "^1.42.1",
|
|
||||||
"prettier": "^3.2.5",
|
|
||||||
"sinon": "^17.0.1",
|
|
||||||
"stylelint": "^16.3.1",
|
|
||||||
"stylelint-config-standard": "^36.0.0",
|
|
||||||
"stylelint-prettier": "^5.0.0"
|
|
||||||
},
|
|
||||||
"optionalDependencies": {
|
|
||||||
"electron": "^29.1.6"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansis": "^2.3.0",
|
"ajv": "^8.16.0",
|
||||||
|
"ansis": "^3.2.0",
|
||||||
"console-stamp": "^3.1.2",
|
"console-stamp": "^3.1.2",
|
||||||
"envsub": "^4.1.0",
|
"envsub": "^4.1.0",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
|
@ -84,21 +68,38 @@
|
||||||
"module-alias": "^2.2.3",
|
"module-alias": "^2.2.3",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"node-ical": "^0.18.0",
|
"node-ical": "^0.18.0",
|
||||||
"pm2": "^5.3.1",
|
"pm2": "^5.4.1",
|
||||||
"socket.io": "^4.7.5",
|
"socket.io": "^4.7.5",
|
||||||
"suncalc": "^1.9.0",
|
"suncalc": "^1.9.0",
|
||||||
"systeminformation": "^5.22.6"
|
"systeminformation": "^5.22.11"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"devDependencies": {
|
||||||
"*": "prettier --write",
|
"@stylistic/eslint-plugin": "^1.8.1",
|
||||||
"*.js": "eslint --fix",
|
"eslint-plugin-import": "^2.29.1",
|
||||||
"*.css": "stylelint --fix"
|
"eslint-plugin-jest": "^28.6.0",
|
||||||
|
"eslint-plugin-jsdoc": "^48.5.0",
|
||||||
|
"eslint-plugin-package-json": "^0.15.0",
|
||||||
|
"eslint-plugin-unicorn": "^54.0.0",
|
||||||
|
"express-basic-auth": "^1.2.1",
|
||||||
|
"husky": "^9.0.11",
|
||||||
|
"jest": "^29.7.0",
|
||||||
|
"jsdom": "^24.1.0",
|
||||||
|
"lint-staged": "^15.2.7",
|
||||||
|
"playwright": "^1.45.0",
|
||||||
|
"prettier": "^3.3.2",
|
||||||
|
"sinon": "^18.0.0",
|
||||||
|
"stylelint": "^16.6.1",
|
||||||
|
"stylelint-config-standard": "^36.0.1",
|
||||||
|
"stylelint-prettier": "^5.0.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"electron": "^31.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
},
|
},
|
||||||
"_moduleAliases": {
|
"_moduleAliases": {
|
||||||
"node_helper": "js/node_helper.js",
|
"node_helper": "js/node_helper.js",
|
||||||
"logger": "js/logger.js"
|
"logger": "js/logger.js"
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
let config = {
|
||||||
|
modules: [
|
||||||
|
{
|
||||||
|
module: "compliments",
|
||||||
|
position: "middle_center",
|
||||||
|
config: {
|
||||||
|
specialDayUnique: false,
|
||||||
|
compliments: {
|
||||||
|
anytime: [
|
||||||
|
"Typical message 1",
|
||||||
|
"Typical message 2",
|
||||||
|
"Typical message 3"
|
||||||
|
],
|
||||||
|
"....-..-..": ["Special day message"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
/*************** DO NOT EDIT THE LINE BELOW ***************/
|
||||||
|
if (typeof module !== "undefined") { module.exports = config; }
|
|
@ -0,0 +1,22 @@
|
||||||
|
let config = {
|
||||||
|
modules: [
|
||||||
|
{
|
||||||
|
module: "compliments",
|
||||||
|
position: "middle_center",
|
||||||
|
config: {
|
||||||
|
specialDayUnique: true,
|
||||||
|
compliments: {
|
||||||
|
anytime: [
|
||||||
|
"Typical message 1",
|
||||||
|
"Typical message 2",
|
||||||
|
"Typical message 3"
|
||||||
|
],
|
||||||
|
"....-..-..": ["Special day message"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
/*************** DO NOT EDIT THE LINE BELOW ***************/
|
||||||
|
if (typeof module !== "undefined") { module.exports = config; }
|
|
@ -54,4 +54,28 @@ describe("Compliments module", () => {
|
||||||
await expect(doTest(["Remote compliment file works!"])).resolves.toBe(true);
|
await expect(doTest(["Remote compliment file works!"])).resolves.toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Feature specialDayUnique in compliments module", () => {
|
||||||
|
describe("specialDayUnique is false", () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
await helpers.startApplication("tests/configs/modules/compliments/compliments_specialDayUnique_false.js");
|
||||||
|
await helpers.getDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("compliments array can contain all values", async () => {
|
||||||
|
await expect(doTest(["Special day message", "Typical message 1", "Typical message 2", "Typical message 3"])).resolves.toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("specialDayUnique is true", () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
await helpers.startApplication("tests/configs/modules/compliments/compliments_specialDayUnique_true.js");
|
||||||
|
await helpers.getDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("compliments array contains only special value", async () => {
|
||||||
|
await expect(doTest(["Special day message"])).resolves.toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
8
vendor/package-lock.json
generated
vendored
8
vendor/package-lock.json
generated
vendored
|
@ -9,7 +9,7 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^6.5.1",
|
"@fortawesome/fontawesome-free": "^6.5.2",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"moment-timezone": "^0.5.45",
|
"moment-timezone": "^0.5.45",
|
||||||
|
@ -19,9 +19,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@fortawesome/fontawesome-free": {
|
"node_modules/@fortawesome/fontawesome-free": {
|
||||||
"version": "6.5.1",
|
"version": "6.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.2.tgz",
|
||||||
"integrity": "sha512-CNy5vSwN3fsUStPRLX7fUYojyuzoEMSXPl7zSLJ8TgtRfjv24LOnOWKT2zYwaHZCJGkdyRnTmstR0P+Ah503Gw==",
|
"integrity": "sha512-hRILoInAx8GNT5IMkrtIt9blOdrqHOnPBH+k70aWUAqPZPgopb9G5EQJFpaBx/S8zp2fC+mPW349Bziuk1o28Q==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
|
|
8
vendor/package.json
vendored
8
vendor/package.json
vendored
|
@ -2,16 +2,16 @@
|
||||||
"name": "magicmirror-vendors",
|
"name": "magicmirror-vendors",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Package for vendors use by MagicMirror² core.",
|
"description": "Package for vendors use by MagicMirror² core.",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/MagicMirrorOrg/MagicMirror/issues"
|
||||||
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/MagicMirrorOrg/MagicMirror"
|
"url": "https://github.com/MagicMirrorOrg/MagicMirror"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/MagicMirrorOrg/MagicMirror/issues"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^6.5.1",
|
"@fortawesome/fontawesome-free": "^6.5.2",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"moment-timezone": "^0.5.45",
|
"moment-timezone": "^0.5.45",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue