import { MediaMatcher } from '@angular/cdk/layout'; import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, HostBinding, HostListener, OnDestroy, output, signal, viewChild, } from '@angular/core'; import { MatListModule } from '@angular/material/list'; import { ProtoMessage } from '../model/proto-message.model'; import { ProtoDefinitionService } from '../proto-definition.service'; import { MatButtonModule } from '@angular/material/button'; @Component({ selector: 'app-proto-definition-selector', standalone: true, imports: [CommonModule, MatListModule, MatButtonModule], template: `

Protobuf Definitions

@for (item of definitionFiles(); track $index) { {{ item.name }} } @for (item of selectedDefinition(); track $index) { {{ item.name }} } `, styleUrl: './proto-definition-selector.component.css', changeDetection: ChangeDetectionStrategy.OnPush, }) export class ProtoDefinitionSelectorComponent { protoSelector = viewChild>('protoSelector'); messageSelected = output(); protected definitionFiles = signal([]); protected selectedDefinition = signal([]); protected isDragging = signal(false); private currentFiles: string[] = []; @HostBinding('class.droppable') get droppable() { return this.isDragging(); } constructor( private protoDefinitionService: ProtoDefinitionService, private elementRef: ElementRef ) {} protected async addDefinitionFiles() { const files = this.protoSelector()?.nativeElement.files; if (files) { const definitionFiles = this.definitionFiles(); for (let i = 0; i < files.length; i++) { if (!this.currentFiles.includes(files[i].name)) { definitionFiles.push(files[i]); this.currentFiles.push(files[i].name); } } this.definitionFiles.set(definitionFiles); } } protected async selectProtoDefinition(file: File) { try { const protoContents = await file.text(); const messageObjects = await this.protoDefinitionService.parseProtoDefinition(protoContents); this.selectedDefinition.set(messageObjects); } catch (err) { console.error(err); alert( "Failed to parse protobuf definition, please check it's a valid file." ); } } @HostListener('dragover', ['$event']) onDrag(event: DragEvent) { event.preventDefault(); } @HostListener('drop', ['$event']) onDrop(event: DragEvent) { event.preventDefault(); const protoSelector = this.protoSelector(); if (protoSelector) { protoSelector.nativeElement.files = event.dataTransfer?.files ?? null; } this.isDragging.set(false); this.addDefinitionFiles(); } @HostListener('dragenter') onDragEnter() { this.isDragging.set(true); } @HostListener('dragleave', ['$event']) onDragLeave(event: DragEvent) { if (event.target) this.isDragging.set(false); } }