Start adding editor, fix up sidebar styling
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
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: `
|
||||
<h2>Protobuf Definitions</h2>
|
||||
<mat-list>
|
||||
@for (item of definitionFiles(); track $index) {
|
||||
<mat-list-item (click)="selectProtoDefinition(item)">{{
|
||||
item.name
|
||||
}}</mat-list-item>
|
||||
}
|
||||
</mat-list>
|
||||
<button mat-button (click)="protoSelector.click()">
|
||||
Select definitions
|
||||
</button>
|
||||
<input
|
||||
#protoSelector
|
||||
type="file"
|
||||
(change)="addDefinitionFiles()"
|
||||
accept=".proto"
|
||||
/>
|
||||
<mat-list>
|
||||
@for (item of selectedDefinition(); track $index) {
|
||||
<mat-list-item (click)="messageSelected.emit(item)">{{
|
||||
item.name
|
||||
}}</mat-list-item>
|
||||
}
|
||||
</mat-list>
|
||||
<!-- TODO: more detail when dragging over so user knows they can drop the file -->
|
||||
`,
|
||||
styleUrl: './proto-definition-selector.component.css',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ProtoDefinitionSelectorComponent {
|
||||
protoSelector = viewChild<ElementRef<HTMLInputElement>>('protoSelector');
|
||||
messageSelected = output<ProtoMessage>();
|
||||
|
||||
protected definitionFiles = signal<File[]>([]);
|
||||
protected selectedDefinition = signal<ProtoMessage[]>([]);
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user