From 5b51e0811a0786cb2562e91291f7373235f48f60 Mon Sep 17 00:00:00 2001 From: Chrystian Huot Date: Thu, 13 Aug 2020 10:07:35 -0400 Subject: [PATCH] Version 4.4.1 --- CHANGELOG.md | 8 + client/package-lock.json | 181 +++++++++--------- client/package.json | 26 +-- .../rdio-scanner/rdio-scanner.component.html | 4 +- .../rdio-scanner/rdio-scanner.component.ts | 8 +- .../rdio-scanner/rdio-scanner.service.ts | 2 +- docs/config.md | 53 ++--- package.json | 2 +- server/lib/rdio-scanner/controller.js | 86 +++++++-- server/package-lock.json | 42 ++-- server/package.json | 6 +- 11 files changed, 242 insertions(+), 176 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ee43c5..b130faa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# Version 4.4 + +- Config.systems.talkgroups.patches to group many talkgroups (patches) into one talkgroup.id. +- Config.options now groups allowDownloads, disableAudioConversion, pruneDays, useDimmer, useGroup and useLed options instead of having them spread all over the config file. +- Client will always display talkgroup id on the right side instead of 0 when call is analog. +- Fix annoying bug when next call queued to play is still played even though offline continuous play mode is turned off. +- Talkgroup ID is displayed no matter what and unit ID is displayed only if known. + # Version 4.3 - Add metatags to converted audio files. diff --git a/client/package-lock.json b/client/package-lock.json index 151226b..00e8e22 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,6 +1,6 @@ { "name": "rdio-scanner-client", - "version": "4.3.3", + "version": "4.4.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -137,6 +137,14 @@ "source-map": "0.7.3", "tslib": "2.0.0", "webpack-sources": "1.4.3" + }, + "dependencies": { + "tslib": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==", + "dev": true + } } }, "@angular-devkit/build-webpack": { @@ -226,17 +234,17 @@ } }, "@angular/animations": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-10.0.7.tgz", - "integrity": "sha512-lTF7wuhx16fc3WahmqcYE3Q6sHB5sUQZ6m4dKg38wuf49Hr9x8uQpOMypnOAp9qfKG06ZZ2arRs53JeHpzkMPw==", + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-10.0.9.tgz", + "integrity": "sha512-NcQOlLQNR50qIvEjR/yo28P6Nh0hf9GRuy+4iCxHiRNZyBL8AwX/y+8/NpgSRoL/U+Iq4bXz5DSOkmrtZfFHXg==", "requires": { "tslib": "^2.0.0" } }, "@angular/cdk": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-10.1.1.tgz", - "integrity": "sha512-Gt9TmqSVxPTmuNkApEuvva25U60WW152r9+vL7ViFgG+297RE7tzUU8ffBwMXZMdtXnrhLKqLv6ZaBhihMM2Kw==", + "version": "10.1.3", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-10.1.3.tgz", + "integrity": "sha512-xMV1M41mfuaQod4rtAG/duYiWffGIC2C87E1YuyHTh8SEcHopGVRQd2C8PWH+iwinPbes7AjU1uzCEvmOYikrA==", "requires": { "parse5": "^5.0.0", "tslib": "^2.0.0" @@ -285,25 +293,25 @@ } }, "@angular/common": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-10.0.7.tgz", - "integrity": "sha512-CPjmbjylbMG0eFLWz7TCaxONDcwuldcvEheEwaBGS3RloHVsa+ry/8r6/7YilQkscdNPUazhX8pIzzrxIf9cBQ==", + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-10.0.9.tgz", + "integrity": "sha512-zg1xtTR8LwLXfTcXX0rL30ur1GKaf3Iu8FCQpfh0804Ezn5TeovuGg2zvf/O3igwmYzrym+a0JRMe4TZsAuJxQ==", "requires": { "tslib": "^2.0.0" } }, "@angular/compiler": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-10.0.7.tgz", - "integrity": "sha512-ut4aq7G0OwpRM2jhWjqN7RR02z9ybwFlP8j+2cr+6wwxZLUB+Gwe+O8iuz6h98O7F9yZx8Lbr5bQ07xbiHgdag==", + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-10.0.9.tgz", + "integrity": "sha512-KUIRkOoZ0C7IlJ514ahyA1VDmlLrh9wBF/hm6e7fKMUAzPTwch6WQczjw/Bdt8ArL3ovYasbFungBvJ7apENtw==", "requires": { "tslib": "^2.0.0" } }, "@angular/compiler-cli": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-10.0.7.tgz", - "integrity": "sha512-bfz/18ktAtc6Es7YaH23paT6Sajitt/0VLuUw0lqhmchV+Xa2c3BEYyOX2AGycEX4mNg7XJoZxOUgJs/9/u4wA==", + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-10.0.9.tgz", + "integrity": "sha512-E4WxTYO4zY7ytMna5Y8Yoh58KPJKjDn3tzefLNrBEX3t69XueYmh5JTRHmNOiWcFX2QIbgqzX9mXZ9uPLDslmg==", "dev": true, "requires": { "canonical-path": "1.0.0", @@ -484,9 +492,9 @@ } }, "@angular/core": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-10.0.7.tgz", - "integrity": "sha512-h8R/2TCIFkagrFl6zmPN34gS5ZtQ1soYDI8dDeLj0+oQ+qH8HncoRgzYl+1+agFvUeYQ2pkwc5i635j/LwC++Q==", + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-10.0.9.tgz", + "integrity": "sha512-sRod8RnARYmMy/uBmZyLxt5F3vYIvAkTEv48DFvCKJ6FN7zJPS7C7/dnnDv0JG7hNsX3jVXCsIRWJiCk0ycDGg==", "requires": { "tslib": "^2.0.0" } @@ -500,41 +508,41 @@ } }, "@angular/forms": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-10.0.7.tgz", - "integrity": "sha512-xSGPhidaUWLop3j9zPy4ZeO+/rwnusNWvwrDNey4W68lS068AExRXqf3yTuzobqBGdV2swDJaRabzgD7NS8yag==", + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-10.0.9.tgz", + "integrity": "sha512-t/ZjPFHz5LLj5osvNTkBibcF5Y1XrOwmgX8e6FPl2OTM/NcEyqUPWQmcGhy1Wc7jxP6JVWSWLrqI5QKkATHSBA==", "requires": { "tslib": "^2.0.0" } }, "@angular/material": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-10.1.1.tgz", - "integrity": "sha512-D9VXwW2ieDUvkQD1VVEX6bxIdCaK6uA6jHpMU2ZLTIQ/EzNRDRwmJbr4rqPhxtHmLMXF+66EBXEjgyV7l91h5g==", + "version": "10.1.3", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-10.1.3.tgz", + "integrity": "sha512-6ygbCVcejFydmZUlOcNreiWQTvL4kOrEp/M51DV70hqffTnxajCzaRe2MQhxisENB/bR8mtMvf8YY3Rsys/HCw==", "requires": { "tslib": "^2.0.0" } }, "@angular/platform-browser": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-10.0.7.tgz", - "integrity": "sha512-iACZDApTWTID+Dgpv9ztAlmP4OBIyCnqfmSrVWIpN30O/2pgalYS4hKS+jFXXjqG3IXrG6IpOAbFT9UubOWXKg==", + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-10.0.9.tgz", + "integrity": "sha512-y6d2CLj6ZM0NpJGH5yfNBTVyMiOwUXFfVRw52MWQ4Kt2Auk0EROG6dWAVL0XcE9OGXBI/U/4wemmQ9LQy7wLSA==", "requires": { "tslib": "^2.0.0" } }, "@angular/platform-browser-dynamic": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-10.0.7.tgz", - "integrity": "sha512-ESn1hssKmgFbSSU8tI3KcP6QFEMKaxTvoKElkwULhAnCNkeXAhZaIkTdeqaa/vkO8s9nRbRwqcLuhw/mIQJbpQ==", + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-10.0.9.tgz", + "integrity": "sha512-iRkBAErsYNG5lPglA8bZfsKQTuVBAl6IVc0TNlGNCePQM1blZ0f2BjMoqBWrbTi5xGgGu2cmJcy9M6hob2sgzw==", "requires": { "tslib": "^2.0.0" } }, "@angular/service-worker": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-10.0.7.tgz", - "integrity": "sha512-yUJveLtvVkNmmvDCAkTsem07Ia/BiGan4JFezPa0npU03p1J3yR63j8nFehwilSvNQbBe+wyA/3Y8sKNcj/s3A==", + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-10.0.9.tgz", + "integrity": "sha512-hrngIkRHhMQaJ0D61kkgstLVDjOASy8j0f+z9AHO4GlILeQlCxzHb5gqd5L6zkQ7MMs8BDSP9JBKw+Tonj4e1A==", "requires": { "tslib": "^2.0.0" } @@ -955,9 +963,9 @@ } }, "@babel/parser": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", - "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "version": "7.11.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz", + "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { @@ -1164,9 +1172,9 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.5.tgz", - "integrity": "sha512-6Ycw3hjpQti0qssQcA6AMSFDHeNJ++R6dIMnpRqUjFeBBTmTDPa8zgF90OVfTvAo11mXZTlVUViY1g8ffrURLg==", + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz", + "integrity": "sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" @@ -2415,9 +2423,9 @@ "dev": true }, "aws4": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", - "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz", + "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", "dev": true }, "axobject-query": { @@ -2741,16 +2749,16 @@ } }, "browserify-sign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz", - "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", "dev": true, "requires": { "bn.js": "^5.1.1", "browserify-rsa": "^4.0.1", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", + "elliptic": "^6.5.3", "inherits": "^2.0.4", "parse-asn1": "^5.1.5", "readable-stream": "^3.6.0", @@ -2786,15 +2794,15 @@ } }, "browserslist": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.13.0.tgz", - "integrity": "sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.0.tgz", + "integrity": "sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001093", - "electron-to-chromium": "^1.3.488", - "escalade": "^3.0.1", - "node-releases": "^1.1.58" + "caniuse-lite": "^1.0.30001111", + "electron-to-chromium": "^1.3.523", + "escalade": "^3.0.2", + "node-releases": "^1.1.60" } }, "buffer": { @@ -2943,9 +2951,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001109", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001109.tgz", - "integrity": "sha512-4JIXRodHzdS3HdK8nSgIqXYLExOvG+D2/EenSvcub2Kp3QEADjo2v2oUn5g0n0D+UNwG9BtwKOyGcSq2qvQXvQ==", + "version": "1.0.30001113", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001113.tgz", + "integrity": "sha512-qMvjHiKH21zzM/VDZr6oosO6Ri3U0V2tC015jRXjOecwQCJtsU5zklTNTk31jQbIOP8gha0h1ccM/g0ECP+4BA==", "dev": true }, "canonical-path": { @@ -2978,9 +2986,9 @@ "dev": true }, "chokidar": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.1.tgz", - "integrity": "sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", + "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", "dev": true, "requires": { "anymatch": "~3.1.1", @@ -4294,9 +4302,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.516", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.516.tgz", - "integrity": "sha512-WDM5AAQdOrvLqSX8g3Zd5AujBXfMxf96oeZkff0U2HF5op3tjShE+on2yay3r1UD4M9I3p0iHpAS4+yV8U8A9A==", + "version": "1.3.533", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.533.tgz", + "integrity": "sha512-YqAL+NXOzjBnpY+dcOKDlZybJDCOzgsq4koW3fvyty/ldTmsb4QazZpOWmVvZ2m0t5jbBf7L0lIGU3BUipwG+A==", "dev": true }, "elliptic": { @@ -5049,9 +5057,9 @@ } }, "follow-redirects": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz", - "integrity": "sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==", "dev": true }, "for-in": { @@ -6102,9 +6110,9 @@ "dev": true }, "is-docker": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.0.tgz", - "integrity": "sha512-mB2WygGsSeoXtLKpSYzP6sa0Z9DyU9ZyKlnvuZWxCociaI0qsF8u12sR72DFTX236g1u6oWSWYFuUk09nGQEjg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", + "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", "dev": true }, "is-extendable": { @@ -6192,9 +6200,9 @@ } }, "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", "dev": true, "requires": { "has-symbols": "^1.0.1" @@ -7555,9 +7563,9 @@ } }, "onetime": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.1.tgz", - "integrity": "sha512-ZpZpjcJeugQfWsfyQlshVoowIIQ1qBGSVll4rfDq6JJVO//fesjoX808hXWfBjY+ROZgpKDI5TRSRBSoJiZ8eg==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { "mimic-fn": "^2.1.0" @@ -10812,9 +10820,9 @@ "dev": true }, "tslib": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", - "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz", + "integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==" }, "tslint": { "version": "6.1.3", @@ -11714,15 +11722,6 @@ "ajv-keywords": "^3.1.0" } }, - "serialize-javascript": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", - "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -11739,16 +11738,16 @@ } }, "terser-webpack-plugin": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz", - "integrity": "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", "dev": true, "requires": { "cacache": "^12.0.2", "find-cache-dir": "^2.1.0", "is-wsl": "^1.1.0", "schema-utils": "^1.0.0", - "serialize-javascript": "^3.1.0", + "serialize-javascript": "^4.0.0", "source-map": "^0.6.1", "terser": "^4.1.2", "webpack-sources": "^1.4.0", diff --git a/client/package.json b/client/package.json index fafee1a..b8ca954 100644 --- a/client/package.json +++ b/client/package.json @@ -1,25 +1,25 @@ { "author": "Chrystian Huot ", "dependencies": { - "@angular/animations": "^10.0.7", - "@angular/cdk": "^10.1.1", - "@angular/common": "~10.0.7", - "@angular/compiler": "~10.0.7", - "@angular/core": "~10.0.7", + "@angular/animations": "^10.0.9", + "@angular/cdk": "^10.1.3", + "@angular/common": "~10.0.9", + "@angular/compiler": "~10.0.9", + "@angular/core": "~10.0.9", "@angular/flex-layout": "^10.0.0-beta.32", - "@angular/forms": "~10.0.7", - "@angular/material": "^10.1.1", - "@angular/platform-browser": "~10.0.7", - "@angular/platform-browser-dynamic": "~10.0.7", - "@angular/service-worker": "~10.0.7", + "@angular/forms": "~10.0.9", + "@angular/material": "^10.1.3", + "@angular/platform-browser": "~10.0.9", + "@angular/platform-browser-dynamic": "~10.0.9", + "@angular/service-worker": "~10.0.9", "rxjs": "~6.6.2", - "tslib": "^2.0.0", + "tslib": "^2.0.1", "zone.js": "~0.10.3" }, "devDependencies": { "@angular-devkit/build-angular": "~0.1000.5", "@angular/cli": "^10.0.5", - "@angular/compiler-cli": "~10.0.7", + "@angular/compiler-cli": "~10.0.9", "@types/node": "~14.0.27", "codelyzer": "^6.0.0", "ts-node": "~8.10.2", @@ -33,5 +33,5 @@ "build": "ng build --base-href ./ --prod", "start": "ng serve" }, - "version": "4.3.4" + "version": "4.4.1" } diff --git a/client/src/app/components/rdio-scanner/rdio-scanner.component.html b/client/src/app/components/rdio-scanner/rdio-scanner.component.html index 33c621f..75b3074 100644 --- a/client/src/app/components/rdio-scanner/rdio-scanner.component.html +++ b/client/src/app/components/rdio-scanner/rdio-scanner.component.html @@ -285,8 +285,8 @@
- - UID: {{ callUnit || 0 }} + + UID: {{ callUnit }}
diff --git a/client/src/app/components/rdio-scanner/rdio-scanner.component.ts b/client/src/app/components/rdio-scanner/rdio-scanner.component.ts index bae55d6..1625568 100644 --- a/client/src/app/components/rdio-scanner/rdio-scanner.component.ts +++ b/client/src/app/components/rdio-scanner/rdio-scanner.component.ts @@ -654,7 +654,11 @@ export class AppRdioScannerComponent implements AfterViewInit, OnDestroy { } } - loadAndPlay(nextId); + timer(1000).subscribe(() => { + if (this.liveFeedOffline) { + loadAndPlay(nextId); + } + }); } else { this.stopOfflinePlay(); @@ -836,7 +840,7 @@ export class AppRdioScannerComponent implements AfterViewInit, OnDestroy { } } else { - this.callTalkgroupId = ''; + this.callTalkgroupId = this.call.talkgroup.toString(); this.callUnit = typeof this.call.source === 'number' ? `${this.call.source}` : ''; } diff --git a/client/src/app/components/rdio-scanner/rdio-scanner.service.ts b/client/src/app/components/rdio-scanner/rdio-scanner.service.ts index 1d28f75..6a75267 100644 --- a/client/src/app/components/rdio-scanner/rdio-scanner.service.ts +++ b/client/src/app/components/rdio-scanner/rdio-scanner.service.ts @@ -643,7 +643,7 @@ export class AppRdioScannerService implements OnDestroy { break; case WebSocketCallFlag.Play: - this.play(message[1], { delay: true }); + this.play(message[1]); break; diff --git a/docs/config.md b/docs/config.md index 9b28a48..8ebb180 100644 --- a/docs/config.md +++ b/docs/config.md @@ -38,9 +38,6 @@ This file is at the heart of [Rdio Scanner](https://github.com/chuot/rdio-scanne // See Access control section below for more details "access": null, - // (boolean) Can users download archived calls. Default value is true - "allowDownload": true, - // (multiple types) API keys for upload scripts and downstreamers // Default value is a random generated UUID // See API keys section below for more details @@ -51,36 +48,42 @@ This file is at the heart of [Rdio Scanner](https://github.com/chuot/rdio-scanne // See DirWatch section below for more details "dirWatch": [] - // (boolean) Disable the audio format conversion to m4a/aac - // Default value is false - "disableAudioConversion": false, - // (object[]) Downstream audio files to other Rdio Scanner instances // Default value is an empty array // See Downstreams section below for more details "downstreams": [], - // (number) Clear the database for audio files older than the specified number of days - // Default value is 7 - // Specifying a value of 0 will disable this feature - "pruneDays": 7 + // (object) Options definitions + "options": { + // (boolean) Can users download archived calls. Default value is true + "allowDownload": true, + + // (boolean) Disable the audio format conversion to m4a/aac + // Default value is false + "disableAudioConversion": false, + + // (number) Clear the database for audio files older than the specified number of days + // Default value is 7 + // Specifying a value of 0 will disable this feature + "pruneDays": 7 + + // (boolean) Turn off the screen backlight when it is inactive + // Default value is true + "useDimmer": true + + // (boolean) Also toggle talkgroups based on their group assignment + // Default value is true + // See Systems section below for more details on groups + "useGroup": true + + // (boolean) Show the activity led + // Default value is true + "useLed": true + } // (object[]) Systems definitions // See Systems section below for more details "systems": [] - - // (boolean) Turn off the screen backlight when it is inactive - // Default value is true - "useDimmer": true - - // (boolean) Also toggle talkgroups based on their group assignment - // Default value is true - // See Systems section below for more details on groups - "useGroup": true - - // (boolean) Show the activity led - // Default value is true - "useLed": true }, // Radio Scanner uses sqlite for its default database @@ -472,6 +475,7 @@ systems: { id: number; label: string; name: string; + patches: number[]; tag: string; group?: string; // mandatory if useGroup is true, optional if not led?: 'blue' | 'cyan' | 'green' | 'magenta' | 'red' | 'white' | 'yellow'; @@ -490,6 +494,7 @@ systems: { - **id** - Talkgroup ID. - **label** - Talkgroup label shown on the left side of third row. - **name** - Talkgroup name shown on the fouth row. + - **patches** - Array of talkgroup ID to include in this talkgroup. - **tag** - Talkgroup tag shown on the right side of second row. - **units** - Unit aliases. - **id** - Unit ID. diff --git a/package.json b/package.json index 11ca36f..04d7f20 100644 --- a/package.json +++ b/package.json @@ -11,5 +11,5 @@ "start": "node run", "update": "node update" }, - "version": "4.3.4" + "version": "4.4.1" } diff --git a/server/lib/rdio-scanner/controller.js b/server/lib/rdio-scanner/controller.js index f37a773..8d1b775 100644 --- a/server/lib/rdio-scanner/controller.js +++ b/server/lib/rdio-scanner/controller.js @@ -53,22 +53,56 @@ class Controller extends EventEmitter { this.config.access = this.config.access !== undefined ? this.config.access : null; - this.config.allowDownload = typeof this.config.allowDownload === 'boolean' ? this.config.allowDownload : true; - this.config.apiKeys = this.config.apiKeys !== undefined ? this.config.apiKeys : uuid.v4(); - this.config.disableAudioConversion = typeof this.config.disableAudioConversion === 'boolean' ? this.config.disableAudioConversion : false; + if (this.config.options === null || typeof this.config.options !== 'object') { + this.config.options = {}; + } - this.config.pruneDays = typeof this.config.pruneDays === 'number' ? this.config.pruneDays : 7; + this.config.options.allowDownload = typeof this.config.options.allowDownload === 'boolean' ? this.config.options.allowDownload + : typeof this.config.allowDownload === 'boolean' ? this.config.allowDownload : true; + + if (this.config.allowDownload !== null || this.config.allowDownload !== undefined) { + delete this.config.allowDownload; + } + + this.config.options.disableAudioConversion = typeof this.config.options.disableAudioConversion === 'boolean' ? this.config.options.disableAudioConversion + : typeof this.config.disableAudioConversion === 'boolean' ? this.config.disableAudioConversion : false; + + if (this.config.disableAudioConversion !== null || this.config.disableAudioConversion !== undefined) { + delete this.config.disableAudioConversion; + } + + this.config.options.pruneDays = typeof this.config.options.pruneDays === 'number' ? this.config.options.pruneDays + : typeof this.config.pruneDays === 'number' ? this.config.pruneDays : 7; + + if (this.config.pruneDays !== null || this.config.pruneDays !== undefined) { + delete this.config.pruneDays; + } + + this.config.options.useDimmer = typeof this.config.options.useDimmer === 'boolean' ? this.config.options.useDimmer + : typeof this.config.useDimmer === 'boolean' ? this.config.useDimmer : true; + + if (this.config.useDimmer !== null || this.config.useDimmer !== undefined) { + delete this.config.useDimmer; + } + + this.config.options.useGroup = typeof this.config.options.useGroup === 'boolean' ? this.config.options.useGroup + : typeof this.config.useGroup === 'boolean' ? this.config.useGroup : true; + + if (this.config.useGroup !== null || this.config.useGroup !== undefined) { + delete this.config.useGroup; + } + + this.config.options.useLed = typeof this.config.options.useLed === 'boolean' ? this.config.options.useLed + : typeof this.config.useLed === 'boolean' ? this.config.useLed : true; + + if (this.config.useLed !== null || this.config.useLed !== undefined) { + delete this.config.useLed; + } this.config.systems = Array.isArray(this.config.systems) ? this.config.systems : systemsDefault; - this.config.useDimmer = typeof this.config.useDimmer === 'boolean' ? this.config.useDimmer : true; - - this.config.useGroup = typeof this.config.useGroup === 'boolean' ? this.config.useGroup : true; - - this.config.useLed = typeof this.config.useLed === 'boolean' ? this.config.useLed : true; - this.config.systems.forEach((system) => { if (system === null || typeof system !== 'object') { console.error(`Config: Unknown system definition: ${JSON.stringify(system)}`); @@ -115,6 +149,10 @@ class Controller extends EventEmitter { console.error(`Config: System ${system.id}, talkgroup ${talkgroup.id}, name not a string: ${JSON.stringify(talkgroup.name)}`); } + if (talkgroup.patches !== undefined && !Array.isArray(talkgroup.patches)) { + console.error(`Config: System ${system.id}, talkgroup ${talkgroup.id}, patches not an array: ${JSON.stringify(talkgroup.patches)}`); + } + if (typeof talkgroup.tag !== 'string' || !talkgroup.tag.length) { console.error(`Config: System ${system.id}, talkgroup ${talkgroup.id}, tag not a string: ${JSON.stringify(talkgroup.tag)}`); } @@ -149,14 +187,14 @@ class Controller extends EventEmitter { console.warn('ffmpeg is missing, no audio conversion possible.'); } - if (this.config.pruneDays > 0) { + if (this.config.options.pruneDays > 0) { this.pruneInterval = setInterval(() => { const now = new Date(); this.models.call.destroy({ where: { dateTime: { - [Op.lt]: new Date(now.getFullYear(), now.getMonth(), now.getDate() - this.config.pruneDays), + [Op.lt]: new Date(now.getFullYear(), now.getMonth(), now.getDate() - this.config.options.pruneDays), }, }, }); @@ -337,16 +375,16 @@ class Controller extends EventEmitter { async getConfig(scope) { return Object.assign({}, this.getOptions(), { - allowDownload: this.config.allowDownload, + allowDownload: this.config.options.allowDownload, systems: await this.getSystems(scope), }); } getOptions() { return { - useDimmer: this.config.useDimmer, - useGroup: this.config.useGroup, - useLed: this.config.useLed, + useDimmer: this.config.options.useDimmer, + useGroup: this.config.options.useGroup, + useLed: this.config.options.useLed, }; } @@ -450,9 +488,21 @@ class Controller extends EventEmitter { } async importCall(call = {}) { - const system = this.config.systems.find((sys) => sys.id == call.system); + const system = this.config.systems.find((sys) => sys.id === call.system); - const talkgroup = Array.isArray(system && system.talkgroups) ? system.talkgroups.find((tg) => tg.id == call.talkgroup) : null; + const talkgroup = Array.isArray(system && system.talkgroups) ? system.talkgroups.find((tg) => { + if (tg.id === call.talkgroup) { + return true; + + } else if (Array.isArray(tg.patches) && tg.patches.includes(call.talkgroup)) { + call.talkgroup = tg.id; + + return true; + + } else { + return false; + } + }) : null; if (!system || !talkgroup) { console.log(`NewCall: system=${call.system || 'unknown'} talkgroup=${call.talkgroup || 'unknown'} file=${call.audioName} No matching system/talkgroup`); diff --git a/server/package-lock.json b/server/package-lock.json index 621ae86..e3b96ce 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -1,6 +1,6 @@ { "name": "rdio-scanner-server", - "version": "4.3.3", + "version": "4.4.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -574,9 +574,9 @@ "optional": true }, "aws4": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", - "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz", + "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", "optional": true }, "balanced-match": { @@ -796,16 +796,16 @@ } }, "browserify-sign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz", - "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", "dev": true, "requires": { "bn.js": "^5.1.1", "browserify-rsa": "^4.0.1", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", - "elliptic": "^6.5.2", + "elliptic": "^6.5.3", "inherits": "^2.0.4", "parse-asn1": "^5.1.5", "readable-stream": "^3.6.0", @@ -1030,9 +1030,9 @@ } }, "chokidar": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.1.tgz", - "integrity": "sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", + "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", @@ -5133,9 +5133,9 @@ "integrity": "sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg==" }, "serialize-javascript": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", - "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -5740,16 +5740,16 @@ } }, "terser-webpack-plugin": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz", - "integrity": "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", "dev": true, "requires": { "cacache": "^12.0.2", "find-cache-dir": "^2.1.0", "is-wsl": "^1.1.0", "schema-utils": "^1.0.0", - "serialize-javascript": "^3.1.0", + "serialize-javascript": "^4.0.0", "source-map": "^0.6.1", "terser": "^4.1.2", "webpack-sources": "^1.4.0", @@ -6596,9 +6596,9 @@ } }, "webpack-node-externals": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-2.5.0.tgz", - "integrity": "sha512-g7/Z7Q/gsP8GkJkKZuJggn6RSb5PvxW1YD5vvmRZIxaSxAzkqjfL5n9CslVmNYlSqBVCyiqFgOqVS2IOObCSRg==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-2.5.1.tgz", + "integrity": "sha512-RWxKGibUU5kuJT6JDYmXGa3QsZskqIaiBvZ2wBxHlJzWVJPOyBMnroXf23uxEHnj1rYS8jNdyUfrNAXJ2bANNw==", "dev": true }, "webpack-sources": { diff --git a/server/package.json b/server/package.json index 6cd07ec..b239276 100644 --- a/server/package.json +++ b/server/package.json @@ -1,7 +1,7 @@ { "author": "Chrystian Huot ", "dependencies": { - "chokidar": "^3.4.1", + "chokidar": "^3.4.2", "cors": "^2.8.5", "dotenv": "^8.2.0", "express": "^4.17.1", @@ -23,7 +23,7 @@ "eslint": "^7.6.0", "webpack": "^4.44.1", "webpack-cli": "^3.3.12", - "webpack-node-externals": "^2.5.0" + "webpack-node-externals": "^2.5.1" }, "license": "LICENSE", "main": "index.js", @@ -39,5 +39,5 @@ "build": "webpack", "start": "nodemon" }, - "version": "4.3.4" + "version": "4.4.1" }