Files
AltitudeWeb/frontend/src/app/pages/altitude/chat/components/mini-message/mini-message.component.ts
T

68 lines
2.2 KiB
TypeScript

import {CommonModule} from '@angular/common';
import {Component, Input, Optional} from '@angular/core';
import {MiniMessageComponent as MiniMessageNode, ResolvedStyle} from '../../mini-message/mini-message.types';
import {hoverEventToTitle, mergeStyle, ownText, styleToNgStyle} from '../../mini-message/mini-message.util';
import {ObfuscatedDirective} from '../../mini-message/obfuscated.directive';
import {MiniMessageInteractionService} from '../../mini-message/mini-message-interaction.service';
/**
* Renders a Paper/Adventure component-JSON tree as styled HTML.
*
* Usage:
* providers: [MiniMessageInteractionService] // once, at the root that hosts <mini-message>
* <mini-message [node]="myComponentJson"></mini-message>
*
* Then subscribe to click events (run_command / suggest_command / copy_to_clipboard /
* change_page) via the injected MiniMessageInteractionService.clicks$; open_url is handled
* natively as a real link so no subscription is needed for that case.
*/
@Component({
selector: 'mini-message',
standalone: true,
imports: [CommonModule, ObfuscatedDirective],
templateUrl: './mini-message.component.html',
styleUrl: './mini-message.component.scss',
})
export class MiniMessageComponent {
@Input() node!: MiniMessageNode;
@Input() parentStyle?: ResolvedStyle;
constructor(@Optional() private readonly interaction: MiniMessageInteractionService | null) {
}
get style(): ResolvedStyle {
return mergeStyle(this.parentStyle, this.node);
}
get ngStyle(): Record<string, string> {
return styleToNgStyle(this.style);
}
get text(): string {
return ownText(this.node);
}
get hoverTitle(): string | null {
return hoverEventToTitle(this.node.hoverEvent);
}
get isUrlLink(): boolean {
return this.node.clickEvent?.action === 'open_url';
}
get hasNonUrlClick(): boolean {
return !!this.node.clickEvent && this.node.clickEvent.action !== 'open_url';
}
onClick(): void {
const click = this.node.clickEvent;
if (!click) return;
if (click.action === 'copy_to_clipboard') {
navigator.clipboard?.writeText(click.value);
}
this.interaction?.emitClick({action: click.action, value: click.value});
}
}