mirror of
https://github.com/chuot/rdio-scanner.git
synced 2026-08-14 08:53:03 -06:00
Version 5.2.4
This commit is contained in:
parent
3edfa3f9ec
commit
fa6d85318a
|
|
@ -22,6 +22,12 @@ _v5.2.3_
|
|||
- Change history columns padding from 1px to 6px on the main screen.
|
||||
- Fix a bug in the admin api where the server crash when saving new config from the admin dashboard.
|
||||
|
||||
_v5.2.4_
|
||||
|
||||
- Updated to Angular 12.2.
|
||||
- New update prompt for clients when server is updated.
|
||||
- Fix unaligned back arrow on the search panel.
|
||||
|
||||
# Version 5.1
|
||||
|
||||
This one is a big one... **Be sure to backup your config.json and your database.sqlite before updating.**
|
||||
|
|
|
|||
|
|
@ -1,36 +1,20 @@
|
|||
{
|
||||
"env": {
|
||||
"commonjs": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"globals": {
|
||||
"Atomics": "readonly",
|
||||
"SharedArrayBuffer": "readonly"
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020,
|
||||
"ecmaVersion": 12,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"max-len": [
|
||||
"error",
|
||||
{
|
||||
"code": 140
|
||||
}
|
||||
],
|
||||
"quotes": [
|
||||
"error",
|
||||
"single"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1535
client/package-lock.json
generated
1535
client/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,26 +1,29 @@
|
|||
{
|
||||
"author": "Chrystian Huot <chrystian.huot@saubeo.solutions>",
|
||||
"dependencies": {
|
||||
"@angular/animations": "^12.1.4",
|
||||
"@angular/cdk": "^12.1.4",
|
||||
"@angular/common": "~12.1.4",
|
||||
"@angular/compiler": "~12.1.4",
|
||||
"@angular/core": "~12.1.4",
|
||||
"@angular/forms": "~12.1.4",
|
||||
"@angular/material": "^12.1.4",
|
||||
"@angular/platform-browser": "~12.1.4",
|
||||
"@angular/platform-browser-dynamic": "~12.1.4",
|
||||
"@angular/router": "^12.1.4",
|
||||
"@angular/service-worker": "^12.1.4",
|
||||
"@angular/animations": "^12.2.0",
|
||||
"@angular/cdk": "^12.2.0",
|
||||
"@angular/common": "~12.2.0",
|
||||
"@angular/compiler": "~12.2.0",
|
||||
"@angular/core": "~12.2.0",
|
||||
"@angular/forms": "~12.2.0",
|
||||
"@angular/material": "^12.2.0",
|
||||
"@angular/platform-browser": "~12.2.0",
|
||||
"@angular/platform-browser-dynamic": "~12.2.0",
|
||||
"@angular/router": "^12.2.0",
|
||||
"@angular/service-worker": "^12.2.0",
|
||||
"rxjs": "~6.5.5",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~12.1.4",
|
||||
"@angular/cli": "^12.1.4",
|
||||
"@angular/compiler-cli": "~12.1.4",
|
||||
"@types/node": "~16.4.10",
|
||||
"@angular-devkit/build-angular": "~12.2.0",
|
||||
"@angular/cli": "^12.2.0",
|
||||
"@angular/compiler-cli": "~12.2.0",
|
||||
"@types/node": "~16.4.13",
|
||||
"@typescript-eslint/eslint-plugin": "^4.29.0",
|
||||
"@typescript-eslint/parser": "^4.29.0",
|
||||
"eslint": "^7.32.0",
|
||||
"ts-node": "~10.1.0",
|
||||
"typescript": "~4.2.4"
|
||||
},
|
||||
|
|
@ -34,5 +37,5 @@
|
|||
"build": "ng build --base-href ./ --configuration production",
|
||||
"start": "ng serve"
|
||||
},
|
||||
"version": "5.2.3"
|
||||
"version": "5.2.4"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ $background-color: rgb(30, 30, 30);
|
|||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
&.search .mat-toolbar > div {
|
||||
&.search .mat-toolbar > div {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import { Component, ElementRef, HostListener, OnDestroy, ViewChild } from '@angular/core';
|
||||
import { MatSidenav } from '@angular/material/sidenav';
|
||||
import { RdioScannerConfig, RdioScannerEvent, RdioScannerLivefeedMode } from './rdio-scanner';
|
||||
import { RdioScannerEvent, RdioScannerLivefeedMode } from './rdio-scanner';
|
||||
import { RdioScannerService } from './rdio-scanner.service';
|
||||
|
||||
@Component({
|
||||
|
|
@ -28,8 +28,6 @@ import { RdioScannerService } from './rdio-scanner.service';
|
|||
templateUrl: './rdio-scanner.component.html',
|
||||
})
|
||||
export class RdioScannerComponent implements OnDestroy {
|
||||
private config: RdioScannerConfig | undefined;
|
||||
|
||||
private eventSubscription = this.rdioScannerService.event.subscribe((event: RdioScannerEvent) => this.eventHandler(event));
|
||||
|
||||
private livefeedMode: RdioScannerLivefeedMode = RdioScannerLivefeedMode.Offline;
|
||||
|
|
@ -108,10 +106,6 @@ export class RdioScannerComponent implements OnDestroy {
|
|||
}
|
||||
|
||||
private eventHandler(event: RdioScannerEvent): void {
|
||||
if ('config' in event) {
|
||||
this.config = event.config;
|
||||
}
|
||||
|
||||
if (event.livefeedMode) {
|
||||
this.livefeedMode = event.livefeedMode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import { DOCUMENT } from '@angular/common';
|
|||
import { EventEmitter, Inject, Injectable, OnDestroy } from '@angular/core';
|
||||
import { interval, Subscription, timer } from 'rxjs';
|
||||
import { takeWhile } from 'rxjs/operators';
|
||||
import { AppUpdateService } from '../../shared/update/update.service';
|
||||
import {
|
||||
RdioScannerAvoidOptions,
|
||||
RdioScannerBeepStyle,
|
||||
|
|
@ -54,7 +55,6 @@ enum WebsocketCommand {
|
|||
LivefeedMap = 'LFM',
|
||||
Max = 'MAX',
|
||||
Pin = 'PIN',
|
||||
Ver = 'VER',
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -97,7 +97,10 @@ export class RdioScannerService implements OnDestroy {
|
|||
|
||||
private websocket: WebSocket | undefined;
|
||||
|
||||
constructor(@Inject(DOCUMENT) private document: Document) {
|
||||
constructor(
|
||||
private appUpdateService: AppUpdateService,
|
||||
@Inject(DOCUMENT) private document: Document,
|
||||
) {
|
||||
this.bootstrapAudio();
|
||||
|
||||
this.restoreLivefeed();
|
||||
|
|
@ -791,7 +794,7 @@ export class RdioScannerService implements OnDestroy {
|
|||
|
||||
break;
|
||||
|
||||
case WebsocketCommand.Config:
|
||||
case WebsocketCommand.Config: {
|
||||
const config = message[1];
|
||||
|
||||
this.config = {
|
||||
|
|
@ -818,6 +821,7 @@ export class RdioScannerService implements OnDestroy {
|
|||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WebsocketCommand.Expired:
|
||||
this.event.emit({ auth: true, expired: true });
|
||||
|
|
@ -915,8 +919,6 @@ export class RdioScannerService implements OnDestroy {
|
|||
|
||||
private rebuildLivefeedMap(): void {
|
||||
const livefeedMap = this.config.systems.reduce((sysMap, sys) => {
|
||||
const tgs = sys.talkgroups.map((tg) => tg.id.toString());
|
||||
|
||||
sysMap[sys.id] = sys.talkgroups.reduce((tgMap, tg) => {
|
||||
const state = this.livefeedMap && this.livefeedMap[sys.id] && this.livefeedMap[sys.id][tg.id];
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|||
import { ExtraOptions, RouterModule, Routes } from '@angular/router';
|
||||
import { AppLocaleModule } from './locale/locale.module';
|
||||
import { AppMaterialModule } from './material/material.module';
|
||||
import { AppUpdateModule } from './update/update.module';
|
||||
|
||||
export interface AppSharedModuleConfig {
|
||||
routerExtraOptions?: ExtraOptions;
|
||||
|
|
@ -33,6 +34,7 @@ export interface AppSharedModuleConfig {
|
|||
exports: [
|
||||
AppLocaleModule,
|
||||
AppMaterialModule,
|
||||
AppUpdateModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
|
|
@ -54,6 +56,7 @@ export class AppSharedModule {
|
|||
ngModule: AppSharedModule,
|
||||
providers: [
|
||||
...AppLocaleModule.forRoot().providers || [],
|
||||
...AppUpdateModule.forRoot().providers || [],
|
||||
...RouterModule.forRoot(config.routerRoutes || [], config.routerExtraOptions || {}).providers || [],
|
||||
],
|
||||
};
|
||||
|
|
|
|||
6
client/src/app/shared/update/update.component.html
Normal file
6
client/src/app/shared/update/update.component.html
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<h1 mat-dialog-title>New version available</h1>
|
||||
<div mat-dialog-content>A new version of this webapp is available. Would you like to reload the page?</div>
|
||||
<div mat-dialog-actions>
|
||||
<button mat-raised-button mat-dialog-close>No</button>
|
||||
<button mat-raised-button color="primary" mat-dialog-close="true">Yes</button>
|
||||
</div>
|
||||
3
client/src/app/shared/update/update.component.scss
Normal file
3
client/src/app/shared/update/update.component.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.mat-dialog-actions {
|
||||
justify-content: space-between;
|
||||
}
|
||||
26
client/src/app/shared/update/update.component.ts
Normal file
26
client/src/app/shared/update/update.component.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2019-2021 Chrystian Huot <chrystian.huot@saubeo.solutions>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
templateUrl: './update.component.html',
|
||||
styleUrls: ['./update.component.scss'],
|
||||
})
|
||||
export class AppUpdateComponent { }
|
||||
44
client/src/app/shared/update/update.module.ts
Normal file
44
client/src/app/shared/update/update.module.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2019-2021 Chrystian Huot <chrystian.huot@saubeo.solutions>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
import { ModuleWithProviders, NgModule } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { ServiceWorkerModule } from '@angular/service-worker';
|
||||
import { AppUpdateComponent } from './update.component';
|
||||
import { AppUpdateService } from './update.service';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppUpdateComponent],
|
||||
imports: [
|
||||
MatButtonModule,
|
||||
MatDialogModule,
|
||||
ServiceWorkerModule,
|
||||
],
|
||||
})
|
||||
export class AppUpdateModule {
|
||||
static forRoot(): ModuleWithProviders<AppUpdateModule> {
|
||||
return {
|
||||
ngModule: AppUpdateModule,
|
||||
providers: [AppUpdateService],
|
||||
};
|
||||
}
|
||||
|
||||
// constructor(appUpdateService: AppUpdateService) { }
|
||||
}
|
||||
47
client/src/app/shared/update/update.service.ts
Normal file
47
client/src/app/shared/update/update.service.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2019-2021 Chrystian Huot <chrystian.huot@saubeo.solutions>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { SwUpdate } from '@angular/service-worker';
|
||||
import { AppUpdateComponent } from './update.component';
|
||||
|
||||
@Injectable()
|
||||
export class AppUpdateService {
|
||||
constructor(
|
||||
private matDialog: MatDialog,
|
||||
private swUpdate: SwUpdate,
|
||||
) {
|
||||
swUpdate.available.subscribe(() => this.prompt());
|
||||
swUpdate.checkForUpdate();
|
||||
setInterval(() => swUpdate.checkForUpdate(), 5 * 60 * 1000);
|
||||
}
|
||||
|
||||
prompt(): void {
|
||||
this.matDialog.open(AppUpdateComponent).afterClosed().subscribe((doUpdate) => {
|
||||
if (doUpdate) {
|
||||
if (this.swUpdate.isEnabled) {
|
||||
this.swUpdate.activateUpdate().then(() => document.location.reload());
|
||||
} else {
|
||||
document.location.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -14,5 +14,5 @@
|
|||
"update": "node update"
|
||||
},
|
||||
"type": "module",
|
||||
"version": "5.2.3"
|
||||
"version": "5.2.4"
|
||||
}
|
||||
|
|
@ -19,6 +19,6 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
export const version = '5.2.3';
|
||||
export const version = '5.2.4';
|
||||
|
||||
export default version;
|
||||
20
server/package-lock.json
generated
20
server/package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "rdio-scanner-server",
|
||||
"version": "5.2.3",
|
||||
"version": "5.2.4",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
@ -835,9 +835,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001248",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001248.tgz",
|
||||
"integrity": "sha512-NwlQbJkxUFJ8nMErnGtT0QTM2TJ33xgz4KXJSMIrjXIbDVdaYueGyjOrLKRtJC+rTiWfi6j5cnZN1NBiSBJGNw==",
|
||||
"version": "1.0.30001249",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001249.tgz",
|
||||
"integrity": "sha512-vcX4U8lwVXPdqzPWi6cAJ3FnQaqXbBqy/GZseKNQzRj37J7qZdGcBtxq/QLFNLLlfsoXLUdHw8Iwenri86Tagw==",
|
||||
"dev": true
|
||||
},
|
||||
"caseless": {
|
||||
|
|
@ -1276,9 +1276,9 @@
|
|||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.3.793",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.793.tgz",
|
||||
"integrity": "sha512-l9NrGV6Mr4ov5mayYPvIWcwklNw5ROmy6rllzz9dCACw9nKE5y+s5uQk+CBJMetxrWZ6QJFsvEfG6WDcH2IGUg==",
|
||||
"version": "1.3.799",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.799.tgz",
|
||||
"integrity": "sha512-V2rbYWdGvSqrg+95KjkVuSi41bGfrhrOzjl1tSi2VLnm0mRe3FsSvhiqidSiSll9WiMhrQAhpDcW/wcqK3c+Yw==",
|
||||
"dev": true
|
||||
},
|
||||
"emoji-regex": {
|
||||
|
|
@ -4382,9 +4382,9 @@
|
|||
}
|
||||
},
|
||||
"webpack": {
|
||||
"version": "5.48.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.48.0.tgz",
|
||||
"integrity": "sha512-CGe+nfbHrYzbk7SKoYITCgN3LRAG0yVddjNUecz9uugo1QtYdiyrVD8nP1PhkNqPfdxC2hknmmKpP355Epyn6A==",
|
||||
"version": "5.49.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.49.0.tgz",
|
||||
"integrity": "sha512-XarsANVf28A7Q3KPxSnX80EkCcuOer5hTOEJWJNvbskOZ+EK3pobHarGHceyUZMxpsTHBHhlV7hiQyLZzGosYw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/eslint-scope": "^3.7.0",
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
"devDependencies": {
|
||||
"eslint": "^7.32.0",
|
||||
"nodemon": "^2.0.12",
|
||||
"webpack": "^5.48.0",
|
||||
"webpack": "^5.49.0",
|
||||
"webpack-cli": "^4.7.2",
|
||||
"webpack-node-externals": "^3.0.0"
|
||||
},
|
||||
|
|
@ -46,5 +46,5 @@
|
|||
"start": "nodemon"
|
||||
},
|
||||
"type": "module",
|
||||
"version": "5.2.3"
|
||||
"version": "5.2.4"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue