Browse Source

dialog camera

pull/14/head
PhamY0601 1 year ago
parent
commit
282475038c
9 changed files with 142 additions and 39 deletions
  1. +11
    -0
      src/app/modules/overview/camera-dialog/camera-dialog.component.html
  2. +9
    -0
      src/app/modules/overview/camera-dialog/camera-dialog.component.scss
  3. +21
    -0
      src/app/modules/overview/camera-dialog/camera-dialog.component.spec.ts
  4. +36
    -0
      src/app/modules/overview/camera-dialog/camera-dialog.component.ts
  5. +1
    -1
      src/app/modules/overview/camera-stream/camera-stream.component.ts
  6. +4
    -2
      src/app/modules/overview/map/map.component.scss
  7. +46
    -29
      src/app/modules/overview/map/map.component.ts
  8. +9
    -6
      src/app/modules/overview/overview.module.ts
  9. +5
    -1
      src/app/shared/shared-material.module.ts

+ 11
- 0
src/app/modules/overview/camera-dialog/camera-dialog.component.html View File


<div style="padding: 10px 20px" fxLayout="row" fxLayoutAlign=" center">
<div style="text-align: center; font-size: 24px; width: 95%">Camera Stream</div>
<button mat-icon-button color="warn" (click)="onClose()">
<mat-icon>close</mat-icon>
</button>
</div>
<div mat-dialog-content>
<canvas class="video" #videoPlayer></canvas>
</div>


+ 9
- 0
src/app/modules/overview/camera-dialog/camera-dialog.component.scss View File

.video {
width: 90% !important;
//height: 90%;
display: block;
margin: 0 auto
}
.mat-mdc-dialog-content{
max-height: unset;
}

+ 21
- 0
src/app/modules/overview/camera-dialog/camera-dialog.component.spec.ts View File

import { ComponentFixture, TestBed } from '@angular/core/testing';

import { CameraDialogComponent } from './camera-dialog.component';

describe('CameraDialogComponent', () => {
let component: CameraDialogComponent;
let fixture: ComponentFixture<CameraDialogComponent>;

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [CameraDialogComponent]
});
fixture = TestBed.createComponent(CameraDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 36
- 0
src/app/modules/overview/camera-dialog/camera-dialog.component.ts View File

import {AfterViewInit, Component, ElementRef, ViewChild} from '@angular/core';
import {MatDialogRef} from "@angular/material/dialog";
import {loadPlayer, Player} from "rtsp-relay/browser";

@Component({
selector: 'app-camera-dialog',
templateUrl: './camera-dialog.component.html',
styleUrls: ['./camera-dialog.component.scss']
})
export class CameraDialogComponent implements AfterViewInit{

player?: Player;
@ViewChild('videoPlayer')
videoPlayer?: ElementRef<HTMLCanvasElement>;


constructor(public dialogRef: MatDialogRef<CameraDialogComponent>) { }

async ngAfterViewInit() {
const connect = async () => {
this.player = await loadPlayer({
url: 'ws://localhost:8080/stream',
canvas: this.videoPlayer!.nativeElement,
onDisconnect: () => {
setTimeout(connect, 5000); // reconnect after 5 seconds
},
});
};
connect();
}

onClose(): void {
this.dialogRef.close();
}

}

+ 1
- 1
src/app/modules/overview/camera-stream/camera-stream.component.ts View File

@ViewChild('videoPlayer') @ViewChild('videoPlayer')
videoPlayer?: ElementRef<HTMLCanvasElement>; videoPlayer?: ElementRef<HTMLCanvasElement>;


constructor(private el: ElementRef, private renderer: Renderer2) {}
constructor() {}


ngOnInit() { ngOnInit() {
} }

+ 4
- 2
src/app/modules/overview/map/map.component.scss View File

opacity: 0; opacity: 0;
} }
} }
::ng-deep tooltip {
::ng-deep .tooltip {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 5px; gap: 5px;

.dynamic-button{
cursor: pointer;
}
} }


