html5 media
This commit is contained in:
parent
ccd1830da9
commit
d8a1f2b85e
10 changed files with 142 additions and 17 deletions
|
@ -0,0 +1,7 @@
|
|||
<mat-card class="callInfo" appearance="outlined">
|
||||
<div class="inc-heading">
|
||||
<div class="field field-label">Time</div>
|
||||
<div class="field field-data">{{ call.call_date }}</div>
|
||||
</div>
|
||||
<audio controls [src]="call.audioURL! | safe: 'resourceUrl'"></audio>
|
||||
</mat-card>
|
|
@ -0,0 +1,22 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CallInfoComponent } from './call-info.component';
|
||||
|
||||
describe('CallInfoComponent', () => {
|
||||
let component: CallInfoComponent;
|
||||
let fixture: ComponentFixture<CallInfoComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [CallInfoComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(CallInfoComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
import { Component, Input } from '@angular/core';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { CallRecord } from '../../calls';
|
||||
import { Share } from '../../shares';
|
||||
import { SafePipe } from '../calls.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-call-info',
|
||||
imports: [MatCardModule, SafePipe],
|
||||
templateUrl: './call-info.component.html',
|
||||
styleUrl: './call-info.component.scss',
|
||||
})
|
||||
export class CallInfoComponent {
|
||||
@Input() share!: Share;
|
||||
call!: CallRecord;
|
||||
|
||||
ngOnInit() {
|
||||
this.call = this.share.sharedItem as CallRecord;
|
||||
}
|
||||
}
|
|
@ -6,6 +6,14 @@ import { environment } from '.././../environments/environment';
|
|||
import { TalkgroupService } from '../talkgroups/talkgroups.service';
|
||||
import { Talkgroup } from '../talkgroup';
|
||||
import { Share } from '../shares';
|
||||
import {
|
||||
DomSanitizer,
|
||||
SafeHtml,
|
||||
SafeResourceUrl,
|
||||
SafeScript,
|
||||
SafeStyle,
|
||||
SafeUrl,
|
||||
} from '@angular/platform-browser';
|
||||
|
||||
@Pipe({
|
||||
name: 'grabDate',
|
||||
|
@ -43,7 +51,11 @@ export class TimePipe implements PipeTransform {
|
|||
export class TalkgroupPipe implements PipeTransform {
|
||||
constructor(private tgService: TalkgroupService) {}
|
||||
|
||||
transform(call: CallRecord, field: string, share: Share|null = null): Observable<string> {
|
||||
transform(
|
||||
call: CallRecord,
|
||||
field: string,
|
||||
share: Share | null = null,
|
||||
): Observable<string> {
|
||||
return this.tgService.getTalkgroup(call.system_id, call.tgid).pipe(
|
||||
map((tg: Talkgroup) => {
|
||||
switch (field) {
|
||||
|
@ -82,6 +94,50 @@ export class FixedPointPipe implements PipeTransform {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize HTML
|
||||
*/
|
||||
@Pipe({
|
||||
name: 'safe',
|
||||
})
|
||||
export class SafePipe implements PipeTransform {
|
||||
/**
|
||||
* Pipe Constructor
|
||||
*
|
||||
* @param _sanitizer: DomSanitezer
|
||||
*/
|
||||
// tslint:disable-next-line
|
||||
constructor(protected _sanitizer: DomSanitizer) {}
|
||||
|
||||
/**
|
||||
* Transform
|
||||
*
|
||||
* @param value: string
|
||||
* @param type: string
|
||||
*/
|
||||
transform(
|
||||
value: string,
|
||||
type: string,
|
||||
): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {
|
||||
switch (type) {
|
||||
case 'html':
|
||||
return this._sanitizer.bypassSecurityTrustHtml(value);
|
||||
case 'style':
|
||||
return this._sanitizer.bypassSecurityTrustStyle(value);
|
||||
case 'script':
|
||||
return this._sanitizer.bypassSecurityTrustScript(value);
|
||||
case 'url':
|
||||
return this._sanitizer.bypassSecurityTrustUrl(value);
|
||||
case 'resourceUrl':
|
||||
let res = this._sanitizer.bypassSecurityTrustResourceUrl(value);
|
||||
console.log(res);
|
||||
return res;
|
||||
default:
|
||||
return this._sanitizer.bypassSecurityTrustHtml(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Pipe({
|
||||
name: 'audioDownloadURL',
|
||||
standalone: true,
|
||||
|
|
|
@ -76,13 +76,13 @@
|
|||
<ng-container matColumnDef="system">
|
||||
<th mat-header-cell *matHeaderCellDef>System</th>
|
||||
<td mat-cell *matCellDef="let call">
|
||||
{{ call | talkgroup: "system":incident | async }}
|
||||
{{ call | talkgroup: "system" : share | async }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="group">
|
||||
<th mat-header-cell *matHeaderCellDef>Group</th>
|
||||
<td mat-cell *matCellDef="let call">
|
||||
{{ call | talkgroup: "group":incident | async }}
|
||||
{{ call | talkgroup: "group" : share | async }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="talkgroup">
|
||||
|
|
|
@ -154,7 +154,7 @@ export class IncidentEditDialogComponent {
|
|||
export class IncidentComponent {
|
||||
incPrime = new Subject<IncidentRecord>();
|
||||
inc$!: Observable<IncidentRecord>;
|
||||
@Input() incident?: Share;
|
||||
@Input() share?: Share;
|
||||
subscriptions: Subscription = new Subscription();
|
||||
dialog = inject(MatDialog);
|
||||
incID!: string;
|
||||
|
@ -187,11 +187,11 @@ export class IncidentComponent {
|
|||
this.incID = this.route.snapshot.paramMap.get('id')!;
|
||||
incOb = this.incSvc.getIncident(this.incID);
|
||||
} else {
|
||||
if (!this.incident) {
|
||||
if (!this.share) {
|
||||
return;
|
||||
}
|
||||
this.incID = (this.incident.sharedItem as IncidentRecord).id;
|
||||
incOb = new BehaviorSubject(this.incident.sharedItem as IncidentRecord);
|
||||
this.incID = (this.share.sharedItem as IncidentRecord).id;
|
||||
incOb = new BehaviorSubject(this.share.sharedItem as IncidentRecord);
|
||||
}
|
||||
this.inc$ = merge(incOb, this.incPrime).pipe(
|
||||
tap((inc) => {
|
||||
|
|
|
@ -1,9 +1,17 @@
|
|||
@let sh = share | async;
|
||||
@if (sh == null) {
|
||||
<h1 class="error">Share invalid!</h1>
|
||||
} @else if (sh.type == "incident") {
|
||||
<app-incident [incident]="sh"></app-incident>
|
||||
} @else if (sh.type == "call") {
|
||||
} @else {
|
||||
<h1 class="error">Share type {{ sh.type }} unknown</h1>
|
||||
@switch (sh?.type) {
|
||||
@case ("incident") {
|
||||
<app-incident [share]="sh!"></app-incident>
|
||||
}
|
||||
@case ("call") {
|
||||
<app-call-info [share]="sh!" player="true"></app-call-info>
|
||||
}
|
||||
@case (null) {
|
||||
<div class="spinner">
|
||||
<mat-spinner></mat-spinner>
|
||||
</div>
|
||||
}
|
||||
@default {
|
||||
<h1 class="error">Share type {{ sh?.type }} unknown</h1>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,16 +5,23 @@ import { ActivatedRoute } from '@angular/router';
|
|||
import { Observable, Subscription, switchMap } from 'rxjs';
|
||||
import { IncidentComponent } from '../incidents/incident/incident.component';
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { CallInfoComponent } from '../calls/call-info/call-info.component';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
|
||||
@Component({
|
||||
selector: 'app-share',
|
||||
imports: [AsyncPipe, IncidentComponent],
|
||||
imports: [
|
||||
AsyncPipe,
|
||||
IncidentComponent,
|
||||
CallInfoComponent,
|
||||
MatProgressSpinnerModule,
|
||||
],
|
||||
templateUrl: './share.component.html',
|
||||
styleUrl: './share.component.scss',
|
||||
})
|
||||
export class ShareComponent {
|
||||
shareID!: string;
|
||||
share!: Observable<Share | null>;
|
||||
share!: Observable<Share>;
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private shareSvc: ShareService,
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
switchMap,
|
||||
} from 'rxjs';
|
||||
import { Talkgroup, TalkgroupUpdate, TGID } from '../talkgroup';
|
||||
import { Share } from '../shares';
|
||||
|
||||
export interface Pagination {
|
||||
page: number;
|
||||
|
@ -54,7 +55,11 @@ export class TalkgroupService {
|
|||
return this.http.get<Talkgroup[]>('/api/talkgroup/');
|
||||
}
|
||||
|
||||
getTalkgroup(sys: number, tg: number): Observable<Talkgroup> {
|
||||
getTalkgroup(
|
||||
sys: number,
|
||||
tg: number,
|
||||
share: Share | null = null,
|
||||
): Observable<Talkgroup> {
|
||||
const key = this.tgKey(sys, tg);
|
||||
if (!this._getTalkgroup.get(key)) {
|
||||
let rs = new ReplaySubject<Talkgroup>();
|
||||
|
|
Loading…
Add table
Reference in a new issue