diff --git a/CHANGELOG.md b/CHANGELOG.md index 64099cff..8981569a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,20 +1,23 @@ # Changelog -## 1.0.1 [UNRELEASED] +## 1.0.1 ### Added - `bridge.client.openExternalUrl()` for opening URLs with the default browser - A link to the OSC reference within settings - A new play mode for groups, Random, which will trigger a random child on play - A counter showing selected items in the footer - A shortcut for aborting an item silently (Shift + F1) +- References and triggers can now target the main client's selection ### Changed - Added 'Stop' as an option when setting default on end actions in settings - Electron now bypasses proxies on requests to localhost +- Update dependencies ### Fixed - Added a check for undefined items in item.change in the type plugin - Regular Electron accelerators now work even though a widget isn't focused (CMD+Q e.t.c.) - Icons for rundown items became misaligned when the items grew in height - An issue causing deleted items not to be removed from the selection +- An issue where caspar template data wouldn't completely overwrite old data ## 1.0.0 ### Added diff --git a/api/node/client.js b/api/node/client.js index 7597ba7c..bfce2730 100644 --- a/api/node/client.js +++ b/api/node/client.js @@ -107,7 +107,7 @@ class Client { * Get the current selection * of a connection by its id * @param { String } connectionId - * @returns { Promise. } + * @returns { Promise. } */ async getSelection (connectionId) { if (!connectionId) { @@ -115,6 +115,20 @@ class Client { } return (await this.#props.State.get(`_connections.${connectionId}.selection`)) || [] } + + /** + * Get the current selection + * by the main client + * @returns { Promise. } + */ + async getMainClientSelection () { + const main = await this.getConnectionsByRole(this.ROLES.main) + if (main.length === 0) { + return + } + const selection = await this.getSelection(main[0]?.id) + return selection + } } DIController.main.register('Client', Client, [ diff --git a/lib/api/SItems.js b/lib/api/SItems.js index 42b55d98..d234014c 100644 --- a/lib/api/SItems.js +++ b/lib/api/SItems.js @@ -13,6 +13,7 @@ const itemHelpers = require('../../shared/items') class SItems extends DIBase { #playHistory = new PlayHistory() #stopHistory = new PlayHistory() + #abortHistory = new PlayHistory() constructor (...args) { super(...args) @@ -111,6 +112,15 @@ class SItems extends DIBase { abortItem (item) { this.#validateItemObject(item) + if (this.#isLoopPreventionEnabled && this.#abortHistory.record(item.id)) { + this.props.SMessages.createWarningMessage({ + text: `Detected abort loop, Bridge prevented the item with id '${item.id}' from being repeatedly aborted`, + ttl: 30000, + dismissable: true + }) + return + } + this.props.SCommands.executeCommand('scheduler.abort', undefined, `play:${item.id}`) this.props.SCommands.executeCommand('scheduler.abort', undefined, `end:${item.id}`) diff --git a/package-lock.json b/package-lock.json index cd0862d2..eb0ae5be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "bridge", - "version": "1.0.0", + "version": "1.0.1", "lockfileVersion": 3, "requires": true, "packages": { @@ -60,13 +60,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -126,14 +126,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", - "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.3", - "@babel/types": "^7.28.2", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -284,29 +284,29 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -399,9 +399,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -448,13 +448,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.4" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -1236,16 +1236,16 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", - "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "version": "7.29.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz", + "integrity": "sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.29.0" }, "engines": { "node": ">=6.9.0" @@ -1913,33 +1913,33 @@ } }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", - "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.4", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", "debug": "^4.3.1" }, "engines": { @@ -1947,14 +1947,14 @@ } }, "node_modules/@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -5140,9 +5140,9 @@ } }, "node_modules/cacache/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "license": "MIT", "dependencies": { @@ -7405,9 +7405,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", "funding": [ { "type": "github", @@ -8547,9 +8547,9 @@ } }, "node_modules/ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", "dev": true, "license": "MIT", "engines": { @@ -11030,9 +11030,9 @@ } }, "node_modules/nodemon/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "license": "MIT", "dependencies": { @@ -14818,9 +14818,9 @@ } }, "node_modules/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", + "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", "license": "MIT", "engines": { "node": ">=10.0.0" diff --git a/package.json b/package.json index 9438204b..d9c8e3da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bridge", - "version": "1.0.0", + "version": "1.0.1", "description": "", "main": "index.js", "scripts": { diff --git a/plugins/agent/package-lock.json b/plugins/agent/package-lock.json index b41486ef..3ae80a89 100644 --- a/plugins/agent/package-lock.json +++ b/plugins/agent/package-lock.json @@ -1002,9 +1002,9 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz", - "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==", + "version": "7.29.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz", + "integrity": "sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==", "dev": true, "license": "MIT", "dependencies": { @@ -2971,12 +2971,12 @@ } }, "node_modules/express-rate-limit": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", - "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.2.tgz", + "integrity": "sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==", "license": "MIT", "dependencies": { - "ip-address": "10.1.0" + "ip-address": "^10.2.0" }, "engines": { "node": ">= 16" @@ -3020,9 +3020,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", "funding": [ { "type": "github", @@ -3225,9 +3225,9 @@ } }, "node_modules/hono": { - "version": "4.12.14", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.14.tgz", - "integrity": "sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w==", + "version": "4.12.21", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.21.tgz", + "integrity": "sha512-uV63apnb0kyPtAUwoWgaGh9HyIFcv8lgmzPZSiTBQAFOFGIzka5EZ1dZocmGnn0XdX0+XTqJ6Tqv7selMuGLRQ==", "license": "MIT", "engines": { "node": ">=16.9.0" @@ -3319,9 +3319,9 @@ } }, "node_modules/ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", "license": "MIT", "engines": { "node": ">= 12" diff --git a/plugins/caspar/app/views/InspectorTemplate.jsx b/plugins/caspar/app/views/InspectorTemplate.jsx index f09699f4..23d605ec 100644 --- a/plugins/caspar/app/views/InspectorTemplate.jsx +++ b/plugins/caspar/app/views/InspectorTemplate.jsx @@ -58,7 +58,7 @@ export const InspectorTemplate = () => { handleNewValue({ data: { caspar: { - data: JSON.parse(newValue) + data: { $replace: JSON.parse(newValue) } } } }) @@ -76,6 +76,8 @@ export const InspectorTemplate = () => { setUnsavedValue(newValue) } + console.log('Rendering', value) + return ( <>
diff --git a/plugins/caspar/package-lock.json b/plugins/caspar/package-lock.json index b206250c..0d3efc45 100644 --- a/plugins/caspar/package-lock.json +++ b/plugins/caspar/package-lock.json @@ -616,9 +616,9 @@ "peer": true }, "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", "dev": true, "funding": [ { diff --git a/plugins/inspector/app/components/Form/index.jsx b/plugins/inspector/app/components/Form/index.jsx index c9d04abb..61c1a0f8 100644 --- a/plugins/inspector/app/components/Form/index.jsx +++ b/plugins/inspector/app/components/Form/index.jsx @@ -263,6 +263,26 @@ export function Form () { return localValue } + /** + * Check if a dependency is met + * @param { string } dep + * @returns { boolean } + *//** + * Check if a dependency matches a specified value + * @param { [string, any] } dep + * @returns { boolean } + * + * @example + * ['key', 'foo'] -> True if item.data.key === 'foo' + */ + function checkDependency (dep) { + if (Array.isArray(dep)) { + const [key, val] = dep + return getValue(key) === val + } + return !!getValue(String(dep)) + } + /** * Render a property * @param { TypeProperty } property @@ -272,7 +292,7 @@ export function Form () { */ function renderProperty (property, id) { if ( - (property['ui.dependsOn'] ?? []).some(key => !getValue(key)) + (property['ui.dependsOn'] ?? []).some(dep => !checkDependency(dep)) ) { return null } diff --git a/plugins/rundown/app/components/RundownListItem/index.jsx b/plugins/rundown/app/components/RundownListItem/index.jsx index 8143edf2..94f2dc7f 100644 --- a/plugins/rundown/app/components/RundownListItem/index.jsx +++ b/plugins/rundown/app/components/RundownListItem/index.jsx @@ -201,6 +201,11 @@ export function RundownListItem ({ return } + /** + * @todo + * Insert default values based on + * the type we're converting to + */ await bridge.items.applyItem(item?.id, { type: typeId }, true) diff --git a/plugins/timecode/package-lock.json b/plugins/timecode/package-lock.json index af285bca..751ddf9b 100644 --- a/plugins/timecode/package-lock.json +++ b/plugins/timecode/package-lock.json @@ -93,9 +93,9 @@ } }, "node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "license": "MIT", "dependencies": { @@ -357,9 +357,9 @@ } }, "node_modules/ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", "dev": true, "license": "MIT", "engines": { diff --git a/plugins/types/index.js b/plugins/types/index.js index 1c7ae183..f8e011d5 100644 --- a/plugins/types/index.js +++ b/plugins/types/index.js @@ -57,8 +57,9 @@ const PLAY_HANDLERS = [ */ { predicate: (item, type) => item.type === 'bridge.types.reference' || type.ancestors.includes('bridge.types.reference'), - fn: item => { - if (!item?.data?.targetId) { + fn: async item => { + const targets = await getReferenceTargets(item) + if (!targets) { return } @@ -66,11 +67,21 @@ const PLAY_HANDLERS = [ case types.REFERENCE_ACTION.none: break case types.REFERENCE_ACTION.stop: - bridge.items.stopItem(item?.data?.targetId) + for (const targetId of targets) { + if (targetId === item?.id) { + continue + } + bridge.items.stopItem(targetId) + } break case types.REFERENCE_ACTION.play: default: - bridge.items.playItem(item?.data?.targetId) + for (const targetId of targets) { + if (targetId === item?.id) { + continue + } + bridge.items.playItem(targetId) + } break } } @@ -97,8 +108,9 @@ const STOP_HANDLERS = [ */ { predicate: (item, type) => item.type === 'bridge.types.reference' || type.ancestors.includes('bridge.types.reference'), - fn: item => { - if (!item?.data?.targetId) { + fn: async item => { + const targets = await getReferenceTargets(item) + if (!targets) { return } @@ -106,11 +118,21 @@ const STOP_HANDLERS = [ case types.REFERENCE_ACTION.none: break case types.REFERENCE_ACTION.play: - bridge.items.playItem(item?.data?.targetId) + for (const targetId of targets) { + if (targetId === item?.id) { + continue + } + bridge.items.playItem(targetId) + } break case types.REFERENCE_ACTION.stop: default: - bridge.items.stopItem(item?.data?.targetId) + for (const targetId of targets) { + if (targetId === item?.id) { + continue + } + bridge.items.stopItem(targetId) + } break } } @@ -125,6 +147,14 @@ const ITEM_CHANGE_HANDLERS = [ { predicate: (item, type) => item.type === 'bridge.types.reference' || type?.ancestors?.includes('bridge.types.reference'), fn: async item => { + const isExpectingId = parseInt(item?.data?.targetType) === types.REFERENCE_TARGET_TYPE.itemById + if (!isExpectingId) { + bridge.items.removeIssue(item?.id, 'types.reference-targeting-ancestor') + bridge.items.removeIssue(item?.id, 'types.reference-targeting-itself') + bridge.items.removeIssue(item?.id, 'types.reference-missing-target') + return + } + const hasTarget = item?.data?.targetId && String(item.data.targetId).length === 4 if (hasTarget) { bridge.items.removeIssue(item?.id, 'types.reference-missing-target') @@ -194,15 +224,34 @@ const ABORT_HANDLERS = [ */ { predicate: (item, type) => item.type === 'bridge.types.reference' || type.ancestors.includes('bridge.types.reference'), - fn: item => { - if (!item?.data?.targetId) { + fn: async item => { + const targets = await getReferenceTargets(item) + if (!targets) { return } - bridge.items.abortItem(item.data.targetId) + + for (const targetId of targets) { + bridge.items.abortItem(targetId) + } } } ] +/** + * Get the target(s) for + * the specified reference item + * @param { any } referenceItem + * @returns { Promise. } + */ +async function getReferenceTargets (referenceItem) { + switch (parseInt(referenceItem?.data?.targetType)) { + case types.REFERENCE_TARGET_TYPE.selection: + return bridge.client.getMainClientSelection() + default: + return [referenceItem?.data?.targetId] + } +} + async function initWidget () { const cssPath = `${assets.hash}.${manifest.name}.bundle.css` const jsPath = `${assets.hash}.${manifest.name}.bundle.js` diff --git a/plugins/types/lib/types.js b/plugins/types/lib/types.js index cc835a77..6df214bd 100644 --- a/plugins/types/lib/types.js +++ b/plugins/types/lib/types.js @@ -13,6 +13,12 @@ const REFERENCE_ACTION = { } exports.REFERENCE_ACTION = REFERENCE_ACTION +const REFERENCE_TARGET_TYPE = { + itemById: 0, + selection: 1 +} +exports.REFERENCE_TARGET_TYPE = REFERENCE_TARGET_TYPE + async function init (htmlPath) { bridge.types.registerType({ id: 'bridge.types.reference', @@ -36,18 +42,27 @@ async function init (htmlPath) { default: REFERENCE_ACTION.stop, 'ui.group': 'Reference' }, + targetType: { + name: 'Target type', + type: 'enum', + enum: ['Item by id', 'Selection (main client)'], + default: String(REFERENCE_TARGET_TYPE.itemById), + 'ui.group': 'Reference' + }, targetId: { name: 'Target', type: 'string', 'ui.group': 'Reference', 'ui.readable': true, - 'ui.glyph': '\uE903' + 'ui.glyph': '\uE903', + 'ui.dependsOn': [['targetType', String(REFERENCE_TARGET_TYPE.itemById)]] }, targetButton: { name: '', type: 'string', 'ui.group': 'Reference', - 'ui.uri': `${htmlPath}?path=inspector/reference/button` + 'ui.uri': `${htmlPath}?path=inspector/reference/button`, + 'ui.dependsOn': [['targetType', String(REFERENCE_TARGET_TYPE.itemById)]] } } })