::ng-deep.icon { ::ng-deep.icon {

+ 46
- 29
src/app/modules/overview/map/map.component.ts View File

AfterViewInit, AfterViewInit,
Component, Component,
OnDestroy, OnDestroy,
OnInit
OnInit, Renderer2
} from '@angular/core'; } from '@angular/core';
import * as L from 'leaflet'; import * as L from 'leaflet';
import 'leaflet.markercluster'; import 'leaflet.markercluster';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { SocketService } from '../../../shared/services/socket.service'; import { SocketService } from '../../../shared/services/socket.service';
import {MatDialog} from "@angular/material/dialog";
import {CameraDialogComponent} from "../camera-dialog/camera-dialog.component";




const alarmData = [ const alarmData = [


]; ];



const alarmDemo = { const alarmDemo = {
title: ' Demo Alarm System', // Thêm mới warning title: ' Demo Alarm System', // Thêm mới warning
detail: { detail: {
time: '06-07-2024' time: '06-07-2024'
}, },
} }

@Component({ @Component({
selector: 'app-map', selector: 'app-map',
templateUrl: './map.component.html', templateUrl: './map.component.html',
state6 = false; state6 = false;
isReady = true; isReady = true;


constructor(private socketService$: SocketService) { }
constructor(private socketService$: SocketService,
private dialog: MatDialog,
private renderer: Renderer2) { }


ngOnInit() { ngOnInit() {
this.statusSubscription = this.socketService$.status$.subscribe(isConnected => { this.statusSubscription = this.socketService$.status$.subscribe(isConnected => {
}); });
} }


openDialog(): void {
this.dialog.open(CameraDialogComponent, {
width: '80vw',
data: ''
});
}

ngAfterViewInit(): void { ngAfterViewInit(): void {
this.initMap(); this.initMap();
} }
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>' attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(this.map); }).addTo(this.map);


this.addIconToMap();
this.addIconsToMap();
} else { } else {
console.error('Map container not found'); console.error('Map container not found');
} }


onMessage(message: any) { onMessage(message: any) {
if (message.id == '0' && message.type === 'get') { if (message.id == '0' && message.type === 'get') {
this.state1 = message.state1 === '0';// 1 OFF // alarm 12h
this.state1 = message.state1 === '0'; // 1 OFF // alarm 12h
this.state2 = message.state2 === '0'; // 1 OFF // alarm 1h this.state2 = message.state2 === '0'; // 1 OFF // alarm 1h
this.state5 = message.state5 === '1';// 1 ON, 0 OFF
this.state5 = message.state5 === '1'; // 1 ON, 0 OFF
this.isReady = message.ready === '1'; this.isReady = message.ready === '1';
this.updateIcons(); this.updateIcons();
} }
} }


addIconToMap() {
addIconsToMap(): void {
this.markers = L.markerClusterGroup(); this.markers = L.markerClusterGroup();
this.data.forEach((item: any) => {
// create icon
const icon = this.createIcon(item.warning);
// add icon into map
L.marker([item.detail.coordinates.lat, item.detail.coordinates.lng], { icon: icon })
.bindPopup(this.popupDetail(item))
.addTo(this.markers);
});
const iconDemo = this.getIcon(this.state5, this.isReady, this.state1, this.state2);
L.marker([this.alarmDemo.detail.coordinates.lat,this.alarmDemo.detail.coordinates.lng], { icon: iconDemo })
.bindPopup(this.popupDetail(this.alarmDemo))
.addTo(this.markers);
this.data.forEach(item => this.addMarker(item));
this.addMarker(this.alarmDemo, true);
this.map.addLayer(this.markers);
}

addMarker(item: any, isDemo: boolean = false): void {
const icon = isDemo ? this.getIcon(this.state5, this.isReady, this.state1, this.state2) : this.createIcon(item.warning);
const marker = L.marker([item.detail.coordinates.lat, item.detail.coordinates.lng], { icon })
.bindPopup(this.popupDetail(item));

marker.on('popupopen', (event) => this.bindPopupEvents(event));


this.markers.addTo(this.map);
this.markers.addLayer(marker);
}

bindPopupEvents(event: any): void {
const popupContainer = event.popup.getElement();
const button = popupContainer?.querySelector('.dynamic-button');
if (button) {
this.renderer.listen(button, 'click', () => this.openDialog());
}
} }


updateIcons(): void { updateIcons(): void {
//clear layer icon mỗi lần update
this.markers.clearLayers(); this.markers.clearLayers();
this.addIconToMap();
this.addIconsToMap();
} }


popupDetail(item: any): string { popupDetail(item: any): string {
<div class="tooltip" style="width: 200px"> <div class="tooltip" style="width: 200px">
<div style="display: flex; flex-direction: row; justify-content: space-between; margin-bottom: 5px"> <div style="display: flex; flex-direction: row; justify-content: space-between; margin-bottom: 5px">
<div style="color: #F33152; padding: 5px 13px; background-color: rgba(243, 49, 82, 0.1); border-radius: 20px; text-align: center; max-width: 180px;">${item.title}</div> <div style="color: #F33152; padding: 5px 13px; background-color: rgba(243, 49, 82, 0.1); border-radius: 20px; text-align: center; max-width: 180px;">${item.title}</div>
<a href="/overview/camera-stream" target="_blank">
<a class="dynamic-button">
<svg width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="none"> <svg width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="none">
<g stroke="currentColor" stroke-width="2"> <g stroke="currentColor" stroke-width="2">
<path d="M16 16V8a1 1 0 00-1-1H5a1 1 0 00-1 1v8a1 1 0 001 1h10a1 1 0 001-1z"/> <path d="M16 16V8a1 1 0 00-1-1H5a1 1 0 00-1 1v8a1 1 0 001 1h10a1 1 0 001-1z"/>
return L.divIcon({ return L.divIcon({
html: `<div class="icon"> html: `<div class="icon">
<div style="z-index:9999" class="sensor-on"> <div style="z-index:9999" class="sensor-on">
<img alt="icon-alarm" src ="assets/images/sensor-on.png" style="width: 30px; height: 30px">
</div>
<div style="background: #F11E1E; color: #FFF; padding: 2px 3px; font-size: 11px; margin-top: 10px; text-align: center">
${htmlContent}
</div>
</div>`,
<img alt="icon-alarm" src="assets/images/sensor-on.png" style="width: 30px; height: 30px">
</div>
<div style="background: #F11E1E; color: #FFF; padding: 2px 3px; font-size: 11px; margin-top: 10px; text-align: center">
${htmlContent}
</div>
</div>`,
iconSize: [200, 30], iconSize: [200, 30],
className: className className: className
}); });

+ 9
- 6
src/app/modules/overview/overview.module.ts View File

import {overviewRoutes} from "./overview.routing"; import {overviewRoutes} from "./overview.routing";
import {MapComponent} from "./map/map.component"; import {MapComponent} from "./map/map.component";
import {SharedMaterialModule} from "../../shared/shared-material.module"; import {SharedMaterialModule} from "../../shared/shared-material.module";
import { CameraStreamComponent } from './camera-stream/camera-stream.component';
import {CameraStreamComponent} from "./camera-stream/camera-stream.component";
import {CameraDialogComponent} from "./camera-dialog/camera-dialog.component";




@NgModule({ @NgModule({
declarations: [ declarations: [
OverallGroundComponent, OverallGroundComponent,
MapComponent, MapComponent,
CameraDialogComponent,
CameraStreamComponent CameraStreamComponent
], ],
imports: [
CommonModule,
RouterModule.forChild(overviewRoutes),
SharedMaterialModule,
imports: [
CommonModule,
RouterModule.forChild(overviewRoutes),
SharedMaterialModule,


]

]
}) })
export class OverviewModule { } export class OverviewModule { }

+ 5
- 1
src/app/shared/shared-material.module.ts View File

import { NgModule } from "@angular/core"; import { NgModule } from "@angular/core";
import { FlexLayoutModule } from "@angular/flex-layout"; import { FlexLayoutModule } from "@angular/flex-layout";
import { MatButtonModule } from "@angular/material/button"; import { MatButtonModule } from "@angular/material/button";
import { MatDialogModule } from "@angular/material/dialog";
import { MatIconModule } from "@angular/material/icon";


@NgModule({ @NgModule({
exports: [ exports: [
MatButtonModule, MatButtonModule,
FlexLayoutModule
FlexLayoutModule,
MatDialogModule,
MatIconModule
] ]
}) })
export class SharedMaterialModule {} export class SharedMaterialModule {}

Loading…
Cancel
Save