diff --git a/client/imports/app/radio/radio-control/radio-control.component.html b/client/imports/app/radio/radio-control/radio-control.component.html index 52b2bff..86b2795 100644 --- a/client/imports/app/radio/radio-control/radio-control.component.html +++ b/client/imports/app/radio/radio-control/radio-control.component.html @@ -24,7 +24,9 @@ -
+ diff --git a/client/imports/app/radio/radio-control/radio-control.component.ts b/client/imports/app/radio/radio-control/radio-control.component.ts index 268de5e..26031ec 100644 --- a/client/imports/app/radio/radio-control/radio-control.component.ts +++ b/client/imports/app/radio/radio-control/radio-control.component.ts @@ -13,6 +13,7 @@ import { AppRadioService } from '../radio.service'; }) export class AppRadioControlComponent implements OnDestroy, OnInit { liveFeed: boolean = this.appRadioService.live; + paused = false; systemHold = false; talkgroupHold = false; @@ -40,6 +41,10 @@ export class AppRadioControlComponent implements OnDestroy, OnInit { this.appRadioService.holdTalkgroup(); } + pause(): void { + this.appRadioService.pause(); + } + replayLast(): void { this.appRadioService.replay(); } @@ -60,6 +65,12 @@ export class AppRadioControlComponent implements OnDestroy, OnInit { this.appRadioService.liveFeed(); } + private _handlePauseEvent(event: RadioEvent): void { + if ('pause' in event) { + this.paused = event.pause; + } + } + private _handleRadioEvent(event: RadioEvent): void { if ('hold' in event) { switch (event.hold) { @@ -83,7 +94,10 @@ export class AppRadioControlComponent implements OnDestroy, OnInit { private _subscribe(): void { this._subscriptions.push( - this.appRadioService.event.subscribe((event: RadioEvent) => this._handleRadioEvent(event)), + this.appRadioService.event.subscribe((event: RadioEvent) => { + this._handlePauseEvent(event); + this._handleRadioEvent(event); + }), ); } diff --git a/client/imports/app/radio/radio-led/radio-led.component.html b/client/imports/app/radio/radio-led/radio-led.component.html index 88bf19a..7b23034 100644 --- a/client/imports/app/radio/radio-led/radio-led.component.html +++ b/client/imports/app/radio/radio-led/radio-led.component.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/client/imports/app/radio/radio-led/radio-led.component.scss b/client/imports/app/radio/radio-led/radio-led.component.scss index 7f84773..8ee05d6 100644 --- a/client/imports/app/radio/radio-led/radio-led.component.scss +++ b/client/imports/app/radio/radio-led/radio-led.component.scss @@ -22,5 +22,16 @@ $color-on: rgb(100, 230, 50); background: $color-on; box-shadow: 0 0 6px 3px $color-on; } + + &.paused { + animation: blink 2s step-end infinite; + } + } +} + +@keyframes blink { + 50% { + background: $color-off; + box-shadow: none; } } \ No newline at end of file diff --git a/client/imports/app/radio/radio-led/radio-led.component.ts b/client/imports/app/radio/radio-led/radio-led.component.ts index f78a8a8..266eb17 100644 --- a/client/imports/app/radio/radio-led/radio-led.component.ts +++ b/client/imports/app/radio/radio-led/radio-led.component.ts @@ -12,6 +12,7 @@ import { AppRadioService } from '../radio.service'; templateUrl: './radio-led.component.html', }) export class AppRadioLedComponent implements OnDestroy, OnInit { + paused = false; rx = false; private _subcriptions: Subscription[] = []; @@ -32,8 +33,17 @@ export class AppRadioLedComponent implements OnDestroy, OnInit { } } + private _handlePauseEvent(event: RadioEvent): void { + if ('pause' in event) { + this.paused = event.pause; + } + } + private _subscribe(): void { - this._subcriptions.push(this.appRadioService.event.subscribe((event: RadioEvent) => this._handleCallEvent(event))); + this._subcriptions.push(this.appRadioService.event.subscribe((event: RadioEvent) => { + this._handleCallEvent(event); + this._handlePauseEvent(event); + })); } private _unsubscribe(subscriptions: Subscription[] = this._subcriptions): void { diff --git a/client/imports/app/radio/radio.service.ts b/client/imports/app/radio/radio.service.ts index f66d9a5..b96d396 100644 --- a/client/imports/app/radio/radio.service.ts +++ b/client/imports/app/radio/radio.service.ts @@ -38,6 +38,8 @@ export class AppRadioService implements OnDestroy { talkgroup: null, }; + private _paused = false; + private _subscriptions: { liveFeed: Subscription[]; systems: Subscription[]; @@ -169,6 +171,26 @@ export class AppRadioService implements OnDestroy { } } + pause(): void { + this._configureAudio(); + + this._paused = !this._paused; + + this._emitPauseEvent(); + + if (this._paused) { + this._audio.pause(); + + } else { + if (this._call.current) { + this._audio.play(); + + } else { + this.skip(); + } + } + } + play(call?: RadioCall): void { this._configureAudio(); @@ -187,7 +209,7 @@ export class AppRadioService implements OnDestroy { } } - } else if (!this._call.current && this._call.queue.length) { + } else if (!this._call.current && this._call.queue.length && !this._paused) { this._call.current = this._call.queue.shift(); this._audio.src = this._call.current.audio; @@ -209,10 +231,12 @@ export class AppRadioService implements OnDestroy { } replay(): void { - const call = this._call.current || this._call.previous; + if (!this._paused) { + const call = this._call.current || this._call.previous; - if (call) { - this.play(call); + if (call) { + this.play(call); + } } } @@ -230,11 +254,7 @@ export class AppRadioService implements OnDestroy { if (nodelay) { this.play(); } else { - setTimeout(() => { - if (this._call.queue.length) { - this.play(); - } - }, 1000); + setTimeout(() => this.play(), 1000); } } @@ -319,7 +339,7 @@ export class AppRadioService implements OnDestroy { }; const stopHandler = () => { - if (this._call.current && playing) { + if (this._call.current && playing && !this._paused) { playing = false; if (watchdog) { @@ -366,6 +386,10 @@ export class AppRadioService implements OnDestroy { this.event.emit({ live: this.live }); } + private _emitPauseEvent(): void { + this.event.emit({ pause: this._paused }); + } + private _emitQueueEvent(): void { this.event.emit({ queue: this._call.queue.length }); } diff --git a/client/imports/app/radio/radio.ts b/client/imports/app/radio/radio.ts index 17e3056..e96f9d0 100644 --- a/client/imports/app/radio/radio.ts +++ b/client/imports/app/radio/radio.ts @@ -30,6 +30,7 @@ export interface RadioEvent { call?: RadioCall | null; hold?: '-sys' | '+sys' | '-tg' | '+tg'; live?: boolean; + pause?: boolean; queue?: number; search?: null; select?: null; diff --git a/docs/images/rdio_scanner_main.png b/docs/images/rdio_scanner_main.png index ac72f62..9c109dc 100644 Binary files a/docs/images/rdio_scanner_main.png and b/docs/images/rdio_scanner_main.png differ diff --git a/docs/images/rdio_scanner_search.png b/docs/images/rdio_scanner_search.png index f1cfc97..0915ff4 100644 Binary files a/docs/images/rdio_scanner_search.png and b/docs/images/rdio_scanner_search.png differ diff --git a/docs/images/rdio_scanner_select.png b/docs/images/rdio_scanner_select.png index 2874182..fb9fd2c 100644 Binary files a/docs/images/rdio_scanner_select.png and b/docs/images/rdio_scanner_select.png differ diff --git a/package-lock.json b/package-lock.json index 54e233c..a3ca94c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3,9 +3,9 @@ "lockfileVersion": 1, "dependencies": { "@angular/animations": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-8.1.0.tgz", - "integrity": "sha512-v1paXrWQGsD+E4QBpwNUZ8dPj8hEn0b2kDVzYX6l/e9flUX6W2BWYx+BRuC4QBnNtTV9jiGsHT8FmQq/WztgWw==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-8.1.1.tgz", + "integrity": "sha512-9P9Yyf2/IUMs0MR4CfthBaMdizbTh8dDSLJHhMw1PjxPQ3c6mn74uY46NyxcJnCxII9oA2pnnV/O+10JFUFKMw==", "requires": { "tslib": "^1.9.0" } @@ -20,25 +20,25 @@ } }, "@angular/common": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-8.1.0.tgz", - "integrity": "sha512-m5oEBPSy5nE+4SZTu3XchJhKT/u73NnJIS3+41xRsF5aX/1p8uNHkhJR7kcJmlVa7BZNr4byl8bGsYjX0CCpVg==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-8.1.1.tgz", + "integrity": "sha512-kgLtexfPhAyNFlwJHKBkpwKyt/19pfULIJWJpUahFqXdYE3LkRNMJQqgfz7DCNpAQxG7B6u4ocq1j2Hx206kxw==", "requires": { "tslib": "^1.9.0" } }, "@angular/compiler": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-8.1.0.tgz", - "integrity": "sha512-+o4jR7WfqR39zgGk7gwpxZfd2hS3X2qgr17mUCeqQkKj0gh+GYWj7OlSuYXG63OS9S4iLsKQiVUYYgqdNSK5mg==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-8.1.1.tgz", + "integrity": "sha512-wz8Mc45EGax5RKRYYqgXI8lr1d0w+f9BDbHui7b3hQtKM5Mj1QxLXiSOYX0dt3lG4VzrxpO0Xku5tS3D4T1xxQ==", "requires": { "tslib": "^1.9.0" } }, "@angular/compiler-cli": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-8.1.0.tgz", - "integrity": "sha512-WqEWjUTkvkp4rYDwYKo9XVXK1sbUHihwiZDOZrBEiGdw08TvZ+3qZs/mnYwRUYCzoN99RVG5rxJDg8Sf2VTY+w==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-8.1.1.tgz", + "integrity": "sha512-nGN+AqNgi4qsh+4c2Tmtg7/v/mG62sDkjPttra1pUPI6cJS9Y4bA+PBEIW1UsR5OcD85qvNK4vliw2YdLtaeuw==", "dev": true, "requires": { "canonical-path": "1.0.0", @@ -55,17 +55,17 @@ } }, "@angular/core": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-8.1.0.tgz", - "integrity": "sha512-GviWJjOu6LJMYNbukdSK35VaXvSrp5LTNd0FbXoBQF+mhVVV/8cG4hTKKjxG1xwWXI5E1t5U4aUKXrKUNJ1sQg==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-8.1.1.tgz", + "integrity": "sha512-B6x8IZeu0Qm2H13leEcNzsx0pGKHMvowziurvDnm7W97MaVrYrgbelNsnly4wNX91FzdBtSVXqbe3jijAD9kjA==", "requires": { "tslib": "^1.9.0" } }, "@angular/forms": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-8.1.0.tgz", - "integrity": "sha512-T9BOveIHZp2/jNB1BnyIZiu+a5Vmn+Z3k95mveP5K3hhMO7dNAKI7X0WaSwe9CW+xxME9Zpc4CpsfnPEhDuY3A==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-8.1.1.tgz", + "integrity": "sha512-jz05UIiIY2Zz/nEveL4Pm9mVCAd5O6JwVDWTHKQ64nKYIN9Nepzgb0ASeOBEZA4qP82KTGJtUm2AN4L7fXN6Pw==", "requires": { "tslib": "^1.9.0" } @@ -79,25 +79,25 @@ } }, "@angular/platform-browser": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-8.1.0.tgz", - "integrity": "sha512-qH6bH6DSRGvgx5iD7BbufsdeMxhh7lL1zN47LkrLGa8hojF+yxwtdE+go+WJ160ArACyX/FrPmPDSWT20YilUQ==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-8.1.1.tgz", + "integrity": "sha512-uP9UIhi9NYTEbfvNj4misBspXkItFopA2pRk083AhHEhOKs79WvMI15w5H5ziIFeH+4UiCvyKrSnPfcjP+Yrvg==", "requires": { "tslib": "^1.9.0" } }, "@angular/platform-browser-dynamic": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-8.1.0.tgz", - "integrity": "sha512-By9I9hXqg538UzhlYDrF1dW7cDaF2JPjoFCE9jZZQxVRhOdjVoYVuIxIa5qPuGWfmMITO2G9rfMMrDiRHMyEDg==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-8.1.1.tgz", + "integrity": "sha512-yUazvP4IBNgXjbzo+NKmu7lVYrrplAN3HSkgYszXwd9uvWLtk1CtXER5hSJE5ZE3Lawoh7PU5hOfMYbqtdAbwg==", "requires": { "tslib": "^1.9.0" } }, "@angular/router": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-8.1.0.tgz", - "integrity": "sha512-LeJOmiFdsXVf0KlN/jzA5NgWY1V4Ty5TDcfNd01s/ckZlzZd+p5hFhRFc75qwENTb8UwClTLsYQLmvmphnB4dA==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-8.1.1.tgz", + "integrity": "sha512-UTL/TjokRUd3hdePBrj1ITmBGq+EcVNz3D18lFi96461ZLQeXSbbf3vjQfL6SE53E4+hfKKR7/tOqQOgb5br7A==", "requires": { "tslib": "^1.9.0" } @@ -123,9 +123,9 @@ } }, "@babel/runtime": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.2.tgz", - "integrity": "sha512-9M29wrrP7//JBGX70+IrDuD1w4iOYhUGpJNMQJVNAXue+cFeFlMTqBECouIziXPUphlgrfjcfiEpGX4t0WGK4g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.4.tgz", + "integrity": "sha512-Na84uwyImZZc3FKf4aUF1tysApzwf3p2yuFBIyBfbzT5glzKTdvYI4KVW4kcgjrzoGUjC7w3YyCHcJKaRxsr2Q==", "requires": { "regenerator-runtime": "^0.13.2" } @@ -160,9 +160,9 @@ } }, "@types/node": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.1.tgz", - "integrity": "sha512-rp7La3m845mSESCgsJePNL/JQyhkOJA6G4vcwvVgkDAwHhGdq5GCumxmPjEk1MZf+8p5ZQAUE7tqgQRQTXN7uQ==", + "version": "12.6.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.2.tgz", + "integrity": "sha512-gojym4tX0FWeV2gsW4Xmzo5wxGjXGm550oVUII7f7G5o4BV6c7DBdiG1RRQd+y1bvqRyYtPfMK85UM95vsapqQ==", "dev": true }, "@types/prop-types": { diff --git a/package.json b/package.json index 41faabb..3fac3f2 100644 --- a/package.json +++ b/package.json @@ -5,17 +5,17 @@ "start:prod": "AOT=1 ROLLUP=1 meteor --production --settings private/settings.json" }, "dependencies": { - "@angular/animations": "^8.1.0", + "@angular/animations": "^8.1.1", "@angular/cdk": "^8.0.2", - "@angular/common": "8.1.0", - "@angular/compiler": "8.1.0", - "@angular/core": "8.1.0", - "@angular/forms": "8.1.0", + "@angular/common": "8.1.1", + "@angular/compiler": "8.1.1", + "@angular/core": "8.1.1", + "@angular/forms": "8.1.1", "@angular/material": "^8.0.2", - "@angular/platform-browser": "8.1.0", - "@angular/platform-browser-dynamic": "8.1.0", - "@angular/router": "8.1.0", - "@babel/runtime": "7.5.2", + "@angular/platform-browser": "8.1.1", + "@angular/platform-browser-dynamic": "8.1.1", + "@angular/router": "8.1.1", + "@babel/runtime": "7.5.4", "bcrypt": "^3.0.6", "core-js": "3.1.4", "hammerjs": "^2.0.8", @@ -26,10 +26,10 @@ "zone.js": "0.9.1" }, "devDependencies": { - "@angular/compiler-cli": "8.1.0", + "@angular/compiler-cli": "8.1.1", "@types/meteor": "1.4.28", "@types/multiparty": "0.0.32", - "@types/node": "^12.6.1", + "@types/node": "^12.6.2", "codelyzer": "^5.1.0", "tslint": "^5.18.0", "typescript": "3.5.3"