|
- import {
- AfterViewInit,
- Component,
- OnDestroy,
- OnInit,
- Renderer2,
- } from '@angular/core';
- import * as L from 'leaflet';
- import 'leaflet.markercluster';
- import { Subscription, take } from 'rxjs';
- import { SocketService } from '../../../shared/services/socket.service';
- import { MatDialog } from '@angular/material/dialog';
- import { AlarmSoundService } from '../../../shared/services/alarm-sound.service';
- import { CameraDialogComponent } from '../../../shared/component/camera-dialog/camera-dialog.component';
- import { alarmData, alarmDemo } from '../data/fake-data';
- import { ConfirmDialogService } from '../../../shared/services/confirm-dialog.service';
-
- @Component({
- selector: 'app-centralized-security-management',
- templateUrl: './centralized-security-management.component.html',
- styleUrls: ['./centralized-security-management.component.scss'],
- })
- export class CentralizedSecurityManagementComponent
- implements OnInit, AfterViewInit, OnDestroy
- {
- private map!: L.Map;
- private markers!: L.MarkerClusterGroup;
- private statusSubscription?: Subscription;
- private messageSubscription?: Subscription;
- data = alarmData;
- alarmDemo = alarmDemo;
- state1 = false;
- state2 = false;
- state5 = false;
- state6 = false;
- isReady = true;
-
- constructor(
- private socketService$: SocketService,
- private dialog: MatDialog,
- private renderer: Renderer2,
- private alarmSoundService$: AlarmSoundService,
- private confirmDialogService$: ConfirmDialogService,
- ) {}
-
- ngOnInit() {
- this.statusSubscription = this.socketService$.status$.subscribe(
- (isConnected) => {
- if (isConnected) {
- this.socketService$.sendMessage({ id: '0', type: 'get' });
- this.messageSubscription = this.socketService$.messages$.subscribe(
- (message) => {
- this.onMessage(message);
- },
- );
- }
- },
- );
- }
-
- openDialog(): void {
- this.dialog.open(CameraDialogComponent, {
- width: '80vw',
- data: '',
- });
- }
-
- ngAfterViewInit(): void {
- this.initMap();
- }
-
- ngOnDestroy(): void {
- this.statusSubscription?.unsubscribe();
- this.messageSubscription?.unsubscribe();
- this.socketService$.close();
- this.alarmSoundService$.stopAlarm();
- }
-
- initMap(): void {
- const mapContainer = document.getElementById('map');
- if (mapContainer) {
- this.map = L.map('map', {
- center: [10.7483, 106.7537],
- zoom: 12,
- });
-
- L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
- maxZoom: 15,
- minZoom: 3,
- attribution:
- '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
- }).addTo(this.map);
-
- this.addIconsToMap();
- } else {
- console.error('Map container not found');
- }
- }
-
- onMessage(message: any) {
- if (message.id == '0' && message.type === 'get') {
- this.state1 = message.state1 === '0'; // 1 OFF // alarm 12h
- this.state2 = message.state2 === '0'; // 1 OFF // alarm 1h
- this.state5 = message.state5 === '1'; // 1 ON, 0 OFF
- this.isReady = message.ready === '1';
- // this.alarmSoundService$.startAlarm(true, true, true, this.state2);
-
- this.updateIcons();
- }
- }
-
- addIconsToMap(): void {
- this.markers = L.markerClusterGroup();
- 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.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 {
- this.markers.clearLayers();
- this.addIconsToMap();
- }
-
- popupDetail(item: any): string {
- return `
- <div class="tooltip" style="width: 200px">
- <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>
- <a class="dynamic-button">
- <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">
- <path d="M16 16V8a1 1 0 00-1-1H5a1 1 0 00-1 1v8a1 1 0 001 1h10a1 1 0 001-1z"/>
- <path stroke-linejoin="round" d="M20 7l-4 3v4l4 3V7z"/>
- </g>
- </svg>
- </a>
- </div>
- <div><strong>Địa điểm:</strong> ${item.detail.position}</div>
- <div><strong>Tọa độ:</strong> ${item.detail.coordinates.lat}, ${item.detail.coordinates.lng}</div>
- <div><strong>Thời gian:</strong> ${item.detail.time}</div>
- <a href="/overview/overall-ground" target="_blank">Xem chi tiết</a>
- </div>`;
- }
-
- createIcon(
- active: boolean,
- className: string = '',
- text: any = [],
- ): L.Icon<L.IconOptions> | L.DivIcon {
- if (text.length < 1) {
- return L.icon({
- iconUrl: active
- ? '../../../../assets/images/sensor-on.png'
- : '../../../../assets/images/sensor-off.png',
- iconSize: [30, 30],
- className: className,
- });
- } else {
- let htmlContent = '';
- text.forEach((item: any) => {
- htmlContent += `<span><b>${item}</b></span><br>`;
- });
-
- return L.divIcon({
- html: `<div class="icon">
- <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>`,
- iconSize: [200, 30],
- className: className,
- });
- }
- }
-
- getIcon(
- isTurnOn: boolean,
- isReady: boolean,
- fireArm: boolean,
- fenceArm: boolean,
- ): L.Icon<L.IconOptions> | L.DivIcon {
- if (isTurnOn && isReady) {
- let text = [];
- if (fireArm && fenceArm) {
- text.push('FIRE ALARM', 'FENCE ALARM');
- } else if (fireArm) {
- text.push('FIRE ALARM');
- } else if (fenceArm) {
- text.push('FENCE ALARM');
- }
- return this.createIcon(true, '', text);
- }
- return this.createIcon(false);
- }
- }
|