import { Directive, ElementRef, EventEmitter, OnDestroy, Output, Input, } from '@angular/core'; // ============================================================================ // Long-Press Directive — CUB-26 // Emits after a sustained press (500ms default). // Used on agent cards to bypass the drawer and open Session Log directly. // ============================================================================ @Directive({ selector: '[appLongPress]', standalone: true, host: { '(mousedown)': 'onMouseDown($event)', '(mouseup)': 'onMouseUp()', '(mouseleave)': 'onMouseLeave()', '(touchstart)': 'onTouchStart($event)', '(touchend)': 'onTouchEnd()', '(touchmove)': 'onTouchMove()', '(contextmenu)': 'onContextMenu($event)', }, }) export class LongPressDirective implements OnDestroy { /** Duration in ms before a press counts as a long press. */ @Input() appLongPressDuration = 500; /** Emits when a long press is detected. Payload is the original event. */ @Output() readonly appLongPress = new EventEmitter(); private timer: ReturnType | null = null; private isLongPress = false; onMouseDown(event: MouseEvent): void { this.isLongPress = false; this.timer = setTimeout(() => { this.isLongPress = true; this.appLongPress.emit(event); }, this.appLongPressDuration); } onMouseUp(): void { this.clearTimer(); } onMouseLeave(): void { this.clearTimer(); } onTouchStart(event: TouchEvent): void { this.isLongPress = false; this.timer = setTimeout(() => { this.isLongPress = true; this.appLongPress.emit(event); }, this.appLongPressDuration); } onTouchEnd(): void { this.clearTimer(); } onTouchMove(): void { // Cancel on touch move (finger moved) this.clearTimer(); } onContextMenu(event: MouseEvent): void { // Prevent native context menu on long press if (this.isLongPress) { event.preventDefault(); } } ngOnDestroy(): void { this.clearTimer(); } private clearTimer(): void { if (this.timer !== null) { clearTimeout(this.timer); this.timer = null; } } }