import { CommonModule } from '@angular/common'; import { Component, ElementRef, SecurityContext, computed, effect, input, signal, viewChild, } from '@angular/core'; import hljs from 'highlight.js/lib/core'; import { ProtoMessage } from '../model/proto-message.model'; import { ProtoFieldComponent } from './proto-field/proto-field.component'; import { DomSanitizer } from '@angular/platform-browser'; import { MatButtonModule } from '@angular/material/button'; import { MatSnackBar } from '@angular/material/snack-bar'; @Component({ selector: 'app-editor', standalone: true, imports: [CommonModule, ProtoFieldComponent, MatButtonModule], templateUrl: './editor.component.html', styleUrl: './editor.component.scss', }) export class EditorComponent { // TODO: This needs to be reworked so we have a local property and implement some kind of auto-save fileContents = input(); selectedMessage = input.required(); showRaw = input(true); protected values = signal(undefined); private code = viewChild>('code'); constructor(sanitizer: DomSanitizer, private snackBar: MatSnackBar) { effect(() => { const element = this.code()?.nativeElement; if (element) { if (!this.values()) { return; } const json = JSON.stringify(this.values(), undefined, 2); const highlighted = hljs.highlightAuto(json, ['json']); const sanitized = sanitizer.sanitize( SecurityContext.HTML, highlighted.value ); if (sanitized) { element.innerHTML = sanitized; } } }); effect( () => { const message = this.selectedMessage(); this.values.set( Object.fromEntries( message.values.map((value) => [[value.name, undefined]]) ) ); }, { allowSignalWrites: true } ); } protected updateValue(key: string, value: any) { const existingValue = { ...this.values() }; existingValue[key] = value; this.values.set(existingValue); } protected async copyToClipboard() { await navigator.clipboard.writeText( JSON.stringify(this.values(), undefined, 2) ); this.snackBar.open('Successully copied to clipboard', 'Close', { duration: 2000, }); } }