import { Clipboard } from '@angular/cdk/clipboard';
import { Component, DestroyRef, Input, inject, signal } from '@angular/core';
@Component({
selector: 'app-task-id-copy',
standalone: true,
template: `
ID: {{ taskId }}
content_copy
{{ feedback() }}
`,
styles: [`
:host { display: block; min-width: 0; font-size: 11px; color: inherit; user-select: text; }
.copy-target { display: inline-flex; align-items: center; gap: 5px; max-width: 100%;
padding: 3px 0; cursor: pointer; user-select: text; border-radius: 3px; }
.value { min-width: 0; overflow-wrap: anywhere; user-select: text; }
.material-symbols-outlined { flex-shrink: 0; font-size: 14px; user-select: none; }
.copy-target:hover { color: var(--app-primary-text, #2563eb); }
.copy-target:focus-visible { outline: 2px solid #60a5fa; outline-offset: 2px; }
.feedback { display: block; line-height: 1.6; user-select: text; }
.feedback:empty { display: none; }
`]
})
export class TaskIdCopyComponent {
@Input({ required: true }) taskId = '';
readonly feedback = signal('');
private readonly clipboard = inject(Clipboard);
private readonly destroyRef = inject(DestroyRef);
private timer: ReturnType | undefined;
constructor() {
this.destroyRef.onDestroy(() => clearTimeout(this.timer));
}
async copy(event: Event): Promise {
event.stopPropagation();
// A drag selection must remain available for the browser's normal copy action.
const selection = window.getSelection();
if (event.type === 'click' && selection && !selection.isCollapsed
&& (event.currentTarget as HTMLElement).contains(selection.anchorNode)) return;
event.preventDefault();
let copied = false;
try {
if (navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(this.taskId);
copied = true;
} else {
copied = this.clipboard.copy(this.taskId);
}
} catch {
try {
copied = this.clipboard.copy(this.taskId);
} catch {
// Keep manual selection available when the browser blocks both clipboard APIs.
}
}
if (this.destroyRef.destroyed) return;
this.feedback.set(copied ? '任务 ID 已复制' : '复制失败,请选中任务 ID 手动复制');
clearTimeout(this.timer);
this.timer = setTimeout(() => this.feedback.set(''), 3000);
}
}